C and arrays of pointers (e)

one-dimensional array

array

1. The value of the array name in C is a pointer constant, which is the address of the first element of the array and a pointer constant pointing to the type of the array element.

2. The array has a certain number of elements. When the array name is used in an expression, it is expressed as a pointer constant. When the sizeof operator and the address & operator are used, the array name is not used as a pointer constant.
1) sizeof returns the entire array length.
2) & returns a pointer to the array, not a pointer to the elements of the array.

3. The subscript reference of the array is exactly the same as the indirect access using the array name + offset, *(array+2) is equivalent to array[2].

Pointer and array
1. When moving in the array according to a fixed number of increments, using pointer variables is more efficient than using subscripts. When the increment is 1 and the machine has an address auto-increment model, the efficiency is more prominent.
1) In some cases, using pointer expressions is more efficient than subscript expressions. When moving one step at a time or a fixed number in the array, the operation of multiplying the fixed number is completed during compilation, but the subscript traverses the array When the subscript value is usually not a fixed number, it is multiplied by the length of the array element, and when the corresponding position is moved to obtain the subscript element, the multiplication will take a certain amount of time and space.
2) When traversing the array with a pointer, the fixed number moved in the loop is multiplied by the fixed number during compilation, and the pointer is added to the movement result to obtain the array element. The multiplication operation is not performed during operation, and the number of operation instructions is reduced.
3) The multiplication operation with the fixed number is completed at the time of compilation. If the subscript or pointer movement number is known at runtime, both solutions need multiplication instructions at runtime, and there is no difference in efficiency.
4) However, when using pointers for loop judgment, if the distance between the pointer and the end pointer is judged, multiplication or division operations need to be performed when using addition or subtraction operations. If the machine has a 32-bit division instruction, the division operation may be more efficient, but each cycle Judgment needs to perform calculations, which is not efficient. Integer counters can be used to control the loop, and pointer addition or subtraction operations can be removed.

2. Pointers declared as register variables are more efficient than pointers located in static memory and stack.
1) If the pointer is declared as a register variable, there is no need to copy the pointer value to the register, and the hardware address auto-increment is used to directly increase the value of the pointer.
2) Loop judgment compares the pointer directly with the end address of the array, without performing addition and subtraction operations and without counter instructions, and the end address of the array can be evaluated during compilation, which is more efficient.
3) The loop termination is judged by some initialized and adjusted content, so there is no need to use a separate counter.

3. From subscript references to pointers using register variables, the final code saves tens of microseconds in running time, but the code is difficult to write and maintain.
1) Some machines use special instructions when designing to perform array subscripting operations. The compiler uses these special instructions to realize subscript expressions, but the compiler does not necessarily use these instructions to realize pointer expressions, resulting in the following Scales are more efficient than pointers.
2) Subscript expressions are still used in most cases, and loops are easy to understand, but in some occasions, the pursuit of peak efficiency is crucial, such as real-time programs that must respond to immediate events as quickly as possible, through the above techniques Improve runtime efficiency.

4. Expressions that must be evaluated at runtime are more expensive than constant expressions like &array[SIZE] or array+SIZE.
5. Both pointers and array names can be accessed indirectly and subscripted.

Statement
1, on many machines, the code generated by register variables executes faster than the code generated by variables in static memory and stack, but the compiler can allocate registers more reasonably, and too many register declarations will reduce efficiency.
1) When declaring an array, the compiler reserves memory space for the array according to the elements specified in the declaration, and then creates the array name, whose value is a constant pointing to the starting position of this space.
2) When declaring a pointer variable, the compiler only reserves memory space for the pointer itself, and does not allocate memory space pointing to the element. If it is an automatic variable, it will not even be initialized.
3) The array name can be dereferenced, and the pointer cannot be dereferenced before it is initialized, but the array name cannot be incremented or decremented.
4) The array name is passed to the function as an actual parameter. The actual value is a pointer pointing to the first element of the array. The function copies the pointer and performs subscript reference on the pointer. In fact, it performs an indirect access operation on the pointer, and can access and modify the array elements. , modifies the value of the pointer but does not affect the pointer of the actual parameter, and modifies the value of the array element for the indirect access of the pointer.

2. Function parameters can be declared as arrays or pointers, and it is more accurate to declare them as pointers.
3. The formal parameter of the array is a space that has already allocated memory. There is no need to allocate memory space for the array parameter. The actual parameter can be an array of any length. What is actually passed is a pointer to the first element of the array. If the function needs to know The length of the array must be explicitly passed as an argument to the function.

Initialization
1, the array can be initialized through the initialization list.

2. Arrays stored in static memory are initialized before the program starts executing.
1) The program does not need to execute instructions to assign the initialization value to the array, and the linker will store the initial value in a suitable location.
2) If the array has no initialization value, the initial value of the array element is zero by default.
3) When the executable file is loaded into the memory, the initial value is loaded into the memory together with the program instructions, and the initial value is loaded into the memory location of the static array. When the program is executed, the static array has been initialized.

3. Automatic variables are uninitialized by default.
1) Automatic variables are located on the runtime stack. Every time the execution flow enters the code block where they are located, the memory locations of such variables may be different, so the compiler cannot initialize these locations before the program starts.
2) If an initial value is given in the variable declaration, when the execution flow enters the scope of the automatic variable declaration, the variable is initialized by the implicit assignment statement.
3) When there are multiple values ​​in the initial value list, multiple assignment statements will be generated.

