问题描述
我试图了解指向数组的指针是如何工作的。一段代码;
#include<stdio.h>
int main()
{
int arr[3] = { 0,8,10 };
int (*ptr)[3] = &arr;
int i = 0;
for (i = 0; i < 3 ; i++)
printf("Address (%p) - value( %d)\n",(*ptr+i),*(*ptr + i));
return 0;
}
星号 *
取消引用 ptr
。如果 i = 1
,为什么 (*ptr+i) = ith value
不是 value at ptr + i
。
解决方法
ptr
的类型是 int (*)[3]
(指向 int
长度为 3 的数组的指针)。 *ptr
的类型是 int[3]
(int
的数组长度为 3)。在大多数表达式中,int[3]
类型的操作数被转换为指向数组第一个元素的 int *
(指向 int
的指针)。表达式 (*ptr+i)
通过指针运算生成指向数组第 i
个元素的指针。在表达式 *(*ptr+i)
中,指向数组第 i
个元素的指针被取消引用以生成数组的第 i
个元素的值,该值的类型为 {{1} }.
以下是这些表达之间的关系:
ptr == &arr // int (*)[3] == int (*)[3]
*ptr == arr // int [3] == int [3]
除非它是 sizeof
或一元 &
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则类型为 表达式 “T
的 N 元素数组”将被转换或“衰减”为“指向 T
的指针”类型的表达式,表达式的值将是第一个元素的地址数组。因此,在下面的表达式中,*ptr
和 arr
从类型“int
的 3 元素数组”“衰减”到“指向 int
的指针”,它们的值是arr
的第一个元素的地址:
(*ptr + i) == (arr + i) == &arr[i] // int * == int * == int *
*(*ptr + i) == *(arr + i) == arr[i] // int == int == int
,
这里使用了malloc
,但概念与分配一维数组的地址相同。
阅读内联评论,以便更好地理解。
#include <stdio.h>
#include <stdlib.h>
#define NCOLS 5
#define NROWS 2
void function( int (*_2D_ptr_Array)[NCOLS],int nrows,int ncols );
//enable this to see the demo of accessing elements using pointer to an array
//disabling this will demo how to pass 2-D array and collect using pointer to an array.
//#define _DEMO_MAIN
int main()
{
// a is a pointer to an array of 5 ints
int (*a)[NCOLS];
int _2D_Array[NROWS][NCOLS] = {
{ 10,20,30,40,50},{ 60,70,80,90,100}
};
int i,j;
#ifdef _DEMO_MAIN
printf("Enter 10 elements\n");
a = malloc(sizeof(int)*5*2);
printf("a got address at %p\n",a);
for(i=0;i<2;i++)
for(j=0;j<5;j++)
scanf("%d",a[i]+j);
//printing one dimentional array values
// *a is equivalent to a[j],when j = 0
for(j=0;j<5;j++)
printf("value %d is at addr %p\n",*(*a+j),(*a+j));
putchar('\n');
//printing multi-dimentional array values
// adding j to a[i] or *a gives the next element address in a given row.
for(i=0;i<2;i++)
for(j=0;j<5;j++)
printf("value %d is at %p\n",*(a[i]+j),a[i]+j);
#else
//a most common use of pointer to an array is to collect the 2-d array as an argument in function
function( _2D_Array,NROWS,NCOLS );
#endif
return 0;
}
void function( int (*_2D_ptr_Array)[NCOLS],int ncols ) {
for(int r = 0; r < nrows ; r++) {
for(int c = 0; c < ncols ; c++)
printf("%d ",_2D_ptr_Array[r][c]);
printf("\n");
}
}
注意:对 scanf
和 malloc
等函数的返回检查不是有目的地处理