Opened the C / C array parameter in the fog Author: universe smile wedge last year, Zhou stars Big Brother has published an article "array reference" to avoid "an array of reduced order" in VCKBASE / C forum, then I can not understand this in depth The meaning of the usage; after a year, my knowledge has been tempered, and finally, I have a gradual understanding of this article, so I have a detailed way, and I have become an article. I hope this article can enlighten the novice, and I hope that everyone will find that he will not leave a message after the 漏. The story originated from the two Demo given by Zhou Xingxing, in order to save the place, I combined two Demo two as one, and I can explain the same problem: #include
Using namespace std;
Void foo1 (int Arr [100])
{
COUT << "pass by POINTER:" << sizeof (arr) << Endl;
}
Void Foo2 (INT (& Arr) [100])
{
COUT << "pass by reference:" << sizeof (arr) << endl
}
void main ()
{
Int a [100];
Cout << "in main function:" << SizeOf (a) << endl;
Foo1 (a);
Foo2 (a);
}
Its operation is as follows: in main function: 400
Pass by Pointer: 4
Pass by reference: 400
This code illustrates that if the array type is to be a group name form (or pointer form, discussed below), use the SIZEOF operator, it will not be able to get the length of the original array; if you use the method referenced by the original array, there is no problem. . This code is really difficult to understand, because this short ten lines involve the relationship between the arguments, the relationship between the group name and pointer, the meaning of the meaning, the name and expression of the audience, as long as there is 1 The bar is understood or understood in incorrect, understand the paragraph of the contrary. This article will start from these four problems, first resolve these four questions, and then discuss this code above. Although it seems to be quite complicated, I think I will understand, learn, is a road like far matches. First, the relationship between the functional ginseng and the argument VOID FOO (INT A);
Foo (10);
Here, the A is called a parameter, referred to as a parameter; the 10 here is called actual parameters (argument), referred to as argument. What is the relationship between conformation and expression? They are the relationship between assignment, that is, the process of passing the arithmetic parameters, can be seen as the process of assigning the value of the reference. In the above example, the real parameters 10 transmits to the formation a, which is equivalent to a = 10; this assignment process. (Because there is much more data type, you can't give it a comprehensive, so you don't have an example; if you feel bad, you will verify this conclusion when you write a SAMPLE to write a Sample in the VC. .) Second, the relationship between group names and pointers This problem is a historic issue. In the C language, the array name is treated as a pointer. More specifically, the array name is a pointer to the first element address of the array, and the array index is the offset of the first element address of the array. It is important to understand this, and many of the groups of applications are there. This is why the arrays in the C language are counting from 0, because so that its index is better to correspond to the offset. In the C language, there is an expression of an array name during the compilation process, which will replace the array name into a pointer; the compiler does not even distinguish between A [4] and 4 [A]! * 2 But here you need to pay attention: int A [100]; int * b;
Both are not equivalent, the first sentence declares an array A, and defines this array. It has 100 INT elements. SizeOf (a) will get the memory size of the entire array, 400; second The sentence is only declared and defined an INT type pointer, and the sizeof (b) will get the memory size occupied by this pointer, 4. Therefore, although the array name is generally treated in the expression, the number of group names and pointers still have a gap, at least a == & a [0], but sizeof (a)! = Sizeof (a [0] ). And in the ANSI C standard, it is also clearly stated that in the declaration of the function parameters, the array name is used as a pointer to the first element of the array. Therefore, the following written forms are equivalent: void foo1 (int Arr [100]) {}
Void foo2 (int Arr []) {}
Void Foo3 (INT * ARR) {}
C is compatible with the C language as much as possible, so this part of the syntax is the same.
Third, the meaning of the reference "Quote" is the concept introduced in C , and there is no in the C language. Its purpose is to replace pointers in some ways. If you think the reference and pointer is not very different, it will definitely report unevenness. It is quite a "bright and bright and bright"; however, the reference does have new features, and it is indeed a lot of places and pointers. Different, this article is an example. Use references, we have to grasp this most important point, this is also the biggest difference between it and pointers: Quote Once, it is tightly combined with the variables that it references it, no separate, any operation of reference It is reflected in the variables it references; but pointers, just access it to another way to point to variables, although there are contacts, but it is not as unlikely like reference. :) # include
Using namespace std;
void main ()
{
INT A = 10;
INT & A_REF = A;
INT b = 20;
/ / Define the reference to initialize, indicating that the reference to the element pointing to it is inseparable // int & b_ref; // Error C2530: '' B_ref ': References Must Be Initialized
INT & B_REF = B;
INT * P;
INT * Q;
// The following results prove: References are defined, you can no longer point to other goals;
// Assign an reference B_ref to another reference A_ref, actually assigns B assigning a.
Cout << a_ref << "" << b_ref << endl;
A_REF = B_ref;
Cout << a_ref << "" << b_ref << endl;
Cout << a << "<< b << endl;
Cout << Endl;
// Even if the address is taken to a reference A_REF, it is also the address of A. Already "evil attachment" :)
P = & a;
Q = & a_ref;
Cout << p << "" << q << Endl;
Cout << Endl;
// The following code shows the difference between the pointer and the reference
P = & a;
Q = & B;
Cout << p << "" << q << Endl;
P = q;
Cout << p << "" << q << Endl;
Cout << Endl;
System ("pause");
}
Below is the result of the run for reference: 10 20
20 20
20 20
0012FED4 0012FED4
0012FED4 0012FEBC
0012FEBC 0012FEBC
Fourth, the relationship between statements and expressions is intended that the analysis of a statement can be regarded as an expression, declare in the operator priority order in the expression. For example, INT (& Arr) [100], you first find the declarator Arr, then & Arr Description Arr is a reference. What references? Outside the parentheses, [] illustrates this array, 100 describes 100 elements of this array, and the previous Int indicates that each element of this array is int type. So, this statement means: ARR is a reference to an array with 100 INT type elements. If you think this understanding is very embarrassed, you may wish to use Typedef to simplify the complex operator priority relationship in the statement, such as the following form is very well understood, its effect is the same as the original example: # INCLUDE
Using namespace std;
Typedef int INTARR [100]; // This ... can also be understood by expressions, a little "GNU IS Not Unix" tastes?
Void foo (INTARR & Arr) // NOH, I understand this, I have passed a reference.
{
COUT << "pass by reference:" << sizeof (arr) << endl
}
void main ()
{
INTARR A; // Use type alias to define aintarr & a_ref = a; // use type alias to define reference A_REF
Cout << "in main function:" << SizeOf (a) << endl;
Foo (a);
System ("pause");
}
The big ending Tao's star is for a long time, everyone feels good, it is over, everyone will bear it. Take a look at the program below: #include
Using namespace std;
void main ()
{
Int a [100];
INT * PA = A;
INT (& A_REF) [100] = a;
Cout << SizeOf (a) << endl;
COUT << SizeOf (PA) << endl;
Cout << sizeof (a_ref) << ENDL;
System ("pause");
}
How is it, is it natural to get the output? If so, it will be done. I summed it to go to get out of class! ^ _ ^ An array name is in the expression, it is often regarded as a pointer to the first element A [0] address, but in SizeOf (a), the result is the size of the array A occupant; PA means a The pointer, he also points to a [0], but in SizeOf (PA), the return result is that the PA is the size of the memory space, which is because the PA is not close enough, which is not close enough, belongs to the access array A The second selection; A_REF This is the reference to the array A, just like "evil attachment", once the attachment is attached, how can you not get it, anything to it, all It is reflected on A. In the original example of this article, the operation added than this example is the transfer of the functionality, we have said above, the passage from the arithmetic parametrin can be seen as a reference . Therefore, the original example of this article, the actual operation process is the same as the last example of this article. So, not the function gives the array to "down", but it originally original this, don't be strange. : p is still unfinished, in the PS: In the C language, there is no reference, how to solve this problem. Here are several common methods:
When passing an array, add a parameter to record the number of elements or lengths of the array. Main (int Argc, char ** args) is this approach; this method can also prevent overflow, and the security is relatively high. Behind the last valid element of the array, indicating that the array is over. The C-language uses a char array to represent a string, pass it to the related string function, which is used. This method guarantees that the so-called string of C is unlimited. Because a variable represents the length of the array, it will be subject to this variable type limit, saying that this variable is a unsigned byte type, then the string length cannot be More than 256, otherwise this variable overflows. For multidimensional arrays, the usual method is to make a row of marks after the last effective dimension, such as A [3] [3] = {{1, 0, 2}, {2, 2, 5}, {- 1, -1 ,-1}}. If my program is not used to -1, I can take -1 to fill the last line, as a logo. In this way, the element is detected in the function is -1, which is explained. The method is flexible and changeable, and the key to see how people use it. C Daddy Dennis Ritchie has said: C is strange, defective, but it has gone a huge success. Note 1: This article will no longer refer to the term "down", which is that I think this "down" concept has the meaning of complicating a 2-dimensional number of copies to 1-dimensional, in fact, this article is not this problem, This article discusses the problem of array length losses during the process of array (this is not accurate, or the discussion in the view). Note 2: The compiler of the C language encounters array element Arr [i], which will replace * (Arr i). Latest Reviews [Published Reviews] [Article Submission] See all comments Recommend to friends print
I think it is actually the most critical is the specific definition of sizeof, in fact it is completed when compiling. The concept of reference is also replaced when compiling. In this way, the above example is more clear. And don't understand and memorize so many bar frames.