4. If the array is very large, you need to consider whether to re-initialize the array every time the execution flow enters the code block or declare the array as static to initialize once.

5. The initialization list is allowed to be smaller than the specified length of the array, and the array is partially initialized, and several elements at the end of the array are initialized to 0.
6. When the length of the array is not specified, the compiler will set the length of the array as the length of the initialization value list.
7. When a string constant is used as an initial value list to initialize a character array, it means an initial value list instead of a string constant.

Multidimensional Arrays

Array name
1, the storage order of multi-dimensional array elements in C is based on the principle that the rightmost subscript changes first, which is called row-major order.
2. The value of a one-dimensional array name is a pointer constant, and its type is a pointer to the element type, which points to the first element of the array. The first dimension of a multi-dimensional array is actually another array, and the value of the array name points to the first element. pointer, the array name is a pointer to another array.
3. Multi-dimensional array name + integer, the integer needs to be adjusted * the length of the sub-array, move to another sub-array, perform an indirect access operation on it to get a sub-array, sub-array + integer, adjust according to the length of the sub-array elements, and get the pointer The pointer to the integer subscript element of the subarray, and the array element is obtained by indirect access to the pointer.
4. Subscripts can be used instead of indirect access. Subscripts are calculated from left to right. The array name is a pointer to the first dimension element. The first subscript is adjusted according to the length of the element, and the result is a pointer to the first dimension. A pointer to an element of a certain dimension. The indirect access operation selects the element of the first dimension. The element itself is an array, so the expression type is a pointer to the first element of the next dimension, and the next subscript value is based on the length of the element in the next dimension. Adjustments are made, and the process is repeated until all subscripts have been calculated.

Pointer
1, pointer to the array int (*p)[10]; subscript reference priority is higher than indirect access, so adding parentheses means that p is a pointer, pointing to an integer array with a length of 10.
1) The length of the array must be specified. When pointer + integer, the integer needs to be adjusted according to the length of the array.
2) If the length of the array pointed to by the declared pointer is empty, adjust according to the length of the empty array.

2. Pointer array int *api[10]; the priority of subscript reference is higher than that of indirect access, and api is an array of 10 pointers to integer elements.

3. The method of passing the name of a multi-dimensional array as a function parameter is the same as that of a one-dimensional array, and what is actually passed is a pointer to the first element of the array.
1) The difference is that each element of a multidimensional array is another array, and the compiler needs to know the dimension in order to evaluate the subscript expression of the function parameter.
2) The compiler must know the length of the second dimension and subsequent dimensions to adjust the number of subscripts according to the dimension, and only the first dimension can be omitted.

Initialization
1, multidimensional array initialization.
1) One method is the initial value list, and the storage order is determined according to the principle that the rightmost subscript changes first.
2) Another method is based on the fact that multidimensional arrays are one-dimensional arrays of complex elements, using the initial value list of complex elements to combine into an initial value list of multidimensional arrays. Each initializer-list is itself a list of initializers, the last few initializers of which can be omitted.

2. In a multidimensional array, only the first dimension can be inferred from the initialization list, and the remaining dimensions must be provided explicitly.

Summary
1. In most expressions, the array name is a pointer to the first element of the array, except sizeof and unary operator &.
1) sizeof returns the bytes occupied by the entire array rather than the bytes occupied by a pointer.
2) & is returning a pointer to an array, not a pointer to a pointer to the first element of the array.

2. Except for the difference in priority, the subscript expression array[value] is the same as the indirect access expression *(array+value).
3. Subscripts can be used not only in array names but also in pointer expressions.
4. When declaring an array, the memory space of the array is allocated at the same time to accommodate the elements of the array. When declaring the pointer, only the memory space of the pointer is allocated.

5. When the array name is passed as a function parameter, the pointer to the first element of the array is passed to the function, and the parameter received by the function is a copy of the pointer.
1) The function can modify the pointer point without affecting the original parameter, but the indirect access to the pointer will modify the elements of the array.
2) An array parameter can be declared as a pointer or as a pointer, and the two declaration methods are equal only when used as a function parameter.

6. Arrays can be initialized with an initializer list.
1) Static variables including arrays get initial values ​​when the program is loaded into memory.
2) Automatic variables including arrays are initialized with assignment statements every time the execution flow enters the code block where the declaration is located.
3) When the number of initial value lists is less than the number of array elements, the last few elements of the array are initialized with default values.
4) If the length of the array is not given, it is inferred from the number of the initial value list.

7. A multidimensional array is a special type of a one-dimensional array. Each element itself is also an array. Elements are stored in row-major order, and the rightmost subscript changes first.
8. The name of the multi-dimensional array is a pointer to the first element of the array, that is, a pointer to the array. The operation on this pointer will adjust the operand according to the length of the array it points to.
9. The multidimensional array subscript reference can also be a pointer expression.
10. When the multi-dimensional array name is passed as a function parameter, the length of the second and subsequent dimensions must be explicitly indicated in the formal parameter declaration.
11. Multidimensional arrays can be initialized by nested initializer lists, and only the length of the first dimension can be inferred by the compiler.

Guess you like

Origin blog.csdn.net/mei_true/article/details/131074381