指向结构的指针的偏差

时间:2014-02-02 10:33:26

标签: c pointers struct

我正在试图找出,指向结构的指针的顺序是什么意思:

struct example{
int x;
}

struct example a = {20};
struct example *b = &a;

现在我的问题:

&a是结构的地址

&b是指向struct

的指针的地址

b将是引用结构指针b的结构的地址

现在:

(*b).x = 21;

(* b):如果这是指向结构地址的指针,这是(*b)b之间的差异?

我试图打印出两个地址是否相同:

printf("%p, %p", *b, b);

答案不是!有人可以解释我错在哪里吗?

2 个答案:

答案 0 :(得分:2)

printf("%p, %p", *b, b);中,参数*b是一个结构。使用%p说明符打印结构的行为不是由C标准定义的。无论你看到什么价值印刷都是有效的垃圾;它毫无意义。

当您以这种方式使用printf时,C实施可能会采取的方式包括,但不限于:

  • 结构*b作为参数传递(通过将表示它的字节放在寄存器或为调用的第三个参数指定的内存中),然后printf重新解释这些字节(包含int)好像它们是一个指针并打印该指针的值。 printf然后继续打印b参数。
  • 结构*b如上所述传递,printf打印它,但是,因为参数(结构)的大小不同于printf所期望的(指针),下一个参数的位置计算不正确,因此printf使用了错误的字节,并且无法正确打印b参数。
  • 传递不正确的参数会导致堆栈损坏,并且程序崩溃。

另请注意,使用%p说明符时,任何传递的指针都应转换为void *(或const void *)。传递%p的任何其他类型的指针也是未定义的行为。

答案 1 :(得分:0)

printf的参数中,b是指针,*bstruct example,而不是指针。 printf正确显示b,因为它是一个内存地址,但它是 cast *b(即:你的结构)转换为指针,这就是为什么这两个数字是不同的。

编辑:为了回应Eric Postpischil的评论,我已将'cast'更新为'转换'。除了术语之外,答案的其余部分是正确的,这是证据:

#include <stdio.h>

int main()
{
   struct test {
      int x;
   };

   struct test t;
   t.x = 0xdeadbeef;

   printf( "%p\n", &t );
   printf( "%p\n", t );

   return 0;
}

这个输出是:

0x7fff5b674b98
0xdeadbeef

请注意,编译器应该警告您:

test.c:13:20: warning: format specifies type 'void *' but the argument has type
  'struct test' [-Wformat]

......但除了这一点之外;这就是你问题的答案;)