2

我有一个示例程序如下:

int testPointer(int * intArray, int * ptr) {
  printf("%i\n", intArray);
  printf("%i\n", ptr);
  printf("%lu\n", &intArray);
  printf("%lu\n", &ptr);
  return 0;
}

int main() {
  int result = testPointer((int *) 0x1, (int *) 0x2);
  return 0;
}

典型的输出是:

1
2
3212962484
3212962480

前两行总是相同的,我理解它们是如何产生的。第三行和第四行在每次运行时都会有所不同,但第四行的值总是比第三行的值小四。我如何破译这些值?它们代表什么?为什么最后一行总是比第三行少四?

4

6 回答 6

6

它为您提供这些变量的地址,即它们的内存位置。

您有这些变量,它们是函数参数,但它们就像 testPointer 函数中的任何其他局部变量一样:

 int testPointer(int * intArray, int * ptr)
                       ^^^^^^          ^^^

它们存在于内存中的某个位置,您可以使用 & 运算符获得该位置的地址。这类似于做

int i;
printf("%p\n", (void*)&i);

它显示了i变量的地址。

请注意,您应该使用 %p 打印指针,如printf("%p\n", (void*)&ptr);%i 或 %lu 需要一个 int 或 long 参数,这可能与给定平台上的指针不兼容。

它们代表什么以及为什么最后一行总是比第三行少四

这是因为编译器已将这 2 个变量彼此相邻放置在内存中,并且在您的平台上,指针显然有 4 个字节大。

而且我们也可能由此猜测,在您的平台上,如果您的系统上的堆栈在内存中向下增长(这是最常见的) ,则函数的参数从左到右(首先intArray,然后)放置在堆栈中ptr

于 2013-04-23T22:47:39.810 回答
1

最后一行总是(在 32 位系统上正好 4 行)小于第 3 行,因为这两个变量都在堆栈上,堆栈通常从内存顶部向下增长。

于 2013-04-23T22:47:54.933 回答
1

你不破译这些值。它们是操作系统和 C 内存分配例程用来保存变量的地址。这些是系统确定可供您使用的内存区域。

你还想破译什么?

于 2013-04-23T22:48:05.070 回答
0

调用此函数时,和int testPointer(int * intArray, int * ptr)的值存储在堆栈中。因此,将打印一个与堆栈指针相同的指针,该指针将随程序的每次运行而变化。intArrayptr&intArray

当传递 2 个参数时,每个参数一个一个地被压入堆栈。由于 2 个参数彼此相邻,并且指针大小为 4 个字节,因此您观察到 4 的差异。

于 2013-04-23T22:49:41.227 回答
0

从技术上讲,该行为是未定义的,因为%lu指令应对应于long unsigned int类型化参数。这可能对您有用,但只是巧合。你不想养成依赖巧合的习惯。在某些实现中long unsigned int,指针的表示和宽度不同,并且此代码可能会导致崩溃。

如果您想以可移植的方式打印这些地址,则需要使用%p对应于void *类型化参数的指令。不要忘记将参数转换为void *,因为int *在表示上可能会有所不同void *。请参阅c-faq.com 的问题 5.17

我如何破译这些值?

它们是地址。把它们想象成邮政地址。当收回资产的人想要取回金融资产时,他们会去该人的地址并拿走电视。当快递员要投递包裹时,他通过地址找到该人。这在概念上类似于普通处理器在计算机上检索和存储值的方式(以非常基本的方式)。

它们代表什么...

它们可能代表它们指向的对象的偏移量。例如,当&intArray对应于时3212962484,这可能intArray是位于 RAM 中第 3212962484 个字节的指示。然而,依靠这一点是巧合。您打印指针的方式不可移植,并且指针在概念上与整数不同。它们也可能是您的信用卡号。

...为什么最后一行总是比第三行少四?

巧合,或者是设计您的编译器、操作系统或 CPU 的人做出的选择。四也可能是完全回答双管问题的答案的百分比

于 2013-04-23T23:30:36.863 回答
-1

这两行是内存中指针的地址。(你应该%p用来显示它们)。

由于它们是连续两次int*传递给函数的,因此它们sizeof(int*)相隔 = 4 个字节(在 32 位系统上)。

于 2013-04-23T22:49:29.737 回答