簡體   English   中英

指針類型轉換

[英]pointer typecasting

int main()
{
int *p,*q;
p=(int *)1000;
q=(int *)2000;
printf("%d:%d:%d",q,p,(q-p));
}

輸出

2000:1000:250

1.我無法理解p=(int *)1000; 行,這是否意味着p指向1000個地址位置? 如果我做*p=22 ,該值存儲在1000個地址並覆蓋現有值怎么辦? 如果它覆蓋該值,那么如果另一個程序正在使用1000地址空間怎么辦?

  1. qp=250如何?

編輯:我試過printf("%u:%u:%u",q,p,(qp)); 輸出是相同的

int main()
{
int *p;
int i=5;
p=&i;
printf("%u:%d",p,i);
return 0;
}

輸出

3214158860:5
  1. 這是否意味着編譯器使用的地址是整數? 普通整數和地址整數之間沒有區別嗎?

這是否意味着p指向1000個地址位置?

是。

如果我做* p = 22怎么辦

它正在調用未定義的行為-您的程序很可能會因段錯誤而崩潰。

請注意,在現代操作系統中,地址是虛擬的-您不能像這樣覆蓋其他進程的地址空間,但是可以嘗試在自己進程的地址空間中寫入無效的內存位置。

qp = 250如何?

因為指針算法的工作原理是這樣的(為了與數組索引兼容)。 兩個指針的區別是它們的值之差除以sizeof(*ptr) 類似地,將n添加到類型T的指針ptr會得到數值ptr + n * sizeof(T)

閱讀有關指針的內容。

這是否意味着編譯器使用的地址是整數?

甚至沒有必要“由編譯器使用”部分。 地址整數,它只是C語言的一種抽象,我們有很好的指針來簡化我們的生活。 如果您使用匯編語言進行編碼,則只需將它們視為無符號整數即可。

順便說一下

printf("%u:%d", p, i);

也是未定義的行為- %u格式說明符期望unsigned int ,而不是指針。 要打印指針,請使用%p

printf("%p:%d", (void *)p, i);

是的,使用*p=22您將寫入1000個地址。

qp是250,因為int的大小是4,所以它是2000-1000 / 4 = 250

p = (int *) 1000的含義是實現定義的。 但是,是的,在典型的實現中,它將使p指向地址1000

之后執行*p = 22確實會嘗試將22存儲在地址1000 但是,在一般情況下,這種嘗試將導致不確定的行為,因為不允許您僅將數據寫入任意內存位置。 您必須以一種或另一種方式分配內存才能使用它。 在您的示例中,您沒有做出任何努力來分配地址1000任何內容。 這意味着您的程序很可能會崩潰,因為它試圖將數據寫入未正確分配的內存區域。 (此外,在許多平台上,為了通過指針訪問數據,這些指針必須指向正確對齊的位置。)

即使您以某種方式成功完成了在地址1000處寫入22 ,也並不意味着它將以任何方式影響“其他程序”。 在某些舊平台上(例如DOS,例如)。 但是現代平台為每個正在運行的程序(進程)實現了獨立的虛擬內存。 這意味着每個正在運行的進程都有其自己的單獨地址1000並且看不到另一個程序的地址1000

  1. 是的, p指向虛擬地址1000 *p = 22; ,您很可能會遇到細分錯誤; 通常,整個前1024個字節對於讀取或寫入都是無效的。 假設您有虛擬內存,它不會影響其他程序; 每個程序都有其自己的虛擬地址空間。

  2. q - p的值是兩個地址之間的sizeof(*p)sizeof(*q)sizeof(int)的單位數。

將任意整數強制轉換為指針是未定義的行為。 任何事情都可能發生,包括什么都沒有,分段錯誤或無聲地覆蓋其他進程的內存(在現代虛擬內存模型中不太可能)。

但是我們曾經在DOS實模式下使用過這樣的絕對地址來訪問中斷表和BIOS變量:)

關於qp == 250 ,這是指針算術語義的結果。 在您的系統中, sizeof int顯然是4。 因此,當您將1加到int指針時,它實際上會增加4,因此它指向下一個int而不是下一個字節。 此行為有助於陣列訪問。

does this mean that p is pointing to 1000 address location?

是。 但是這個1000地址可能屬於其他一些進程地址。在這種情況下,您非法訪問了另一個進程的地址空間的內存。 這可能會導致分割錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM