我不知道爲什麼這段代碼不顯示錯誤。 讓我知道這是爲什麼。爲什麼沒有錯誤在C中顯示此代碼?
char str[10][5];
scanf("%s",&str[1]);
printf("%s",str[1]);
我認爲這必須顯示錯誤,但這隻顯示警告,通常執行。 請告訴我爲什麼這通常執行。
我不知道爲什麼這段代碼不顯示錯誤。 讓我知道這是爲什麼。爲什麼沒有錯誤在C中顯示此代碼?
char str[10][5];
scanf("%s",&str[1]);
printf("%s",str[1]);
我認爲這必須顯示錯誤,但這隻顯示警告,通常執行。 請告訴我爲什麼這通常執行。
正如前面討論過的,數組的地址與其第一個元素的地址具有相同的數值(數組在傳遞給函數時會衰減)。也就是說,str[1]
這是一個char數組會衰減到一個指向char的指針,該指針包含與&str[1]
相同的地址,該地址是該數組的地址。而且,不管你信不信,陣列都從第一個元素開始,這樣它們就可以共享相同的地址。
所以這兩個指針指向str中的一些內存位置,也就是有效地址;它們的輸入方式不同。 C的弱類型系統容忍類型差異。 scanf將從格式說明符%s中假定您傳遞了一個字符指針。由於內存很好(畢竟是s[1]
),你可以掃描它。
是的,它是UB,但適用於凡人可用的每個平臺。
表達
&str[1]
的值等於表達式
str[1]
的值即兩個尋址相同存儲器程度。
所以你因爲根據格式說明%s
也就是在這個記憶程度scanf函數存儲文字補上他們終止零,直到它遇到的printf輸出從相同的內存程度人物scanf
和printf
過程中的價值得到正確的結果終止零。這兩個表達式都提供相同的地址。
@maekchi Expression&str [1]給出數組str [1]佔用的內存地址。並且rvalue str [1]給出了與str [1] – 2014-10-02 07:50:14
@maekchi佔用的範圍相同的地址的數組的第一個元素的地址澄清:值是相同的,類型不是,但它「起作用「因爲陣列布局的方式。但在形式上它是*未定義的行爲*。 – juanchopanza 2014-10-02 07:53:21
scanf
和printf
是得到variadic參數的函數。這意味着你可以傳遞任何數量的參數。任何錯誤使用這些功能後會導致不確定的行爲,因此這些功能被認爲是不安全的。
str[1]
和&str[1]
的值是相同的。但他們的類型不是,類型分別是char*
和char(*)[5]
。
%s
所需的類型是char*
,如果您傳遞不兼容的類型,則會出現未定義的行爲。現在由於價值是相同的,程序將工作,但代碼本身不正確。
謝謝!我明白! – maekchi 2014-10-02 07:54:02
然後將警告視爲錯誤。 – 2014-10-02 07:36:53
編譯所有警告和調試信息('gcc -Wall -g')。你在[] scanf(3)'](http://man7.org/linux/man-pages/man3)上有[未定義行爲](http://en.wikipedia.org/wiki/Undefined_behavior) /scanf.3.html)。仔細閱讀它的文檔。 [C99](http://en.wikipedia.org/wiki/C99)標準在這種情況下不需要*任何診斷,所以很高興得到警告。 – 2014-10-02 07:37:11