2016-12-16 25 views
0

我在學習C的樂趣。在我的第一部分代碼中(通過'學習C的艱難之路'),我故意在printf語句中遺漏了變量。新手Q--當我在printf中忽略一個變量時發生了什麼

#include <stdio.h> 

int main() { 
    int age = 3; 

    printf("I am %d years old.\n"); 

    return 0; 
} 

很簡單。它按我的預期編譯和投入收益。但是,當我傻傻的運行程序破碎無論如何,我得到一個不尋常的輸出:

I am 1476430496 years old. 

我每次運行它,數量不同,但相似的。我想,也許這是一個內存地址爲「年齡」,所以我嘗試:

printf("age is %p\n", &age); 

但是,這不是它:

I am 1570798240 years old. 
age is 0x7fff5da07a78 

所以我很好奇。這個數字是多少?它從何而來?我嘗試了不同的輸出類型(%s,%e,%u),事情變得更加詭異。

作爲後續問題,當我嘗試%p沒有變量時,我確實得到了的內存地址。

I am 0x7fff53e8caa0 years old. 

我也很好奇這個地址是從哪裏來的?有什麼方法可以查看可能存在的內容嗎?

感謝您的時間和任何幫助,您可以提供!

邁克

+3

這稱爲[_undefined behavior_](https://en.wikipedia.org/wiki/Undefined_behavior)。換句話說,這些值根據C標準沒有特定的含義;他們可能只是編譯的代碼碰到內存而已。 – qxz

+0

這是一個UB。在你的情況下'printf'解析格式字符串並從棧中獲取指定數量的參數。既然你沒有提供這些參數 - 你會得到一些內存垃圾。不同的編譯器/系統可能會產生不同的結果。 – Ari0nhh

+1

C強大。它會給你自由去做美妙的事情,比如在腳下自我射擊。注意警告。他們通常不是輕微的投訴。 – e0k

回答

3

Printf將嘗試讀取您在格式字符串中指定的許多變量。在這種情況下,它將讀取堆棧中接下來的4或8個字節,並將其解釋爲一個整數或指針,因爲您告訴它將會有一個整數或指針。

無論發生什麼事,你都會看到。完全有可能是先前在該內存空間中執行的進程留下的一些字節。

正如其他人指出的那樣,語言在技術上未定義行爲,您可以編寫編譯器以多種方式實現這種情況,包括崩潰。只是發生的最簡單的事情是信任格式字符串並繼續閱讀,並且通常有足夠的空間映射到堆棧,以便返回

0

未定義行爲

printf()不會更改傳遞給它的變量的內容,因此您只需傳遞變量的值即可。

您可以從手冊中閱讀關於格式說明符printf。 printf中的格式說明符不匹配導致Undefined behavior

相關問題