C language: pointer to array and pointer to first element of array

Related Reading

C language icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12423166.html?spm=1001.2014.3001.5482


        Pointers to arrays and pointers to the first element of an array are often confused, or loosely referred to as array pointers, but there is a difference between them, which this article will discuss.

        The following code first creates an array, then creates a pointer to the array and a pointer to the first element of the array.

int arr[] = {0,1,2};
int *ptr0 = arr;     //创建了一个int型指针,指针值为数组首元素地址
int *ptr1 = &arr[0]; //创建了一个int型指针,指针值为数组首元素地址
int (*ptr2) [3] = &arr;  //创建了一个int型数组指针,指针值为整个数组的地址

        The three pointers above actually have the same pointer values, that is, the three constants arr==&arr[0]==&arr (although this seems a bit strange), so what is the difference between them?

  • There is no difference between &arr[0] and arr to the compiler, so the various properties of the two pointers ptr0 and ptr1 are the same.
  • Although the constant value of &arr is the same as the other two, to the compiler, it represents the address of the entire array. Therefore, when &arr is added or subtracted from other numbers, the other numbers will be converted into the number of bytes of the array. The address value is also the same for pointer ptr2.
例1
int arr[] = {0,1,2};
//下面两条语句等价
int *ptr0 = arr;      //创建了一个int型指针,指针值为数组首元素地址
int *ptr1 = &arr[0];  //创建了一个int型指针,指针值为数组首元素地址
int (*ptr2) [3] = &arr; //创建了一个int型数组指针,指针值为整个数组的地址
 
printf("arr is %p\n", arr);
printf("arr + 1 is %p\n", arr + 1);
printf("&arr[0] is %p\n", &arr[0]);
printf("&arr[0] + 1 is %p\n", &arr[0] + 1);
printf("&arr is %p\n", &arr);
printf("&arr + 1 is %p\n", &arr + 1);
 
printf("ptr0 is %p\n", ptr0);
printf("ptr0 + 1 is %p\n", ptr0 + 1);
printf("ptr1 is %p\n", ptr1);
printf("ptr1 + 1 is %p\n", ptr1 + 1);
printf("ptr2 is %p\n", ptr2);
printf("ptr2 + 1 is %p\n", ptr2 + 1);
 
输出:
arr is         000000000061FDFC
arr + 1 is     000000000061FE00
&arr[0] is     000000000061FDFC
&arr[0] + 1 is 000000000061FE00
&arr is        000000000061FDFC
&arr + 1 is    000000000061FE08
ptr0 is        000000000061FDFC
ptr0 + 1 is    000000000061FE00
ptr1 is        000000000061FDFC
ptr1 + 1 is    000000000061FE00
ptr2 is        000000000061FDFC
ptr2 + 1 is    000000000061FE08

         From Example 1 above, we can see that the values ​​of arr, &arr[0], &arr, ptr0, ptr1, and ptr2 are all the same, but the addition of arr, &arr[0], ptr0, and ptr1 by 1 adds 1 to the address value after compilation. 4. Because the int type occupies 4 bytes of space; &arr and ptr2 plus 1 add 12 to the address value after compilation. Because the array contains three int type data, the array occupies 12 bytes of space.

        Pointers to arrays are common when working with multidimensional arrays, as shown in Example 2 below.

例2
int arr[2][2] = {
   
   {0,1},{2,3}}; //创建一个多维数组

int (*ptr0) [2][2] = &arr; //创建了一个int型二维数组指针,指针值为二维数组的地址 
//下面两条语句等价
int (*ptr1) [2] = arr;     //创建了一个int型一维数组指针,指针值为两个数组中第一个数组的地址 
int (*ptr2) [2] = &arr[0]; //创建了一个int型一维数组指针,指针值为两个数组中第一个数组的地址
int *ptr3 = arr[0];        //创建了一个int型指针,指针值为两个数组中第一个数组的首元素地址
int *ptr4 = &arr[0][0];    //创建了一个int型指针,指针值为两个数组中第一个数组的首元素地址



printf("ptr0 is %p\n", ptr0);
printf("ptr0 + 1 is %p\n", ptr0 + 1);
printf("ptr1 is %p\n", &arr[0]);
printf("ptr1 + 1 is %p\n", ptr1 + 1);
printf("ptr2 is %p\n", ptr2);
printf("ptr2 + 1 is %p\n", ptr2 + 1);
printf("ptr3 is %p\n", ptr3);
printf("ptr3 + 1 is %p\n", ptr3 + 1);
printf("ptr4 is %p\n", ptr4);
printf("ptr4+ 1 is %p\n", ptr4 + 1);

