為什么以及如何235在 C 中列印給定的代碼?
#include <stdio.h>
int main()
{
int i;
char ch[] = { 'z', 'o', 'h', 'o' };
char *ptr, *str1;
ptr = ch;
str1 = ch;
i = (*ptr-- *str1) - 10;
printf("%d", i);
return 0;
}
uj5u.com熱心網友回復:
In i=(*ptr-- *str1)-10;,*ptr--被決議為*(ptr--)因為 postfix--比 unary 系結得更緊密*。
由于先前ptr=ch;設定ptr為指向 的第一個元素ch,因此ptr--嘗試遞減ptr以指向 的開始之前ch。C 標準沒有定義這種行為。
由于ptr--通常計算為ptr減量之前的值,因此*ptr--可能會產生ptr指向的值,就好像它*ptr不是*ptr--. 因此,它將產生 的值z。但是,由于不正確的指標增量,C 標準不能保證這一點。一旦存在標準未定義的行為,則不會定義同一代碼路徑上的其他行為。
如果我們洗掉錯誤--并使用(*ptr *str1)-10,那么它本身*ptr會產生 的值'z',當使用 ASCII 字符集時為 122。str1也指向 的第一個元素ch,因此 *str1遞增該元素以將其從 122 更改為 123。
此時,又出現了 C 標準未定義的行為。*ptr使用ch[0], 并對其進行 *str1修改,兩者之間沒有先后順序。根據 C 2018 6.5 2 中的規則,程式的行為不是由 C 標準定義的。
如果我們假設以某種方式添加了排序,因此增量晚于*ptr,則 *str1產生增量值 123。
然后 將 122 和 123 相加得到 245,減去 10 得到 235。
uj5u.com熱心網友回復:
在運算式*ptr––中,后綴––的優先級高于一元*,所以運算式被決議為*(ptr––); 您正在取消參考 的結果,ptr––這會產生'z'(ASCII 122)。作為一個副作用,ptr被遞減并且現在指向陣列邊界之外。
在運算式 *str中,一元 和一元*具有相同的優先級,因此運算式被決議為 (*str),與 相同'z' 1,或者 ASCII 123. 122 123 - 10給你235。作為尺寸效果,ch[0]現在包含 ASCII 123 或'{'.
這整個爛攤子相當于寫作
tmp1 = ptr;
tmp2 = *str;
i = *tmp1 (tmp2 1) - 10;
ptr = ptr - 1;
*str = *str 1;
除了對 、 和 的更新i可以ptr按*str任何順序進行,甚至可以同時進行。
uj5u.com熱心網友回復:
為了評估(*ptr-- *str1),編譯器應用 C 語法的規則:后綴運算子比前綴運算子系結更強,它們從左到右應用,然后前綴運算子從右到左應用于結果。
*ptr--因此適用*于 的結果ptr--,即 的原始值ptr,副作用ptr發生在下一個序列點之前的某個時間,即下一條陳述句。既然ptr已經賦值給陣列的開頭ch,*ptr--就有了值'z'。
但是請注意,ptr在陣列開頭之前遞減具有未定義的行為......雖然此特定實體在大多數當前系統上不會導致任何問題,但僅存在未定義行為可能會讓編譯器執行激進的優化并產生違反直覺的結果。
*str被決議為 (*str):值是,因此(*)*str 1之后字符集中的下一個字符,并且值作為副作用在下一個序列點之前的某個時間遞增。z*str
這是未定義行為的另一個實體,因為*ptr和*str參考陣列的相同元素ch:副作用*str明顯與*ptr讀取相同元素相沖突。C 標準將此描述為未定義的行為,因為在運算式中修改的物件只能被讀取以計算修改后的值,這里不是這種情況。
觀察到的行為,即 的輸出235,與評估為的完整運算式('z' ('z' 1)) - 10以及未觀察到的副作用以及使用 ASCII 編碼'z'的值一致122:122 122 1 - 10 = 235。
請注意,這只是對觀察到的行為的一種潛在解釋,但 C 標準根本不保證這種行為:行為是未定義的,程式可能以不同的方式運行:它可以輸出236, 329, 330,它可以有或沒有停止錯誤或產生其他不可預知的結果。
(*) 請注意,在默認情況下具有帶符號值的 (*str)假設系統上也將具有實作定義的行為。這會嘗試轉換超出有符號型別范圍的值,這種情況由6.3.1.3 [...] 結果是實作定義的,或者引發了實作定義的信號。. 許多系統的值為并設定為... close but no cigar:)'z'CHAR_MAXchar *strchar'z'122CHAR_MAX127
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/468479.html
標籤:C
上一篇:沒有收到任何錯誤并輸出C
