我尝试使用change()
函数更改y
的内容。
我想问一下,在将y
分配给*
时删除x
时,为什么"abc"
无法更改?
另外,我发现&*x
与&y
相同,这是否意味着指针x
的地址被指定为与{{{}的内容的地址相同1}}指出?另外,为什么*y
不等于&x
?
我的代码:
"abc"
答案 0 :(得分:5)
您的代码中存在许多问题,需要指出其中一些问题
y
指向字符串文字。任何修改字符串文字的尝试都是undefined behaviour。%p
格式说明符,并为参数添加(void*)
,使用不正确的参数类型为undefined behaviour。同样,要打印char
,您需要%c
,以打印您需要的字符串%s
。阅读更多here change()
内部,*x
的类型为char
,您正在尝试为其指定一个指针(字符串文字"abc"
的基地址)。 够!!请你的编译器告诉你'其余的。(换句话说,请启用编译器警告并尝试修复报告的问题。)
答案 1 :(得分:2)
为什么& x不等于" abc"?
因为&x
给出x
的地址而不是它指向的值。要获得价值,您需要*x
。
y
无法更改,因为它指向的字符串文字是常量。任何尝试改变它都会导致UB。
这是否意味着指针x的地址被指定为与* y指向的内容的地址相同?
当您将x
的地址作为参数传递时,指针y
具有指针y
的地址。
答案 2 :(得分:2)
您必须阅读有关指针和参数传递的更多信息。 指针是一个变量,用于保存另一个变量的内存中的地址。 当您在代码中引用变量时,编译器会使用此类变量的值,因此当您引用指针时,您将获取其内容是地址。
运算符&
会返回变量的地址,所以在代码段中:
int a = 10;
int *p = &a;
指针p
将保存变量a
的内存地址。如果我们在*
上使用运算符p
,我们将通过a
获取内存地址的内容:
printf("%d", *p);
将打印10
。
如果我们写&*p
,虽然它不完全正确并且许多编译器甚至会发出警告,但我们得到指针指向的值,而不是要求该内容的地址< / strong>,即再次返回作为指针内容的数据地址。
现在函数,当你在函数中传递一个参数时,一个变量的副本被推送到堆栈中,从那里将被访问函数。 这些值是本地值,当您离开函数时,对它们所做的任何更改都将丢失。当然,如果你传递一个指针,你的变量的地址,然后使用指针改变值,你可以反映真实变量的变化。
但是你在代码中犯了一个大错误,而你在函数proto中声明了一个指向char的指针:
void change(char *x)
您传递的change(&y);
是char **
(y
是char *
,&y
是char **
)。你应该收到很多警告。
无论如何,这个概念在调用者方面是正确的,你传递存储字符串地址的地址,改变它y
将指向新字符串。这是完全合法的,因为您正在用另一个常量字符串更新指针(不更改非法的常量字符串)。
但是你需要指向字符串的指针的地址,你的函数必须是:
void change(char **x)
{
*x = "abc";
printf("S3: %p\n", (void *)&x);
printf("S4: %p\n", (void *)&*x);
}
int main(int argc, char *argv[])
{
char *y = "def";
printf("S1: %p\n", (void *)&y);
printf("S2: %p\n", &*y);
change(&y);
printf("result: %s\n", y);
return 0;
}
最后在printf
中使用正确的格式,指针为%p
。
答案 3 :(得分:1)
它应该是change(y)
而不是change(&y)
,change(&y)
是*y
的地址,而不是y中的地址。所以y给出一个字符串中第一个字符的地址,其中&amp; y给地址y而不是第一个字符串的地址。
HTH