簡體   English   中英

(int *)&var是什么意思?

[英]What does (int*) &var mean?

(int*) &i的含義是什么?

  char i;
  int* p = (int*) &i;
  ...
  *p = 1234567892;
  ...

如果是* &i ,我會理解。 但在這種情況下,這里有一個“ int ”。

&i:表示取i的地址(這是一個char *)

(int*)&i :將指針強制轉換為指向整數的指針(這樣做是壞/錯,但你告訴編譯器這樣做,所以它甚至不會發出警告)

int* p = (int*)&i; :一個聲明,表示將i的指針存儲在p中(並將其轉換為:編譯器甚至不會抱怨)

*p = 1234567892; :寫這個值,它是p指向的址的幾個字節(雖然p認為它指向一個int,但是為char!)。 其中一個字節將以i結尾,但其他字節將覆蓋相鄰i的字節。

構造(int *) &var ,其中var是一個char ,它接受一個指向var的指針,然后將它轉換為一個不同類型的指針(即int )。 程序稍后將int值寫入指針。 由於指針實際上指向一個char ,一個int值不適合,這會觸發未定義的行為 ,這是一個奇特的名稱,“字面上任何東西(你的計算機可以實際完成)可能發生 - 這個程序是錯誤的”。

編輯:根據要求,一些標准學來解釋為什么這個程序有未定義的行為。 以下所有部分參考均為N1570 ,這是與C2011官方文本最接近的,可以在線免費訪問。

作為序言,在閱讀C標准的文本時,您需要知道“應該”一詞具有特殊意義。 任何包含單詞“shall”的句子都對程序或編譯器和運行時環境提出了硬性要求; 你必須從上下文中找出哪一個。 該計划有兩種硬性要求。 如果“約束”部分中出現“應該”的句子,那么編譯器就需要診斷違規(第5.1.1.3節)(標准永遠不會說明程序必須被拒絕 ,但這是通常在錯誤和警告)。 如果“shall”句子出現在其他地方,則編譯器不需要診斷它,但是違反要求的程序具有未定義的行為(§4p1,2)。 有時文本會說“如果是X,那么行為是未定義的”; 后果沒有區別。

首先,轉換(int *) &varchar *轉換為int *當且僅當 point-to- char的值與int類型的對象正確對齊時 ,才由§6.3.2.3p7明確允許。

指向對象類型的指針可以轉換為指向不同對象類型的指針。 如果生成的指針未針對引用的類型正確對齊,則行為未定義。 否則,當再次轉換回來時,結果將等於原始指針。

顯示的代碼中沒有任何內容可以確保 var對於int進行了適當的對齊,因此程序可能已經觸發了此時未定義的行為,但我們假設它正確對齊。 int *類型的值保存到使用該類型聲明的變量中是沒有問題的。 下一個操作是*p = integer_literal 這是對對象var 的存儲值寫訪問 ,它必須遵守§6.5p6,7中的規則:

  1. 用於訪問其存儲值的對象的有效類型是對象的聲明類型(如果有)。 [...更多關於如果對象沒有聲明類型會發生什么的文本; 這里不相關......]

  2. 對象的存儲值只能由具有以下類型之一的左值表達式訪問:

    • 與對象的有效類型兼容的類型,
    • 與對象的有效類型兼容的類型的限定版本,
    • 與對象的有效類型對應的有符號或無符號類型的類型,
    • 與有效類型的對象的限定版本對應的有符號或無符號類型的類型,
    • 聚合或聯合類型,包括其成員中的上述類型之一(包括遞歸地,子聚合或包含聯合的成員),或者
    • 一個字符類型

對於像intchar這樣的簡單算術類型, 兼容 類型在剝離typedef之后意味着相同的類型。 (確切的定義分布在§§6.2.7,6.7.2,6.7.3和6.7.6。)對於這種分析而言,重要的是聲明的var類型是char ,但是左值表達式*p type int ; intchar不兼容, int不是字符類型。 因此,該程序違反了單詞“shall”所聲明的要求,該要求不在名為“constraints”的部分中,並且其行為未定義。

注意最后一個項目符號點的不對稱性。 任何對象都可以通過具有字符類型的左值表達式訪問其存儲值,但聲明具有字符類型的對象可能無法由具有不兼容類型的左值表達式訪問。 是的,這意味着訪問一個大的陣列的字符(如數據從文件中讀取的緩沖)“四在時間”的通過一個指向共同的成語int是,嚴格地說,無效。 許多編譯器對這種情況的指針別名規則做了一個特殊的例外,以避免使該習慣用法無效。

但是,通過指向int的指針訪問單個char也是無效的,因為(在大多數系統上) int大於char ,因此您讀取或寫入超出對象末尾的字節。 該標准並不打算將該案例與陣列案例區分開來,但無論如何它都會對你不利。

int *是一個類型 - 特別是它是指向int的指針。

(type)x是一個類型轉換。 它說要重新解釋或轉換x到那種類型。 對於指針類型,它總是意味着重新解釋。

ichar類型。 所以&ichar *類型。 將它轉換為int *使其類型為int *以便可以為其分配p

當你隨后通過p寫時,你將寫一個完整的int

&i給出變量i的地址。 (int *)將指針( char *類型(int *)轉換為指向int的指針。

然后語句*p = 1234567892具有未定義的行為,因為p實際上指向單個char的地址,但是此表達式將該位置視為包含int (不同類型)。 在實踐中,通常的結果是寫入超過單個char內存位置,這可能導致數據中毒(例如,更改其他變量的值)到立即程序崩潰。

沒有(int*) ,gcc會抱怨,因為指向胡蘿卜的指針不是指向土豆的指針。

warning: initialization from incompatible pointer type [enabled by default]

因此,這種表示法只是意味着我知道我在這里做什么,認為它是指向不同類型的指針,即int。

這意味着您的程序即將崩潰並出現BUS錯誤

當然它是類型轉換。 我是一個字符變量,p是指向整數的指針。 所以p =(int *)&i表示p存儲的是i類型的地址,但是你有類型轉換它,所以沒關系。 現在p指向我。

* p = 123455; //這里你用123455將值存儲在&i。

當你打印這些價值時

print(* p)// 123455

print(i)//一些垃圾 - 因為我是char(1字節)並且具有整數值(4字節)。 所以我將它作為十進制值並相應地打印該值。

但是,讓我們說* p = 65;

print(* p)// 65

print(i)// A - 因為char i = 65而​​char 65是'A'

希望它能幫到你。

暫無
暫無

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

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