输出:
ptr0 is     000000000061FDE0
ptr0 + 1 is 000000000061FDF0
ptr1 is     000000000061FDE0
ptr1 + 1 is 000000000061FDE8
ptr2 is     000000000061FDE0
ptr2 + 1 is 000000000061FDE8
ptr3 is     000000000061FDE0
ptr3 + 1 is 000000000061FDE4
ptr4 is     000000000061FDE0
ptr4+ 1 is  000000000061FDE4

        It can be seen that even if the values ​​of ptr0, ptr1, ptr2, and ptr3 are the same, ptr0+1 adds 16 to the address value after compilation (the two-dimensional array occupies 4 bytes of space), ptr1+1 and ptr2+1 After compilation, 8 is added to the address value (the one-dimensional array occupies 8 bytes of space), and ptr3+1 adds 4 to the address value after compilation (the int type occupies 4 bytes of space).

        Example 3 below shows how to use a pointer to an array and a pointer to the first element of the array.

例3
int arr[] = {0,1,2};
//下面两条语句等价
int *ptr0 = arr;        //创建了一个int型指针,指针值为数组首元素地址
int *ptr1 = &arr[0];    //创建了一个int型指针,指针值为数组首元素地址
int (*ptr2) [3] = &arr; //创建了一个int型数组指针,指针值为整个数组的地址

printf("arr[0] is %d\n", ptr0[0]); //使用指向数组首元素的指针和[]打印0
printf("arr[1] is %d\n", ptr0[1]); //使用指向数组首元素的指针和[]打印1
printf("arr[2] is %d\n", ptr0[2]); //使用指向数组首元素的指针和[]打印2

printf("arr[0] is %d\n", arr[0]);  //使用数组名和[]打印0
printf("arr[1] is %d\n", arr[1]);  //使用数组名和[]打印1
printf("arr[2] is %d\n", arr[2]);  //使用数组名和[]打印2

//一个很傻的例子,它是不必要的
printf("arr[0] is %d\n", (&arr[0])[0]);  //使用首元素地址和[]打印0
printf("arr[1] is %d\n", (&arr[0])[1]);  //使用首元素地址和[]打印1
printf("arr[2] is %d\n", (&arr[0])[2]);  //使用首元素地址和[]打印2

//实际上还能更傻,这么做的可读性很差
printf("arr[0] is %d\n", (&((&arr[0])[0]))[0]);  //奇怪地打印0
printf("arr[1] is %d\n", (&((&arr[0])[0]))[1]);  //奇怪地打印1
printf("arr[2] is %d\n", (&((&arr[0])[0]))[2]);  //奇怪地打印2

//尽管ptr2的值和ptr1、ptr0一样,但仍需先用*解引用才能再使用[]访问元素
printf("arr[0] is %d\n", (*ptr2)[0]);  //使用指向数组的指针和[]打印0
printf("arr[1] is %d\n", (*ptr2)[1]);  //使用指向数组的指针和[]打印1
printf("arr[2] is %d\n", (*ptr2)[2]);  //使用指向数组的指针和[]打印2

printf("arr[0] is %d\n", ptr2[0]);  //错误的
printf("arr[1] is %d\n", ptr2[1]);  //错误的
printf("arr[2] is %d\n", ptr2[2]);  //错误的

printf("arr[0] is %d\n", *(ptr0 + 0)); //使用指向数组首元素的指针和*打印0
printf("arr[1] is %d\n", *(ptr0 + 1)); //使用指向数组首元素的指针和*打印1
printf("arr[2] is %d\n", *(ptr0 + 2)); //使用指向数组首元素的指针和*打印2

printf("arr[0] is %d\n", *(arr + 0));  //使用数组名和*打印0
printf("arr[1] is %d\n", *(arr + 1));  //使用数组名和*打印1
printf("arr[2] is %d\n", *(arr + 2));  //使用数组名和*打印2

//尽管ptr2的值和ptr1、ptr0一样,但仍需先用*解引用才能再使用*访问元素
printf("arr[0] is %d\n", *((*ptr2) + 0));  //使用指向数组的指针和*打印0
printf("arr[1] is %d\n", *((*ptr2) + 1));  //使用指向数组的指针和*打印1
printf("arr[2] is %d\n", *((*ptr2) + 2));  //使用指向数组的指针和*打印2

printf("arr[0] is %d\n", *(ptr2 + 0));  //错误的
printf("arr[1] is %d\n", *(ptr2 + 1));  //错误的
printf("arr[2] is %d\n", *(ptr2 + 2));  //错误的

        I believe that through this article, readers should have a full understanding of pointers to arrays and pointers to the first element of arrays, and be able to use pointers with ease in subsequent programming.

Guess you like

Origin blog.csdn.net/weixin_45791458/article/details/134976287