**(x + i)和*(* x + i)之间的差异

时间:2019-09-22 23:50:35

标签: c pointers

我正在使用一个指针数组,其中每个索引都包含一个指向整数数组的指针。虽然我能够弄清楚如何使用指针数组在数组中打印值,但是我需要澄清一行代码。我想了解**(x + i)和*(* x + i)之间的区别,因为前者引发了Segmentation Fault异常,而后者则输出了所需的输出。请参考下面的示例代码。

int pointer_array=malloc(1*sizeof(int*));
int number_array = malloc(2*sizeof(int));
*(pointer_array)=number_array; 
for(int i=0;i<2;i++) {
  *(pointer_array+i)=i;
}
for(int i=0;i<2;i++) {
  //printf("\n%d",**(pointer_arr+i));  This throws Segmentation Fault exception
    printf("\n%d",*(*pointer_arr+i)); // This prints the desired output 0 \n 1
}

3 个答案:

答案 0 :(得分:6)

如果我们通过使用*(a + i) == a[i]等价及其推论*a == a[0]将它们转换为数组符号,则表达式之间的区别将变得非常明显。

**(x + i)x[i][0],而*(*x + i)x[0][i]

在您的代码中,我们想要这样做:

#include <stdlib.h>

int **pointer_array = malloc(1*sizeof(int*));
    ^^

int *number_array = malloc(2*sizeof(int));
    ^

然后其余的代码就是这样:

*(pointer_array)=number_array; // pointer_array[0] = number_array

糟糕:循环将整数分配给指针:

for(int i=0;i<2;i++) {
  *(pointer_array+i)=i;  // pointer_array[i] = i
}

以上内容可能是number_array[i] = i

for(int i=0;i<2;i++) {

  printf("\n%d",*(*pointer_arr+i)); // printf ... pointer_arr[0][i]
}

如果我们纠正第一个循环以初始化number_array,那么第二个循环应检索这些值。

否则,我们将继续使用未初始化的值。

答案 1 :(得分:0)

**(x+i)的意思是“求值x+i,它将给出一个指针,然后读取其指向的值,这将给出另一个指针,然后读取其指向的值”,或等效地,x[i][0]*(*x+i)的意思是“求值x,它将给出一个指针,然后读取它指向的值,这将给出另一个指针,然后向其添加i,然后读取该值它指向”,或等效地为x[0][i]。显然,这是非常不同的表达方式。

答案 2 :(得分:0)

您的代码不安全; malloc将返回void * —指针类型。您将结果存储在int中。无法保证int的大小足以存储void *,并且实际上不会在当前的主要体系结构x86上使用。

话虽这么说

  • (x+i)(如果x是指针)将求值为i*sizeof(*x) + x。因此,它将求出一个指针,该指针在x后面是i个插槽;
  • **(x+i)因此将从x之后的i插槽读取指针,然后读取该指针指向的任何内容。

因此,从指向数组的指针数组中,它将从第i个数组中读取第一项。

位置:

  • *x+i将从x中读取一个指针,然后向其添加i * sizeof(** x);
  • *(*x+i)从那里读取一个指针并取消引用。

因此,从指向数组的指针数组中,它将从第一个数组中读取第i个项目。