The technique of inheriting an array subscript as a pointer plus an offset from the BCPL (C-language ancestor) of the C language. In people's conventional thinking, it is impractical to increase the scope of the subscript in C language at run time. Because the removal of the subscript simply means that the array will be accessed, it is not guaranteed to be accessible. Also, programmers can use pointers to access arrays, bypassing subscript operators. In this case, the array subscript range detection does not detect the access of all the arrays. In fact, subscript range detection is not considered worthy of being added to the C language.
It is also said that using pointers is more efficient than using arrays when writing array algorithms.
This rather acceptable claim is often wrong. With modern product-quality-optimized compilers, the code generated by one-dimensional arrays and pointer references is not significantly different. In any case, the array subscript is defined on the basis of the pointer, so the optimizer can often convert it to a more efficient pointer expression and generate the same machine instruction. Let's take a look at both the array/pointer scenario and detach the initialization from the access inside the loop.
int a [ten], *p, I;
Variable A[i] can be accessed using the various methods shown in Figure 9-2, and the effect is exactly the same.
Even if the compiler uses a more original translation method, which produces a different code, iterating over a one-dimensional array with pointers is often no faster than iterating through a one-dimensional array directly using the subscript. Whether it is a pointer or an array, the compiler must compute the step forward each time it moves on a contiguous memory address. The calculated method is the offset multiplied by the number of bytes occupied by each array element, and the result is the actual number of bytes that offset the starting address of the array. The step factor is often the 2 (such as int is 4 bytes, double is 8 bytes, and so on), so that the compiler can use a fast left shift operation rather than a relatively slow addition operation when calculating. A binary number left 3 bits is the equivalent of multiplying it by 8. If the size of an element in an array is not the right of 2 (the element type of a group is a struct), then this technique cannot be used.
However, iterating an int array is the easiest one to think about. If a well tuned compiler carries out code analysis, and the base variable is placed in a high speed register to confirm that the loop continues, then the code that eventually accesses the pointer and array in the loop is likely to be the same.
When working with one-dimensional arrays, pointers are not necessarily faster than arrays. The root cause of the C language's rewriting of the array subscript to pointer offsets is that pointers and offsets are the basic models used by the underlying hardware.
These examples show the intermediate code generated by the translation of different alternatives. If you use optimization measures, the intermediate code may not be the same as shown here. RO, R1 and so on behalf of the CPU registers. In the diagram, we use
R0 Store P's left value R1 store A's left value or P's right value
R2 Store I's left value R3 the right value of storage I
[R0] represents an indirect load or write, whose address is the contents of the register (a common concept used by many assembly languages). "You can refer to the loop" means that the data will not be recycled, and you can speed up the cycle by not having to execute the statement at each loop.
"Array name as function argument" equals pointer
Rule 3 also requires an explanation.
First, let's review some of the terms mentioned in the C programming language.
The declaration of a formal parameter as an array of type should be adjusted to "pointer of type". In the case of a function parameter definition, the compiler must overwrite the form of the array as a pointer to the first element of the array exponentially. The compiler only passes the address of an array to a function, not a copy of the entire array. Now let's focus on the array, however, and the implicit conversion means that three forms are completely equivalent. Therefore, on the invocation of My_function (), whether the argument is an array or a true pointer is legitimate.
my_function (int *turnip) {.
my-function (int turnip[]) {
My one function (int turnip[200]) {