c语言中参数传递(指针参数)

来源:互联网 发布:mysql的update语句 编辑:程序博客网 时间:2024/05/22 13:11

C语言中调用函数传递参数实质上是传递一个当前传入数值的拷贝到新函数参数中,如下,最简单的一个函数:

void test(int a){ ... }

当调用该函数时,如test(x);会新开辟一个int大小的内存a,将x值赋值给a,但如果想要做到修改a值,这种传值方式无法完成,因为当test函数调用结束时,a分配的内存空间也会被释放

一级指针作为参数

当需要将修改后的结果回传,则需要使用指针,如下

void test(int *p){ ... }

调用时原理也是一样,不过这里传入的值应该是一个int *类型,也就是一个int型的内存地址。调用test函数时将传入内存地址的值赋给新变量p,p被定义成int *类型,专门存储int型内存地址,然后通过*操作符可以访问p存储的内存地址指向的值,也可以修改这个内存地址的值。这样就实现了将修改结果传回。

例如

void test(int *p){    cout << &p << "  " << p << ":  " << *p << endl;    *p = 10;    cout << &p << "  " << p << ":  " << *p << endl;}int main(){    int a = 5;    cout <<&a << ":  " << a << endl;    test(&a);    cout << &a << ":  " << a << endl;    return 0;}

输出为:

0037FBD0:  50037FAFC  0037FBD0:  50037FAFC  0037FBD0:  100037FBD0:  10

这里将int型变量a的地址0037FBD0当做参数传入,test函数使用int *类型的p变量接收,也就是把0037FBD0值放入p中。为了在test中修改mian函数中的a值,只需要修改p中存储的地址中的值,使用*访问到p中存储的地址对应的值。函数调用结束后p的内存被释放,但是0037FBD0内存地址中的值不会受影响,这就达到了在函数test中修改a值。

二级指针作为参数

二级指针作为参数作用:为了拿到调用函数中产生的一个地址

再看如下例子(错误示例),这里程序希望拿到test中的局部变量m的地址值,但是并未达到目的。
(这里注意:拿到m的地址值并没有意义,也无法获得m中存储的值,因为m是test函数局部变量,内存在栈上分配,一旦test调用结束,栈上内存将被释放,m地址中存储的值也被清除,这里只是用来作为例子,拿到m的地址)???

void test(int *p){    cout << &p << "  " << p << ":  " << *p << endl;    int m = 10;    p = &m;    cout << &p << "  " << p << ":  " << *p << endl;}int main(){    int a = 5;    cout <<&a << ":  " << a << endl;    test(&a);    cout << &a << ":  " << a << endl;    return 0;}

结果:

0034FE7C:  50034FDA8  0034FE7C:  50034FDA8  0034FD94:  100034FE7C:  5

错误分析:
这里a的地址0034FE7C
p的地址是0034FDA8,p中存储a的地址0034FE7C
p = &m;这句只是将p中的值由0034FE7C改为0034FD94,当test函数调用结束时,p变量的内存被释放,即p中存储的数据也同时丢失。无法完成回传地址。(这里是无法修改的关键,因为只是修改了p中存储的值)
希望把,test中定义的局部变量m的地址传回main函数可以使用二级指针,即int** p,可以将*p=&m,即将m的地址值赋值给p所指的这个内存中。

代码如下:

void test(int **p){    cout << "&p:" << &p << "  p:" << p << "  *p:" << *p << "  **p:" << **p << endl;    int m = 10;    cout << "&m:" << &m << "  m:" << m << endl;    *p = &m;    cout << "&p:" << &p << "  p:" << p << "  *p:" << *p << "  **p:" << **p << endl;}int main(){    int a = 5;    int *b = &a;    cout << "&b:" << &b << "  b:" << b << "  *b:" << *b << endl;    test(&b);    int m[1024];    cout << "&b:" << &b << "  b:" << b << "  *b:" << *b << endl;    return 0;}

输出如下

&b:0040FE98  b:0040FEA4  *b:5&p:0040EDB8  p:0040FE98  *p:0040FEA4  **p:5&m:0040EDA4  m:10&p:0040EDB8  p:0040FE98  *p:0040EDA4  **p:10&b:0040FE98  b:0040EDA4  *b:10

最常见的传参

struct Student {    int a = 10;}stu;void t1(Student s){    s.a = 20;}void t2(Student& s){    s.a = 20;}void t3(Student* s){    s->a = 20;}int main(){    Student s1,s2,s3;    t1(s1);    t2(s2);    t3(&s3);    cout << s1.a << endl;    cout << s2.a << endl;    cout << s3.a << endl;    return 0;}

输出

102020