2017-09-04 75 views
0

我用sprintf(),以填補我的字符串,但是當我不這樣做,我發現了一些奇怪的事情,這名測試甚至可以是一個說法,我想調用函數時,它就像一個R值進行修改的VAR ,或者這裏是我沒注意到的地方,下面是我的代碼和輸出。sprintf()修改函數中的變量嗎?

謝謝。

#include <stdio.h> 
#include <stdlib.h> 

void Encap(char str[9]) 
{ 
    printf("%s\n", str); 
    sprintf(str, "hi e"); 
    printf("%s\n%p\n", str, &str); 
} 

int main() 
{ 
    char test[9] = "ABC"; 

    printf("%s\n", test); 
    Encap(test); 
    printf("%s\n%p\n", test, &test); 

    system("pause"); 
    return 0; 
} 

輸出

ABC 
ABC 
hi e 
0061FF10 
hi e 
0061FF27 
+2

在你pronting變量'str',地址在另一個案件 - 'test'。不同的變量 - 不同的地址。 –

+1

'&str'不是你可能期望的值......因爲'char str [9]'確實是'char * str'。 – Jarod42

+0

數組作爲指針傳遞給一個函數;正如你演示的那樣,指針指向的內容可以被修改。這是基本的C理論(和實踐)。這裏不應該有任何意外。 –

回答

2

您傳遞函數指針,它必將在存儲位置更改值。 當你逝去的指針,指針的另一個副本將被創建並將於功能。使用(當我們調用一個函數,變量的副本,是由和操作上覆制變量完成)。這裏的變量是指針類型的變量,因此會創建另一個指針變量,它將指向與測試指向的內存位置相同的位置,但會有不同的地址。 這就是爲什麼當您打印兩個不同指針的地址時,會打印兩個不同的內存地址。

+0

@ Feng.Ma在函數中,移除'&'因爲函數已經傳遞了感興趣的指針。所以'printf(「%s \ n%p \ n」,str,str);'你在做什麼,是打印函數參數的地址(可能是它在堆棧上的位置) - 而不是指針本身的值。實際上'printf(「%s \ n%p \ n」,str,(void *)str);'更正確。 –

+0

好吧,我明白了,關鍵是arg傳遞是ptr,謝謝你的回答。 –

3

聲明數組test,並且將它傳遞給函數Encap。你的問題有點不清楚,但有兩件事可能令你感到驚訝:

  1. 在功能Encap內,您正在修改數組的內容。
  2. 功能Encap返回後,回到調用者,所述修改到test陣列持續。

(你還問到「右值」,它可以是一個重要的概念,但它不會在您所期望的方式適用於此。)

之所以這個作品它的方式是因爲兩個不同的東西:

  1. 當您通過陣列test的功能Encap,你不通過數組的全部價值。實際得到的結果只是指向數組的第一個元素。
  2. 在函數Encap,你是不是修改傳遞指針,而是要修改的內存的指針指向。你正在使用指針作爲一個值(一個指針值)來知道你應該修改的內存的位置 - 這最終將成爲main()中的test數組。
+0

他需要一個C初學者書沒有任何解釋,因爲他不知道基本知識 –

+0

在閱讀了解釋之後,我發現了一些錯誤但重要的一點,感謝對初學者如此耐心。 –