1. array name
Let's take a look at the two statements in the statement:
Int;
Int B [10];
We call variable a scalar because it is a single value. We call variable B an array because it is a set of values. B [0] indicates the first number in the array, B [1] indicates the second number in the array, and so on.
We know that the type of B [0] is an integer. So what is the type of B? What does it mean? A logical answer seems to be that it represents the entire array, but this is not the case. In C, the array name always represents a pointer constant, that is, the address of the first element of the array, that is, & B [0]. Its type depends on the array type.
Note: here we talk about "pointer constants" instead of the "pointer variables" mentioned in the previous article ". A pointer constant cannot change the value pointed to by the pointer. This code is incorrect:
Int number = 0;
Int a [10] = {0 };
A = & number;
Although a is an integer pointer, a is a pointer constant and cannot change its value.
Please do not conclude that the pointer is the same as the Array Based on the fact that the array name is a pointer. Arrays have some completely different features from pointers. For example, an array has a definite number value, while a pointer is only a scalar value.
2. subscript reference
In the Context Environment declared earlier, what does the following expression mean?
* (B + 3 );
First, the value of B is a pointer constant pointing to an integer. Therefore, the value 3 is adjusted based on the length of the integer. The result of the addition operation is another pointer to the integer, that is, & B [3]. Then, you can use "*" to unreference it, which is equivalent
* (& B [3]) or directly expressed as B [3].
We can assume that, except for the different priorities, subscript references and indirect pointer access are identical. For example, the following two expressions are equivalent:
Array [subsricpt]
* (Array + (subsrept ))
Let's take a look at an example to consolidate and review the previous knowledge.
Int array [10];
Int * ap = array + 2;
In the following ap-related expressions, see if you can write the corresponding array expression:
Ap, this is very easy, & array [2] Or * (array + 2)
* Ap. This is also very easy. It is equivalent to performing the dereference operation on the ap, which is equivalent to array [2] Or * (array + 2)
Ap [0] converts it to * (ap + 0), that is, * ap, which is equivalent to the previous expression.
Ap + 6. This expression is equivalent to & array [2 + 6] Or * (array + 2 + 6), that is, & array [8] or
* (Array + 8)
* Ap + 6. Be careful. There are two operators here. However, indirect access has a higher priority than addition operations. Therefore, this formula is equivalent to array [2] + 6.
Ap [6], you may have questions? Is this wrong? Indeed, he may be wrong in other languages, but he is correct in C language. We have said that the following table operations in C language are exactly the same as indirect access operations by pointers, that is
* (Ap + 6)
& Ap: this expression is completely legal. It represents the address of the ap pointer, that is, the pointer of the pointer.
Well, if the problem above is hard for you, let's take a look at the following:
2 [ap]
Yes, you are not mistaken. 2 [ap], not ap [2].
His answer may surprise you: it is legal. Convert it into a peer-to-peer indirect access expression, and you will find its validity:
* (2 + (array ))
The parentheses in the inner layer are redundant, that is, they are equivalent to * (array + 2.
3. Efficiency of pointers and Arrays
Here, I do not want to use disassembly to experiment on the efficiency of arrays and pointers. For the moment, readers can remember this:
"Assuming both methods are correct, the subscript will never be more efficient than the pointer, but sometimes the pointer will be more efficient than the subscript"
From Kernel & UI