2015-09-28 47 views
0

我通過使用一個非常簡單的程序熟悉了C字符串和指針。爲什麼我必須通過引用傳遞字符串才能更改其指向的位置?

這個版本,它通過引用傳遞一個字符串,作品:

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

void test(char **string) { 

    *string = (char *)malloc(5); 
    char *temp = "hell"; 
    strcpy(*string, temp); 
} 

int main(int argc, char *argv[]) { 

    char *string = NULL; 
    test(&string); 
    printf("%s\n", string); 
    return 0; 
} 

它打印出 「地獄」。

這個版本,它只是按值傳遞的字符串,不工作,並因此導致segfault:

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

void test(char *string) { 

    string = (char *)malloc(5); 
    char *temp = "hell"; 
    strcpy(string, temp); 
} 

int main(int argc, char *argv[]) { 

    char *string = NULL; 
    test(string); 
    printf("%s\n", string); 
    return 0; 
} 

據我所知,第一個版本是有道理的,因爲我傳遞的地址字符串的地址。因此,當我解引用這個雙指針時,我得到了字符串的真實地址,並可以用malloc重新分配它。

然而,第二個版本我不清楚它爲什麼不起作用。在這個版本中,我將字符串的地址傳遞給測試函數。我讀過C中的所有東西都是按值傳遞的,但是這些數組名稱實際上是地址。這是否意味着我將字符串的實際地址傳入測試?難道事情不一樣嗎?我很困惑,請幫助我。

+1

出於同樣的原因,如果你想改變它的值,你需要通過引用傳遞'int'。 – juanchopanza

+0

C使用[傳遞值](http://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) –

回答

3

記住這個:在C編程中使用一個值,你通過「按值」。要更改值,您必須通過「按地址」。所以,如果你想改變的是一個地址,那麼你需要傳遞它的地址來改變它,否則你只能使用它。

+0

大聲笑出所有答案這是最簡單的,對我來說最有意義 – nemo

0

在您的第二個版本中,string本身正在按值傳遞,因此您根本無法更改string本身。這是由於類似的原因,當它按值傳遞時,您無法更改intfloat的值。雖然參數是按值傳遞的,但在被調用函數的堆棧中創建了本地副本。

但是,您可以隨時更改string的內容。

2

當您通過「值」傳遞參數時,參數的值是複製到函數的形式參數中。更改副本(在test函數內的string)當然不會改變原來的(main函數中的string)。

在附註上,C實際上並沒有「通過引用傳遞」,它只能傳遞值。您模擬通過使用指針傳遞引用。

0

在C中,數組類型被表示爲指向其第一個元素的指針。類型中的*表示「指向」,但類型之外的意思是「取消引用指針」。當你將參數傳遞給函數時,在函數體中,你有拷貝你通過的東西。讓我們分析的頭腦與您的代碼:

void test(char **string) {  //expect pointer to string 
    *string = (char *)malloc(5); //dereference pointer to string and allocate memory (*string is of type char*, it is a string)      
    char *temp = "hell";   //create new string 
    strcpy(*string, temp);  //copy new string to the old one 
} 
int main(int argc, char *argv[]) { 
    char *string = NULL;  //create empty pointer (string is array, which is pointer to char), but NULL is not a valid string 
    test(&string);   //pass pointer to string 
    printf("%s\n", string); //print string 
    return 0; 
} 

**sting並沒有改變,但其內容*string一樣。 而在第二個:

void test(char *string) { //with this type, you could modify, what is actual string content (for example first letter), but you pass here NULL, so there is nothing you can do 
    string = (char *)malloc(5); //here, you are changing only COPY of the pointer, that you passed in main 
    char *temp = "hell";  //create another string 
    strcpy(string, temp);  //copy new string to the one created, after this operation pointer to the string is lost 
} 

int main(int argc, char *argv[]) { 
    char *string = NULL; //the same 
    test(string);   //pass the string, you are screwed here, values in C are passed by copying, so even if you modify the string correctly, you will not see the result 
    printf("%s\n", string); //the string variable never changed from NULL, so you get the error 
    return 0; 
} 
相關問題