2014-10-02 131 views
0

我不知道爲什麼這段代碼不顯示錯誤。 讓我知道這是爲什麼。爲什麼沒有錯誤在C中顯示此代碼?

char str[10][5]; 

scanf("%s",&str[1]); 
printf("%s",str[1]); 

我認爲這必須顯示錯誤,但這隻顯示警告,通常執行。 請告訴我爲什麼這通常執行。

+3

然後將警告視爲錯誤。 – 2014-10-02 07:36:53

+2

編譯所有警告和調試信息('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

回答

5

正如前面討論過的,數組的地址與其第一個元素的地址具有相同的數值(數組在傳遞給函數時會衰減)。也就是說,str[1]這是一個char數組會衰減到一個指向char的指針,該指針包含與&str[1]相同的地址,該地址是該數組的地址。而且,不管你信不信,陣列都從第一個元素開始,這樣它們就可以共享相同的地址。

所以這兩個指針指向str中的一些內存位置,也就是有效地址;它們的輸入方式不同。 C的弱類型系統容忍類型差異。 scanf將從格式說明符%s中假定您傳遞了一個字符指針。由於內存很好(畢竟是s[1]),你可以掃描它。

是的,它是UB,但適用於凡人可用的每個平臺。

+0

謝謝!我明白! – maekchi 2014-10-02 07:52:49

+0

您的用戶圖片的好分形! – Joao 2014-10-07 06:03:37

2

表達

&str[1] 

的值等於表達式

str[1] 

的值即兩個尋址相同存儲器程度。

所以你因爲根據格式說明%s也就是在這個記憶程度scanf函數存儲文字補上他們終止零,直到它遇到的printf輸出從相同的內存程度人物scanfprintf過程中的價值得到正確的結果終止零。這兩個表達式都提供相同的地址。

+0

@maekchi Expression&str [1]給出數組str [1]佔用的內存地址。並且rvalue str [1]給出了與str [1] – 2014-10-02 07:50:14

+0

@maekchi佔用的範圍相同的地址的數組的第一個元素的地址澄清:值是相同的,類型不是,但它「起作用「因爲陣列布局的方式。但在形式上它是*未定義的行爲*。 – juanchopanza 2014-10-02 07:53:21

0

scanfprintf是得到variadic參數的函數。這意味着你可以傳遞任何數量的參數。任何錯誤使用這些功能後會導致不確定的行爲,因此這些功能被認爲是不安全的。

4

str[1]&str[1]的值是相同的。但他們的類型不是,類型分別是char*char(*)[5]

%s所需的類型是char*,如果您傳遞不兼容的類型,則會出現未定義的行爲。現在由於價值是相同的,程序將工作,但代碼本身不正確。

+0

謝謝!我明白! – maekchi 2014-10-02 07:54:02

相關問題