澄清C指针和内存地址

时间:2012-09-11 16:39:06

标签: c pointers memory-management

我对以下代码中的第6,7和8行感兴趣。

#include <stdio.h>
#include <stdlib.h>

void go_south_east(int *lat, int *lon) {
  printf("Lat: %p, Long: %p\n", lat, lon);
  printf("Address of Lat: %p, Address of Long: %p\n", &lat, &lon);
  printf("Address of Lat: %p, Address of Long + 8 bytes?: %p\n", &lat, &lon+8);
  printf("Size of Lat: %lu, Size of Long: %lu\n", sizeof(lat), sizeof(lon));
  *lat -= 1;
  *lon += 1;
}

int main() {

  int latitude = 32;
  int longtitude = -64;
  go_south_east(&latitude, &longtitude);
  printf("Avast! Now at: [%i, %i]\n", latitude, longtitude);

  return 0;
}

我得到的输出是:

Address of Lat: 0x7fff5fbfe9e8, Address of Long: 0x7fff5fbfe9e0
Address of Lat: 0x7fff5fbfe9e8, Address of Long + 8 bytes?: 0x7fff5fbfea20 
Size of Lat: 8, Size of Long: 8

我知道lat和long指针的大小是8个字节,因为它们是long unsigned int。但为什么它们在内存中只相距1个字节?它们不应该相距8个字节,因为它们的大小是8个字节吗?请指教。


感谢所有有用的建议。我希望我能把每个人都标记为答案,但我不能。真的很感激。

4 个答案:

答案 0 :(得分:2)

你的问题中有完全不同的东西和无法解释的断言。

首先,我在代码中看不到long unsigned int指针。代码中的所有指针都有int *类型。 long unsigned int来自哪里?

其次,latlon是数据指针。通常,在非奇异的C实现中,所有数据指针具有相同的大小。它们指向的并不重要。在您的平台上,数据指针的大小为8字节。这意味着指向char的指针以及指向double的指针以及指向unsigned long int的指针将具有相同的8字节大小。

第三,你在哪里知道它们在内存中距离是1个字节?输出中的第一行清楚地显示它们位于0x7fff5fbfe9e80x7fff5fbfe9e0地址。这些地址正好在8字节之外:0x7fff5fbfe9e8减去0x7fff5fbfe9e0等于8.那么,你的“1字节之外”来自哪里?

第四,您的代码似乎建议&lon+8将地址更改为“8字节”。这是不正确的。将1添加到数据指针T*会将其移位sizeof(T)个字节,这意味着&lon+8实际上将地址更改为8 * 8 = 64个字节,这正是您在输出中观察到的内容:0x7fff5fbfea20减去0x7fff5fbfe9e0等于64。

基本上,您提出的问题与您在输出中观察到的内容完全相矛盾。这有点让人无法回答。这就像向人们展示一块红色的手帕,并问为什么它是绿色的。

答案 1 :(得分:0)

这两个地址之间的区别恰好是8,再看看。

答案 2 :(得分:0)

它们相距八个字节。 PC是字节可寻址的,而不是位可寻址的。

也就是说编号的存储单元是字节

答案 3 :(得分:0)

指针算法实际上会将数据类型的大小添加到地址中。澄清:

int* i = 0;
i++;
printf("%p\n", i); // Prints 0x4, not 0x1

所以

printf("Address of Lat: %p, Address of Long + 8 bytes?: %p\n", &lat, &lon+8);

实际打印lon + 8 * sizeof(&amp; lon)字节的地址