2017-09-24 133 views
2
#include <stdio.h> 

int main() 
{ 
    int a[]={11,12,13},*p; 
    printf("%x\n",a); 

    for(int i=0;i<3;i++) 
     printf("%x ",(a+i)); 

    p=(&a)+1; //LINE1 
    printf("this is this %x\n",p); //LINE2 
    printf("%d ",*p); 
    printf("%d\n",*(p-1)); 
    return 0; 
} 

在LINE1上进行指针运算后,为什么LINE2打印的地址不等于a [1]?相反,还有4个字节的差异。int * p = somearray但(p + 1)不等于somearray的地址[1]。为什么?

+1

请您分享该程序的输出。这很难理解,至少对我来说 –

+0

'printf''%x'接受一个'unsigned int',而不是'int *'。 – melpomene

+3

'a'的类型为int(*)[3]'。表达式'(&a)+ 1'偏移指针'sizeof(int(*)[3])'。取出'&'。 –

回答

4

当你写

&a 

您正在获取数组a的地址。由于数组a的类型为int [3],因此该指针的类型为int (*) [3],这是一个指向三个整数数组的指针。

当你再写入

&a + 1 

你说“去了一个对象,在过去的a一个指向。”请记住,a的类型为int (*) [3],因此C解释为指向“指向三个int的数组,后面跟着a指向的三个int的数组。因此,您将指向3 × sizeof(int)个字节,超出了阵列的底部,而不是您会找到元素a[1]的位置。

你大概应该从线得到一个编译器警告

p = (&a) + 1 

,因为类型是错误的。指针pint *,右侧的表达式的类型为int (*) [3]。使用高警告设置进行编译可能会提醒您某些事情是错误的,这可能会导致您错误地发现某些事情并不完全正确。我建议今后进行高级警告设置编译,因为这些天编译器报告的许多警告是合法的问题。

有几件事你可以做,以解决这个问题。之一将是写

&a[0] + 1 

表达&a[0]装置“的指针的a第一元件”和具有类型int *,因此当添加一个到它,C将此解释为表示“点到下一个inta[0]后,这是在a[1]生命。

由于阵列到指针衰减,也可以写

a + 1 

因为C解释表达式a作为指向a(即&a[0])的第一个元素的指针。

总结:

  • 指针运算依赖于底层类型的大小。
  • 写入&a为您提供指向元素数组的指针,而不是指向数组的第一个元素的指针。地址相同,但类型不同。
0

你需要在数组中的元素使用指针运算: 一个已经INT *,所以你有两个选择:

p=(&a[0])+1; //LINE1 

p=a+1; //LINE1 
+0

正确。或只是'p = a + 1;' – Soonts

+0

加上它,thks – Gabriel

1

对于指针算术,您应该知道指针的类型。 现在这里是一个指向3个元素的整数数组的指针。 即a的数据类型是int(*)[3]。

每当你给a加1时,它会指向3个整数后的下一个存储单元。 和指针类型&(a [0])是int *。

希望这会解决您的问题。

相关问题