C指针数学与结构

use*_*048 1 c pointers structure

试着更好地学习指针数学我编写了这段代码.目的是增加指针投掷结构并打印它的成员.我知道如何打印它的成员更简单的方法,但我真的想知道我的指针数学是如何搞砸的.谢谢.

typedef struct{ 
  int num;
  int num2;
  char *string;
} astruct ;

int main (int argc, const char * argv[])
{
  astruct mystruct = { 1234, 4567,"aaaaaaa"};

  astruct *address;
  address = &mystruct;

  // this does print 1234
  printf("address 0x%x has value of:%i\n",address, *address); 
  address = address + sizeof(int);

  //this does NOT print 4567
  printf("address 0x%x has value of:%i\n",address, *address); 
  address = address + sizeof(int);

  //this crashes the program, I wanted to print aaaaaaaa
  printf("address 0x%x has value of:%s\n",address, **address); 

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 5

指针运算将指针增加指向的字节数.例如,

int a[2];
int *p = a;

assert( &a[0] == p )
assert( &a[1] == p + 1 )
Run Code Online (Sandbox Code Playgroud)

所以,你的路线

address = address + sizeof(int);
Run Code Online (Sandbox Code Playgroud)

实际上address改为address + sizeof(int) * sizeof(astruct)(使用正常,而不是指针算术).

没有保证可以做你正在尝试的事情,因为允许编译器在结构中引入填充.考虑结构

struct A {
    char a;
    int b;
};
Run Code Online (Sandbox Code Playgroud)

编译器很可能会给这个结构提供以下布局:

+------------+-------------------+-------------+
| a (1 byte) | (3 bytes padding) | b (4 bytes) |
+------------+-------------------+-------------+
Run Code Online (Sandbox Code Playgroud)

所以你不能通过获取bstruct实例的地址并添加1来实现.

在您的特定情况下,编译器可能不会引入填充,因此您可以使用这些行来更新address:

address = (char *) address + sizeof(int); // OR...
address = (int *) address + 1;
Run Code Online (Sandbox Code Playgroud)

但是,这又完全取决于编译器按照您认为的方式布局结构,并且任何小的更改都可能会破坏它,所以您真的不应该依赖这种类型的行为.