2015-02-12 16 views
1
#include <stdio.h> 
char* func(); 
int main () 
{ 
    char *p; 
    p=func(); 
    printf("%c",*p); 
} 
char* func() 
{ 

    return "hello"; 
} 

這裏,printf打印「h」,表示創建了一個指向「hello」的指針,並將字符串「hello」存儲在內存中。 同樣,在printf(「%d」,5)中,是否將'5'存儲在內存中?在printf(「%d」,5);是5存儲在內存中?

+0

問題是...? – Rizier123 2015-02-12 05:55:34

+0

printf中的'5'是否被賦予了內存? – 2015-02-12 05:58:32

+0

'return「hello」'是無效的,因爲它不是給定的任何內存,你只需將它寫入...堆中的某個地方。如果您現在嘗試「打印」整個字符串,它可能會失敗並/或打印一些其他字符。 – 2015-02-12 05:59:59

回答

4

您的問題與平臺非常相關,但大多數理智的編譯器不應將代碼5存儲在您的代碼的任何數據部分,只讀或其他部分 - 應在printf調用之前簡單地將其壓入堆棧。

編輯:我其實只是檢查,GCC做更有趣的東西:

它完全避免了在64位機器上的棧和使用,因爲現有的衆多的直寄存器。它仍然不會將5存儲在任何地方,而是存儲在操作碼本身中。

+0

@JashanSingh在C中,字符串文字沒有類型「const char'。他們在C++中做。 – 2015-02-12 06:06:16

+0

我不明白你的意思,但文字*是*在只讀數據部分,而'5' *不是* – Blindy 2015-02-12 06:06:38

+0

請您解釋彙編輸出。我不知道彙編語言。 – 2015-02-12 06:10:12

2

你所印刷只是一個字符以打印出存儲在存儲器位置整個字符串,直到\0字符是

printf("%s",p); 

%s格式說明符可以確保字符打印

+0

我知道這一點。我只是想證明字符串文字存儲在內存中。但我如何檢查'5'是否被賦予內存 – 2015-02-12 05:57:09

0

如果您想確保檢查編譯器的adsembler語言輸出。

大多數情況下,函數調用中的整數字面值將通過單個操作放置在堆棧上。你可以從被調用函數(即printf)中訪問5的內存地址,但是當功能返回時,它將從堆棧中彈出。

0

在回答這個問題後,問題從C++改爲C了。我不會追逐一個不斷變化的問題,但我現在離開這個答案是因爲它可能對讀者有用。

在聲明

printf("%d", 5); 

格式字符串後的參數都爲C 傳遞參數可變參數,指定由正式參數列表三個時期...。這意味着就編譯器而言,沒有特別的類型是預期的,除非不允許非POD類類型實際參數。這也意味着在它們通過之前,值爲提升爲較小的一組類型,整數通常高達int,浮點高達double

5通常是機器代碼指令的一部分,該指令將機器運行時堆棧上的值推送出去。

由於它是在「存儲器」指令的一部分,但它不需要是可作爲該數值可以容易地訪問的一個分離的部分,並且它需要甚至不會其中C++對象駐留在普通數據存儲器(一些微控制器使用具有獨立代碼和數據存儲器的哈佛架構,可能,但我不知道,他們有C++編譯器)。


)智能編譯器能夠知道關於普通的標準庫函數,如printf,和解釋格式字符串等例如g ++做到了。在舊C時代,這是一個名爲lint的獨立程序的功能。

+0

再看一遍 - 這是一個C問題。 – 2015-02-12 06:15:25

+0

@MikeHousky:你的意思是,它*現在*是一個C問題。當這個答案發布時,這是一個C++問題。我不會去追求一個不斷變化的問題,但是謝謝! - 我即將發佈C++標準關於參數類型促銷的措辭,現在我不必這樣做。 – 2015-02-12 06:19:19

0

5和「hello」之間的區別在於「hello」是一個數組,因此它作爲參數傳遞並作爲結果以指針形式返回(作爲指向第一個元素的指針)。函數的int參數(如printf)按值傳遞,並且內存可能只在函數調用期間存在。

編譯後的代碼可能(通常會)只是將一個常量5推送到堆棧中以用於該參數。有內存,沒問題,但它在機器指令中是一個字段,而不是數據字。

如果你有一個調試器,你可能會感興趣的是在調用中反彙編代碼,看看我的意思。例如,在x86處理器上,操作碼名稱很容易就可以近似地找出發生的事情。

在那個printf調用中,您會看到格式字符串被作爲指向存儲在常量數據存儲器中的字符串的指針,但5可能是「立即」推送值5.(「立即「裝配中的數據意味着該值在指令本身中,而不是與數據存儲器分開提取。)

底線是該函數的執行過程中只保證存儲器5的存儲空間。