簡體   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