簡體   English   中英

為什么必須通過引用傳遞字符串才能更改其指向的位置?

[英]Why must I pass a string by reference in order to change where it points?

我通過使用一個非常簡單的程序來熟悉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語言中的所有內容都是按值傳遞的,但是數組名稱實際上是地址。 這是否意味着我要將字符串的實際地址傳遞給test? 事情不應該一樣嗎? 我很困惑,請幫幫我。

切記:在C編程中使用值時,您傳遞“按值”。 要更改值,您必須傳遞“按地址”。 因此,如果要更改的是地址,則需要傳遞其地址以進行更改。否則,只能使用它。

當您通過“按值”傳遞參數時,參數的值將被復制到函數中的形式參數中。 當然,更改副本(在您的情況下為test函數中的string )不會更改原始副本( main函數中的string )。

附帶說明一下,C實際上沒有“按引用傳遞”,它只有按值傳遞。 您可以通過使用指針來模擬按引用傳遞。

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

但是,您始終可以更改string的內容。

在C語言中,數組類型表示為指向其第一個元素的指針。 * in type表示“指向”的指針,而type之外則表示“取消引用指針”。 當您將參數傳遞給函數時,在函數主體中,您獲得傳遞的事物的副本 讓我們牢記這一點來分析代碼:

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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM