繁体   English   中英

澄清C指针和内存地址

[英]Clarification on C pointers and memory addresses

我对以下代码中的第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个字节吗? 请指教。


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

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

首先,我没有在代码中看到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 。

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

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

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

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

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

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(&lon)字节的地址

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM