Detailed explanation of pointer array and array pointer

Reprinted from: https://blog.csdn.net/men_wen/article/details/52694069

 

Detailed explanation of pointer array and array pointer

1. What are pointer arrays and array pointers?

  • Pointer array: The pointer array can be said to be an "array of pointers". First, this variable is an array, and secondly, "pointer" modifies the array, which means that all elements of the array are pointer types. In a 32-bit system, The pointer occupies four bytes.
  • Array pointer: An array pointer can be said to be a "pointer to an array". First, this variable is a pointer, and secondly, "array" modifies the pointer, which means that the pointer stores the first address of an array, or that the pointer points to a The first address of the array. 
    According to the above explanation, you can understand the difference between a pointer array and an array pointer, because the two are fundamentally different types of variables.

2. What exactly are pointer arrays and array pointers?

2.1 Array of pointers

First define an array of pointers. Since it is an array, the name is called arr

char *arr[4] = {"hello", "world", "shannxi", "xian"}; //arr就是我定义的一个指针数组,它有四个元素,每个元素是一个char *类型的指针,这些指针存放着其对应字符串的首地址。

(When an operator appears on the left and right of a variable, people who don't remember the operator's precedence will be confused about which operator the arr variable is combined with first. If you define an array of pointers yourself, you can't figure out the operator's Priority, then add parentheses (), such as defining an array of pointers, which can be written as char *(arr[4]), but you must be clear about the variables you define before defining them. If the purpose is an array, then put enclose arr[4], if it is a pointer, enclose *arr. If you see a piece of code like this, you can distinguish whether it is an array or a pointer from its initialization. Obviously, what I define here is a Arrays, if pointers, are initialized with NULL.)

How big is this array of pointers? The answer is 16 bytes because it's an array of pointers. (This is nonsense, let's talk about it below) 
Whenever these problems occur, you must react to the first time in your mind内存映像图

memory map content permission
stack area Ordinary variables in functions read and write
heap area dynamically allocated memory read and write
static variable area static modified variable read and write
data area constants used to initialize variables read only
code area code instructions read only

The leftmost column here is a very simple but explanatory memory map. In general, from the stack area to the code area, it is from high address to low address. The stack grows downward and the heap grows upward.

arr[4] is an array defined in the main function. Corresponding it to the corresponding memory, arr is an 栈区array with four elements, and each array is a pointer, so its four elements each occupy four bytes, so the size of the variable arr is 16 bytes.

So someone asked? What the hell is initializing arr's {"hello", "world", "shannxi", "xian"};? 
These four are not ghosts. They also exist in memory, but they are not in the same space as the variable arr. They are allocated in 只读数据区the four pointer elements of the array arr[4], which respectively store the first of the four strings. Address, imagine, from the stack area there are four invisible fingers pointing to the space of the data area. arr+1 will skip four bytes, . That is, the size of a pointer 
is equivalent to the definition of char *p1 = "hello", char *p1 = "world", char *p3 = "shannxi", char *p4 = "xian", which are four pointers, each Each pointer stores the first address of a string, and then uses the array arr[4] to store these four pointers respectively, forming an array of pointers.

2.2 Array pointers

First, define an array pointer. Since it is a pointer, the name is called pa

char (*pa)[4];

If the variable names of the pointer array and the array pointer are the same, it will be like this: char *pa[4] and char (*pa)[4], the fundamental reason for the formation of the pointer array and the array pointer is the priority of the operator problem, so you must pay attention to this problem when defining variables, otherwise there will be fundamental differences in defining variables!

pa is a pointer to an array of char [4], and each array element is a variable of type char, so we might as well write it as: char[4] (*pa); so that we can intuitively see what pa is pointing to Type, but don't write it like this in the editor, because the compiler doesn't know it at all, it's just to help us understand.

Since pa is a pointer that stores the address of an array, when we define an array, the name of the array is the first address of the array, so what is the difference and connection between the two?

char a[4];,

a is a character array of length 4, and a is the address of the first element of the array. Since a is an address and pa is a pointer to an array, can we assign a to pa? The answer is no! Because a is the first address of the first element of the array, pa stores the first address of the array, a is of type char, a+1, the value of a will actually increase by 1, and pa is of type char[4], pa+ 1, pa will add 4, although the value of the first address of the array and the first address of the first element are the same, but the two operations are different, so the type mismatch cannot be directly assigned, but it can be like this: pa = &a, pa is equivalent to a two-dimensional array , now it points to the address of a[4].

3. Use of pointer arrays and array pointers

3.1 The use of pointer arrays in parameter passing

The pointer array is often used 主函数传参. When writing the main function, there are two parameters, one to determine the number of parameters, and the other is the address of the pointer array used to receive each parameter (string)

int main(int argc, char *argv[])

At this point, you can imagine the memory map. The stack area of ​​the main function has an array called argv. The elements of this array are the addresses of the parameters you input, pointing to the read-only data area.

If it is to 子函数传参, this is the same as the idea of ​​passing an ordinary array. You cannot pass the entire array in the past. If the array is large, the memory utilization is very low, so you should pass the first address of the array, and use a pointer to receive this address. Therefore, the pointer array corresponds to the second-level pointer

void fun(char **pp);//子函数中的形参
fun(char *p[]);//主函数中的实参

3.2 Sorting an array of pointers

The sorting of the pointer array is very interesting, because the pointers are stored in this array, through 比较指针指向的空间的大小,排序这些空间的地址. The function is implemented as follows:

void sort(char **pa, int n)//冒泡排序
{
    int i, j;
    char *tmp = NULL;

    for(i = 0; i < n-1; i++){
        for(j = 0; j < n-1-i; j++){
            if((strcmp(*pa+j), *(pa+j+1)) > 0){
                tmp = *(pa + j);
                *(pa + j) = *(pa + j + 1);
                *(pa + j + 1) = tmp;
            }
        }
    }
}

Define an array of pointers in the function, and print the result as follows:

char *pa[4] = {"abc", "xyz", "opq", "xyz"};

[root@menwen-linux test]# ./test 
abc
ijk
opq
xyz

The use of array pointers when passing parameters

Since the array pointer is a pointer, it is used to receive the address, and the address of the array is received when the parameter is passed, so the array pointer corresponds to a two-dimensional array.

void fun(int (*P)[4]);//子函数中的形参,指针数组 

a[3][4] = {0};//主函数中定义的二维数组
fun(a);//主函数调用子函数的实参,是二维数组的首元素首地址

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325077389&siteId=291194637