在C语言中,理解值传递、地址传递和引用传递非常重要,首先,我们得来区分一下指针变量、指针地址、指针的值之间的关系。有三个变量:
C是"一段内容";
B是一个指针变量,存放着C的地址;
A是一个二级指针变量,存放着B的地址。如下图所示:
一级指针作参传递
代码中定义了三个同样类型的变量(a、b是值,q是整型指针),观察为什么执行log中*q不等于100?
#include<iostream>
using namespace std;
int a= 10;
int b = 100;
int *q;
void func(int *p) {
cout<<"func:&p="<<&p<<",p="<<p<<endl; //note:3
p = &b;
cout<<"func:&p="<<&p<<",p="<<p<<endl; //note:4
}
int main()
{
cout<<"&a="<<&a<<",&b="<<&b<<",&q="<<&q<<endl; //note:1
q = &a;
cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl; //note:2
func(q);
cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl; //note:5
system("pause");
return 0;
}
---------------------------------------------------------------
//// q = &a时,q的值变了;但是func(q)之后,q的值没变!!!
&a=0032F000,&b=0032F004,&q=0032F228
*q=10,q=0032F000,&q=0032F228
func:&p=0018FD24,p=0032F000
func:&p=0018FD24,p=0032F004
*q=10,q=0032F000,&q=0032F228
我们看输出:
note:1->a,b,q都有一个地址;note:2->q指向a;note:3->我们发现参数p的地址变了,跟q不一样了,但是其指向的地址0x0032F000(a的地址)还是不变的;note:4->p重新指向b;note:5->退出函数,p的修改并不会对q造成影响。说明参数传递是制作了一个副本,也就是p和q不是同一个指针。
二级指针作参传递
二级指针本身也是一个变量,即指针的指针。想要函数内的修改,导致外部参数联动,那就需要用二级指针作参传递。
#include<iostream>
using namespace std;
int a= 10;
int b = 100;
int *q;
void func(int **p) //2
{
cout<<"func:&p="<<&p<<",p="<<p<<endl;
*p = &b; //3
cout<<"func:&p="<<&p<<",p="<<p<<endl;
}
int main()
{
cout<<"&a="<<&a<<",&b="<<&b<<",&q="<<&q<<endl;
q = &a;
cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl;
func(&q); //1
cout<<"*q="<<*q<<",q="<<q<<",&q="<<&q<<endl;
system("pause");
return 0;
}
例子
下面代码,通过调用子函数,为主函数指针分配一块内存空间:
void my_malloc(char **s) {
*s=(char*)malloc(100);
}
void main() {
char *p=NULL;
my_malloc(&p);
free(p);
p=NULL;
}
注意:一级指针、二级指针作为参数时,入参及函数内使用参数的形式不同。