C 双指针与单指针
有人能解释/给我一个理由,为什么在下面的代码片段中,main函数中变量i的值不通过函数test1改变,而通过test2改变?我认为一个指针就足以改变I的值。为什么我们要用双指针C 双指针与单指针,c,pointers,C,Pointers,有人能解释/给我一个理由,为什么在下面的代码片段中,main函数中变量i的值不通过函数test1改变,而通过test2改变?我认为一个指针就足以改变I的值。为什么我们要用双指针 #include <stdio.h> void test1(int* pp) { int myVar = 9999; pp = &myVar; } void test2(int** pp) { int myVar = 9999; *pp = &myVar; } i
#include <stdio.h>
void test1(int* pp)
{
int myVar = 9999;
pp = &myVar;
}
void test2(int** pp)
{
int myVar = 9999;
*pp = &myVar;
}
int main()
{
printf("Hej\n");
int i=1234;
int* p1;
p1 = &i;
test1(p1);
printf("does not change..., p1=%d\n",*p1);
test2(&p1);
printf("changes..., p1=%d\n",*p1);
return 0;
}
#包括
无效测试1(int*pp)
{
int-myVar=9999;
pp=&myVar;
}
无效测试2(整数**pp)
{
int-myVar=9999;
*pp=&myVar;
}
int main()
{
printf(“Hej\n”);
int i=1234;
int*p1;
p1=&i;
试验1(p1);
printf(“不改变…,p1=%d\n”,*p1);
测试2(&p1);
printf(“更改…,p1=%d\n”,*p1);
返回0;
}
在C中,参数是按值传递的。这意味着,在test1
中,当您通过pp
时,指针将被复制,而当您更改它时,将更改为副本而不是指针本身。使用test2
时,副本是一个双指针,但当您在此处取消引用并赋值时
*pp = &myVar;
您正在更改指向的内容,而不是更改
pp
本身。请注意,test2
中的这种行为是未定义的,正如这里的一些其他答案所记录的那样如果您想更改T
类型变量的值,您必须在该类型上使用指针(T*
)。由于要更改指针(T=int*
),必须提供指向指针的指针(T*=int**
),否则只能更改副本
注意
int myVar = 9999;
*pp = &myVar;
将导致未定义的行为,因为pp
现在将包含在退出函数后无效的局部变量的地址。因为f(x)
无法更改x
的值,无论x是int、float还是指针
int* p1;
p1 = &i;
test1(p1); //1st
test2(&p1); //2nd
简单地说,第一个是传递值
,第二个是传递地址
说明:
在第一种情况下,它传递的指针实际上是test1
内部p
的副本,因此test1内部的pp
是该函数的本地指针,它是在test1
中创建的。你分配了地址,当它失效时,它就被销毁了
但在第二种情况下,您将指针的地址传递给
test2
函数。因此test2
中的指针pp
将指向main中的指针p
,因此使用*pp=&myVar
为pp
分配一个新地址将自动设置p
的值(因为您正在解除对指针的引用)。因此,当test2
终止时,p
仍将指向修改的位置。pp=&myVar代码>将myVar
的地址分配给指针pp
。如果要更改pp
指向的值,请使用
*pp = myVar;
相反
在回答第二个问题时,如果要更改指向的对象,而不是更改现有对象的值,请将指针传递给指针。但您没有更改i
的值,而是更改pp
指向的地址,如果您只想更改i
的值,那么将测试更改为:
void test3(int* pp)
{
int myVar = 9999;
*pp = myVar;
}
此函数被传递一个指针pp
。该函数修改该指针。但由于参数是按值传递的,因此调用方看不到该修改
您需要这样编写函数:
void test1(int* pp)
{
*pp = 9999;
}
int i = 0;
test1(&i); // pass address of int variable
printf("%d\n", i); // prints the new value, 9999
此函数的调用方应传递int
变量的地址。然后,函数将int
值(本例中为9999)写入该地址。这是关键。向您传递一个地址,然后向该地址写入一个值。你的坏版本只是修改了地址。你错过了间接的过程
当函数返回时,调用方可以观察对int
变量的修改,该变量的地址已传递给函数。调用代码可以如下所示:
void test1(int* pp)
{
*pp = 9999;
}
int i = 0;
test1(&i); // pass address of int variable
printf("%d\n", i); // prints the new value, 9999
现在,这是在一个非常严重的方式打破。此函数确实返回指向调用方的指针。但它返回一个指向一个对象的指针,该对象在函数返回后立即超出范围。这被称为未定义的行为。不要这样做。切勿从函数中传出指向该函数中定义的局部变量的指针。请注意,由于局部变量的地址超出了它的使用范围,程序的格式不正确。我注意到test2中的缺陷,但我在这里故意不去碰它,因为它举例说明了需要避免的危险情况。感谢所有回复者的启发……我建议大家阅读以下有趣的内容:)在底部,你可以找到一个与C相关的问题。它并不“危险”。这只是错误的、破碎的、未定义的行为。它不会工作,除非在一些非常罕见的测试用例中,星星正好对齐,使其正常工作。不,OP想要更改值。