C中的指针算术

我有以下代码。 也许我没有理解指针算法以及我应该有但是为什么int_pointer增加4而不是1? 使用char_pointer,为什么它不会增加4而不是1?

#include  int main() { int i; char char_array[5] = {'a', 'b', 'c', 'd', 'e'}; int int_array[5] = {1, 2, 3, 4, 5}; char *char_pointer; int *int_pointer; char_pointer = int_array; // The char_pointer and int_pointer now int_pointer = char_array; // point to incompatible data types. for(i=0; i < 5; i++) { // Iterate through the int array with the int_pointer. printf("[integer pointer] points to %p, which contains the char '%c'\n", int_pointer, *int_pointer); int_pointer = int_pointer + 1; } for(i=0; i < 5; i++) { // Iterate through the char array with the char_pointer. printf("[char pointer] points to %p, which contains the integer %d\n", char_pointer, *char_pointer); char_pointer = char_pointer + 1; } } 

OUTPUT:

 [integer pointer] points to 0xbffff810, which contains the char 'a' [integer pointer] points to 0xbffff814, which contains the char 'e' [integer pointer] points to 0xbffff818, which contains the char ' ' [integer pointer] points to 0xbffff81c, which contains the char ' [integer pointer] points to 0xbffff820, which contains the char ' ' [char pointer] points to 0xbffff7f0, which contains the integer 1 [char pointer] points to 0xbffff7f1, which contains the integer 0 [char pointer] points to 0xbffff7f2, which contains the integer 0 [char pointer] points to 0xbffff7f3, which contains the integer 0 [char pointer] points to 0xbffff7f4, which contains the integer 2 

这就是指针aritmetics的工作方式:如果将指针递增1,则地址会增加指针类型的大小。 因此,在你的机器中,int是4个字节,递增一个int指针会增加4个字节的地址。

未定义的行为

你所拥有的是未定义的行为 ,首先你违反了严格的别名规则 ,这通常使得通过不同类型的指针访问对象是非法的,尽管允许通过char *进行访问。 我将在这里引用我的答案,其中更广泛地涵盖了这一点:

虽然允许通过char *访问,但严格的别名规则使得通过不同类型的指针访问对象是非法的。 允许编译器假设不同类型的指针不指向相同的存储器并相应地进行优化。 它还意味着代码调用未定义的行为,并且可以真正做任何事情。

第二个不同的指针可能有不同的对齐要求,因此通过int指针访问char数组可能会违反此要求,因为char数组可能无法正确对齐int。 C99标准草案在第6.3.2.3节中说明了这一点( 强调我的 ):

指向对象或不完整类型的指针可以转换为指向不同对象或不完整类型的指针。 如果结果指针没有针对指向类型正确对齐57) ,则行为未定义。

使用正确的标志集合的好编译器应该在这里有很多帮助,使用clang和以下标志-std=c99 -fsanitize=undefined -Wall -Wextra -Wconversion -pedantic我看到以下警告( 请参见实时 ):

 warning: incompatible pointer types assigning to 'char *' from 'int [5]' [-Wincompatible-pointer-types] char_pointer = int_array; // The char_pointer and int_pointer now ^ ~~~~~~~~~ warning: incompatible pointer types assigning to 'int *' from 'char [5]' [-Wincompatible-pointer-types] int_pointer = char_array; // point to incompatible data types. ^ ~~~~~~~~~~ 

并在运行时我看到以下错误:

 runtime error: load of misaligned address 0x7fff48833df3 for type 'int', which requires 4 byte alignment 0x7fff48833df3: note: pointer points here 00 e0 3e 83 61 62 63 64 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6d 47 60 5a 1d 7f 00 ^ 

指针算术

因此,指针算法基于所指向类型的大小。 如果数组访问基本上是指针算术的语法糖,那么如何才能正常工作? 您可以在此处阅读更详细的说明和相关讨论 。

在进行指针运算时,它将按您尝试增加的大小递增。 以此为例。

 int a[2]; a[0] = 1; a[1] = 3; a = a + 1 printf("%d\n",*a) \\ 3 

它需要通过指向的东西的大小向前移动。 总是帮助我的是首先将指针转换为char以使用字节。

 int a[2]; a[0] = 1; a[1] = 3; a = (char)a + sizeof(int)*1 printf("%d\n",*a) \\ 3 

这有点容易理解,它会产生你的想法。