我通过使用一个非常简单的程序熟悉c-strings和指针。
此版本通过引用传入字符串,起作用:
#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中的所有内容都是按值传递的,但数组名称实际上是地址。这是不是意味着我将字符串的实际地址传入测试?不应该有相同的事情吗?我很困惑,请帮帮我。
答案 0 :(得分:3)
记住这一点:在C编程中使用一个值,你传递&#34;按值&#34;。要更改值,您必须通过&#34;地址&#34;。因此,如果您要更改的是地址,则需要传递其地址以进行更改。否则您只能使用它。
答案 1 :(得分:2)
当您通过“按值”传递参数时,参数的值将复制到函数中的形式参数中。更改副本(在string
函数中的test
个案例中)当然不会更改原始文件(string
函数中的main
)。
在旁注中,C实际上没有“按引用传递”,它只传递值。您使用指针模拟通过引用传递。
答案 2 :(得分:0)
在您的第二个版本中,string
本身正在按值传递,因此您无法自行更改string
。这是出于类似的原因,当您按值传递时,您无法更改int
或float
的值。当一个参数按值传递时,会在被调用函数的堆栈中创建一个本地副本。
但是,您始终可以更改string
的内容。
答案 3 :(得分:0)
在C中,数组类型表示为指向其第一个元素的指针。类型中的*
表示&#34;指向&#34;的指针,但在类型之外表示&#34;取消引用指针&#34;。当您将参数传递给函数时,在函数体中,您已经传递了事物的 copy 。让我们分析你的代码:
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;
}