#include <stdio.h>
int a = 9, b = 10;
void changeaa(int *asd) {
asd = &a;
}
int main()
{
int* aa; int* bb;
changea(aa);
printf(" %d\n",*aa);
getchar();
return 0;
}
//错误,因为*aa创建以后指向NULL,
//传进函数里,形参,指向NULL,修改的也是形参
int main()
{
int* aa; int* bb;
aa = &b;
changea(aa);
printf(" %d\n",*aa);
getchar();
return 0;
}
//打印的是10,函数里并没有改变指针的目标地址
//也就是说,传进去的指针会被复制一份进行操作。
第二个虽然能输出,但是输出的是10,因为传入里面以后,;临时变量的地址指向了a,但是aa指针还是指向b
想在子函数里把别的地址传给指针怎么办?
上面那个方法肯定是不行了,因为传递一维指针进去,会创建形参而代替实参,所以说如果只传递一维指针,修改的指向值只能是形参的,而不是实参的。
就只能换种方法了:
#include <stdio.h>
//想在子函数中让aa指向a;
int a = 9, b = 10;
void changeaa(int **dst) {
*dst = &a;
}
int main()
{
int* aa; int* bb;
aa = &b;
changeaa((int**)&aa);
printf(" %d\n",*aa);
getchar();
return 0;
}
//打印出来9
int main()
{
int* aa; int* bb;
changeaa(&aa);
printf(" %d\n",*aa);
getchar();
return 0;
}
//打印出来也是9
现在解释一下这两个函数程序,首先是第二个,其实两个都没有差别:
把aa的地址传了进去(我们假设地址为0x531),函数的参数是指向指针的指针(二重指针),所以说这里面的dst就是指向指针的指针,即等同于:(int * *)dst; dst = &aa;
在这里&aa会被转换为(int * *)型变量的变量值,即dst的值是aa的地址。
所以对dst第一次解引用以后,就是 *dst,也就是表示aa指针本身。(再解释一下,对指针解引用以后的值相当于指针变量值的地址所指向的区域的元素,因为这里的指针变量值正好是aa的地址)再画图解释一下吧。
因为会自动类型转换,所以其实&aa和(int**)&aa没有什么区别。
记住,想在子函数里修改指针的指向(即一维指针的值),就要用二维指针。
想在子函数里修改变量的值,就要用一维指针。