4

当我在 Xcode 的 64 位 Intel 中编译下面的代码时,我得到了这个输出。

#include<stdio.h>
#include<limits.h>

int main(void)
{
  /* declare some integer variables */
  long a = LONG_MAX;
  long b = 2L;
  long c = 3L;

  /* declare some floating-point variables */
  double d = 4.0;
  double e = 5.0;
  double f = 6.0;

  printf("A variable of type long occupies %d bytes.", sizeof(long));
  printf("\nHere are the addresses of some variables of type long:");
  printf("\nThe address of a is: %p  The address of b is: %p", &a, &b);
  printf("\nThe address of c is: %p", &c);
  printf("\nThe address of a-b is: %ld\nvalue of a is %ld\nValue of b is %ld\nsize of pointer %ld ", (&a-&c),a,b,sizeof(&a));
  printf("\n\nA variable of type double occupies %d bytes.", sizeof(double));
  printf("\nHere are the addresses of some variables of type double:");
  printf("\nThe address of d is: %p  The address of e is: %p", &d, &e);
  printf("\nThe address of f is: %p\n", &f);

    printf("\n size long - %d", sizeof(a));
  return 0;
}
long 类型的变量占用 8 个字节。

以下是一些 long 类型变量的地址:

a的地址是:0x7fff5fbff880
b的地址为:0x7fff5fbff878
c的地址是:0x7fff5fbff870
ab的地址是:2

a 的值为 9223372036854775807
b 的值为 2
指针大小 8

double 类型的变量占用 8 个字节。

以下是一些 double 类型变量的地址:

d的地址是:0x7fff5fbff868
e的地址是:0x7fff5fbff860
f的地址是:0x7fff5fbff858
尺寸长 - 8

对我来说奇怪的是,地址之间的差异a只有b2。我希望它是 8,这将匹配很长的字节数。有谁知道为什么会这样?


我在减去 &a-&c 的代码中确实有错字,但这确实与我的问题无关。我的问题是为什么从变量 a 的地址到变量 b 的地址只有 2 个字节的差异,而 long 是 8 个字节长并且我希望看到 8 个差异?

4

5 回答 5

7

指针算术基于它指向的类型的大小,而不是字节,这个关于指针算术的参考很好地涵盖了这个主题,你也有一个错字:

(&a-&c)

你实际上是ca.

这也是未定义的行为,因为仅当指针指向同一数组时才定义指针减法,请参阅以下部分6.5.6/9C11 draft standard

[...] 当两个指针相减时,两者都应指向同一个数组对象的元素,或者指向数组对象最后一个元素的元素;[...]

部分6.5.6/8也相关:

[...] 如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。[...]

于 2013-08-04T03:17:49.013 回答
4

差异以 为单位sizeof(long)。要强制它以字节为单位,您应该先转换两个指针:

((char *)&a-(char *)&b)

这样,区别就在于单位sizeof(char)是字节数

于 2013-08-04T03:14:20.967 回答
4

首先,在印刷品中:

printf("\nThe address of a-b is: %ld\nvalue of a is %ld\nValue of b is %ld\nsize of pointer %ld ", (&a-&c),a,b,sizeof(&a));

你通过的是(&a-&c),不是(&a-&b)。传递&a-&b,那么你实际上会得到输出:

 The address of a-b is: 1

为什么?可能编译器碰巧把a, b,c放在串行内存中,它看起来好像是一个数组,在指针算术中,减法将返回元素的数量,而不是字节。

请注意,这是未定义的行为,因为指针算术仅在它们确实在同一个数组中时才有效,而在您的示例中它们不在。

于 2013-08-04T03:18:01.460 回答
0

编译器可能不会将变量彼此相邻放置,可能是因为它旁边的块没有 8 个空闲字节。另一个原因可能是字节数是 64 的倍数,速度显着提高。

于 2013-08-04T12:02:54.217 回答
0

I had a mental lapse and forgot that the addresses are in hex and 0x7fff5fbff880 - 0x7fff5fbff878 = 8 (bytes)

于 2013-08-04T11:55:33.120 回答