Thoroughly smash "the confusion of pointers and arrays" (on)

zhaozj2021-02-16  54

Abstract: The pointer is the essence of the C language, and it is also the essence of C . It is not very easy to master it, especially often with the array, I hope to pass this article, you can have a clear understanding. (1) One-dimensional array and pointer first let's take a look at the following example: Char a [10], * p; p = a; P is a char type pointer, which is put into the first address of array A, namely A [0]; a double meaning here: address, can also be considered as a constant pointer; structure, contains 10 char elements. In this case, the pointer can complete the operation of the array, for example, for an array of access, can be performed with a pointer, or an array unit can be assigned to the array unit. But the array cannot be seen as a normal pointer, it should be understood as a fixed address, she is determined during the compilation, or understanding into a constant pointer. However, due to the double meaning of the number of groups, he determines his own characteristics. If you don't believe it, please see the following procedures: #include #include using namespace std;

INT Main (int Argc, char * argv []) {Int a [10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, * p; p = a;

COUT << a << endl; cout << & a << endl; cout << & a [0] << endl;

Cout << p << endl; cout << & p << endl; cout << & p [0] << ENDL;

System ("pause"); Return 0;} We see the results of A, & A, & A [0] are consistent, they are the first address of the array, here A reflects the characteristics of the pointer, & A is reflected The characteristics of the structure. But for P, it is different because the pointer P opens up its own memory space at the beginning. After p = a, P = A is put into the first address of array A, so P and & P [0] results They are the first address of array A, but & p is the memory address of the pointer P itself. So what is the meaning of one-dimensional array? In fact, a one-dimensional array should understand a linear table, and he has opened a continuous memory space in memory. When accessing the array, in fact, the compiler makes a certain conversion work: array name (start addresses of arrays) plus relative amounts relative to the start address (given by the subscript variable), get to access The unit address of the array element, and then accesses the contents of the calculated unit address. For example, A [3] is converted to * (A 3). Since the array is determined during the compilation period, the representative is a fixed memory space, so the array is unable to change, namely A , a, a -, - a, a = 3, A- = 3, etc. It is not allowed, but the pointer P do these movements is no problem. In memory, the distribution of pointers is only occupied by 4 bytes (do not consider other situations such as 16 bits. After all, the most common is 32-bit, um, ok, let's talk about this problem), But for arrays, it is different. In addition to assigning their own memory cells, some information is saved to store the number of elements. In theory, the compiler can adopt any technique, but in the actual compiler, two more popular techniques are generally used: associated techniques, cookie strategies. The association method is to allocate a static array. There is a compiler to control, put on a map, the keyword can be used in the number of group name valid intervals, the value can be the number of elements, the time to release the memory space, go search accordingly Map, it seems to be a more secure strategy, but it is more slow. Cookie strategy, also known as the transition allocation technology, when no one-time array spatial assignment, add a sizeof (size_t) byte space in a certain location in the array to store the number of elements of the array. This strategy is undoubted, but it is not safe enough, sometimes we can take the value of cookie and modify it, so that the stack space can be destroyed. However, there is an exception here. When the array is passed as a parameter, the number will be automatically used for ordinary pointers, and the benefits of doing this are also obvious: improve efficiency. You can imagine that if you don't make a pointer to pass, the passage of the element will be a big overhead. There is still a very important issue of the pointer, that is, the problem of alignment of the pointer. When you perform your program on the 80x86 processor, this problem is not fatal, but for the vast majority of the chips, this is fatal. It will also have an impact on your application to a certain other environment. In addition, even for Intel processors, this problem may not be fatal, but she will take up more time to convert, there is no doubt that the performance is lowered.

When your pointer is switched from a type to another, it is possible to generate a non-alignment pointer. The processor generally requires the address of the memory block to be aligned with the boundary that matches the size of the memory block. For example, the word can only be accessed on the word boundary (the address is a multiple of the multiple), and the double word can only be accessed on the double word boundary (the address is a multiple of four), and push it according to the class. The compiler typically ensures that this rule is monitored. But when your pointer type is converted from a type to a large type, you can easily violate this rule: char CA; char * pc = & ca; int * pi; pi = (int *) PC; * Pi = 0; because the characters are only one byte length, the address & ca may have any value, including an odd value. However, PI should contain only four times the number of addresses. By conversion, it allows the PC to be assigned to the PI, but if the address is not a quantity, the assignment that occurs can cause the program to crash. However, this situation only occurs when you are converting your pointer from pointing to a type of type. Not finished (to be renewed ...)

转载请注明原文地址:https://www.9cbs.com/read-23881.html

New Post(0)