为什么我需要使用二维数组的额外星号?
Why Do I need that extra asterix using 2D array?
我知道如果 arr
是一个数组那么 arr[i]=*(arr+i)
;如果是二维数组,则 arr[i][j]=*(*(arr+i)+j)
;所以我有这个代码
main(){
int arr[5][5];
int arr2[25]; // same as arr[5][5];
int i,j;
for(i=0;i<5;i++)
for(j=0;j<5;j++){
arr[i][j]=i+j;
printf("arr[%d][%d] is at %p\n",i,j,&arr[i][j]);
}
printf("*(arr+i)=%d\n",*(arr+1)); // why this dont work
for(i=0;i<24;i++){
arr2[i]=i;
printf("arr2[%d] is at %p\n",i,(arr2+i));
}
printf("*(arr+i)=%d\n",*(arr2+1)); // prints 1 as expected
}
我知道在 C 中没有二维数组这样的东西,它基本上是一个线性行主要连续的内存块。所以我想知道为什么我不能使用 *(arr+1) 打印 2D arr 的值,这意味着将 1*5*4
字节添加到 arr 的基址并取消引用该地址处的值。我知道 **(arr+1)
有效,但我不知道为什么我需要那个额外的星号?此外,如果我这样做 printf("*(arr+i)=%p\n",*(arr+1));
与我将使用 (arr+i)
解释为地址相同
*(arr+1)
的类型=arr[1]
的类型=int [5]
,在printf
中使用会衰减到int*
。
要打印指针,请使用:
printf("*(arr+i)=%p\n", *(arr+1));
要打印它指向的对象,请使用:
printf("*(*(arr+i))=%d\n", *(*(arr+1)));
您可以使用以下方法使您的代码更易于阅读:
printf("arr[1] = %p\n", arr[1]); // Print the pointer
printf("arr[1][0] = %d\n", arr[1][0]); // Print the value
如您所说,C 中的二维数组基本上是一维数组的数组。您可能会将其视为行数组。
最右边的 *
将取消引用外部数组,选择您想要的行。
*(arr+i) //this gives me a pointer to the row I want
左边的 *
将取消引用内部数组,从行中选择一个元素。
*(*(arr+i)+j) //this gives me an element in the row
**(arr+i)
只是上面的一个特例,其中列号 j
是 0
.
arr
是 int
数组的数组。它的类型是int [5][5]
。所以,arr
的元素是一维数组。在表达式中使用时,在大多数情况下,数组会转换为指向其第一个元素的指针。在 *(arr + 1)
中,arr
被转换为指向 arr[0]
的指针,即第一个一维数组。添加 1
会将其递增 5*4 = 20
字节,即数组 arr
的下一个元素是 arr[1]
。
由于arr[1]
是一个数组,所以不能打印(整体),但是它的地址可以。 arr[1]
本身是一个数组,它会衰减到指向其第一个元素的指针,即 arr[1][0]
。要打印其元素,您需要另一个取消引用,这是通过 arr[1][j]
实现的(j
是列)。
arr[1][j]
等价于 *(arr[1] + j)
最终等价于 *(*(arr + 1) + j)
。
推荐阅读:What exactly is the array name in c?
我知道如果 arr
是一个数组那么 arr[i]=*(arr+i)
;如果是二维数组,则 arr[i][j]=*(*(arr+i)+j)
;所以我有这个代码
main(){
int arr[5][5];
int arr2[25]; // same as arr[5][5];
int i,j;
for(i=0;i<5;i++)
for(j=0;j<5;j++){
arr[i][j]=i+j;
printf("arr[%d][%d] is at %p\n",i,j,&arr[i][j]);
}
printf("*(arr+i)=%d\n",*(arr+1)); // why this dont work
for(i=0;i<24;i++){
arr2[i]=i;
printf("arr2[%d] is at %p\n",i,(arr2+i));
}
printf("*(arr+i)=%d\n",*(arr2+1)); // prints 1 as expected
}
我知道在 C 中没有二维数组这样的东西,它基本上是一个线性行主要连续的内存块。所以我想知道为什么我不能使用 *(arr+1) 打印 2D arr 的值,这意味着将 1*5*4
字节添加到 arr 的基址并取消引用该地址处的值。我知道 **(arr+1)
有效,但我不知道为什么我需要那个额外的星号?此外,如果我这样做 printf("*(arr+i)=%p\n",*(arr+1));
与我将使用 (arr+i)
解释为地址相同
*(arr+1)
的类型=arr[1]
的类型=int [5]
,在printf
中使用会衰减到int*
。
要打印指针,请使用:
printf("*(arr+i)=%p\n", *(arr+1));
要打印它指向的对象,请使用:
printf("*(*(arr+i))=%d\n", *(*(arr+1)));
您可以使用以下方法使您的代码更易于阅读:
printf("arr[1] = %p\n", arr[1]); // Print the pointer
printf("arr[1][0] = %d\n", arr[1][0]); // Print the value
如您所说,C 中的二维数组基本上是一维数组的数组。您可能会将其视为行数组。
最右边的 *
将取消引用外部数组,选择您想要的行。
*(arr+i) //this gives me a pointer to the row I want
左边的 *
将取消引用内部数组,从行中选择一个元素。
*(*(arr+i)+j) //this gives me an element in the row
**(arr+i)
只是上面的一个特例,其中列号 j
是 0
.
arr
是 int
数组的数组。它的类型是int [5][5]
。所以,arr
的元素是一维数组。在表达式中使用时,在大多数情况下,数组会转换为指向其第一个元素的指针。在 *(arr + 1)
中,arr
被转换为指向 arr[0]
的指针,即第一个一维数组。添加 1
会将其递增 5*4 = 20
字节,即数组 arr
的下一个元素是 arr[1]
。
由于arr[1]
是一个数组,所以不能打印(整体),但是它的地址可以。 arr[1]
本身是一个数组,它会衰减到指向其第一个元素的指针,即 arr[1][0]
。要打印其元素,您需要另一个取消引用,这是通过 arr[1][j]
实现的(j
是列)。
arr[1][j]
等价于 *(arr[1] + j)
最终等价于 *(*(arr + 1) + j)
。
推荐阅读:What exactly is the array name in c?