在下面这段与指针及其输出相关的C代码中,为什么';t将值a[1]即20存储在连续地址de9处?

在下面这段与指针及其输出相关的C代码中,为什么';t将值a[1]即20存储在连续地址de9处?,c,pointers,memory,garbage,C,Pointers,Memory,Garbage,在下面的代码中,每个位置都可以保存32位有符号数据。那么,为什么值a即20不存储在连续地址de9?数组应该将数据存储在连续的内存位置,对吗?我知道这个在线gdb编译器中的sizeof(int)是4个字节,但它怎么可能与在4个位置存储20个字节有关呢?我是否缺少一些基本概念 int main() { int a[2]= {214748368,20}; void *ptr1 = &a; void *ptr2= &a;

在下面的代码中,每个位置都可以保存32位有符号数据。那么,为什么值a即20不存储在连续地址de9?数组应该将数据存储在连续的内存位置,对吗?我知道这个在线gdb编译器中的sizeof(int)是4个字节,但它怎么可能与在4个位置存储20个字节有关呢?我是否缺少一些基本概念

  int main()
    {
     int a[2]= {214748368,20};
       
       void *ptr1 = &a;
       void *ptr2= &a;
       
       ptr1++;
       ptr2 = ptr2;
       
       printf("%d \n", *(int*)ptr2);
       printf("\n Pointer table");
       printf("\n Data : %d at address : %p", *(int*)ptr2, ptr2);
       ptr2=ptr2+1;
       printf("\n Data : %d at address : %p", *(int*)ptr2, ptr2);
       ptr2=ptr2+1;
       printf("\n Data : %d at address : %p", *(int*)ptr2, ptr2);
       ptr2=ptr2+1;
       printf("\n Data : %d at address : %p", *(int*)ptr2, ptr2);
       ptr2=ptr2+1;
       printf("\n Data : %d at address : %p", *(int*)ptr2, ptr2);
       return 0;
    }

当您在C中增加指针时,将使用指针算法。因此,如果指针
a
的类型为
int*
,它将增加
sizeof(int)
。但是,指针的类型为
void*
。这不是故意的,显然它增加了一个字节(请参阅)

由于系统上的
int
的大小为32位或4字节,因此必须将指针增加四倍1字节,才能到达数组中的下一个元素

通过将指针定义为
int*
,可以避免此问题:

int *ptr1 = &a;
int *ptr2 = &a;

在这种情况下,指针递增一次(
ptr2++
)将得到下一个元素。

ptr1++前进1-超过
a
ptr2=ptr2的末尾毫无意义<代码>无效*ptr1=a将允许
ptr1++
指向
a
的第二个元素。这是因为
int
具有
4
(此处)字节宽度,所以它将存储在
4
字节之后,即
a[0]
位于
0x7fff97fb9de9
a[1]
0x7fff97fb9dec
ptr1
的问题是当您在
a
上使用
(地址)运算符时,例如
&a
,结果指针是指向数组
int[2]的指针
而不是允许通过约束冲突进行常规数组/指针转换,因为尝试在
void*
上执行算术。您的编译器有义务发出有关此的诊断消息,但许多c编译器在这种情况下是不一致的。您可以通过为编译器提供正确的命令行参数来取消中断编译器,使其能够正确执行其工作。此程序已中断。
void
指针上的指针算法是非标准的gcc扩展。通过<代码> int <代码>指针访问<代码> int 对象中间的字节是未定义的行为。您可以检查单个字节,但需要通过
char
指针进行检查。