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
- c语言中参数传递(指针参数)
- C语言指针传递参数
- C语言中函数和指针的参数传递
- C语言中指针数组作为参数传递修改内容
- C指针参数传递
- C语言之旅(5)参数传递(值传递,指针传递,数组传递)
- c/c++中指针参数传递
- C中函数传递参数原理:值传递, 指针传递?
- C中函数传递参数原理:值传递, 指针传递?
- C/C++语言参数传递----值传递、引用传递、指针传递、指针引用传递
- C/C++语言参数传递----值传递、引用传递、指针传递、指针引用传递
- C/C++语言参数传递----值传递、引用传递、指针传递、指针引用传递
- c语言参数传递
- C语言参数传递
- C语言参数传递
- C语言参数传递
- C语言参数传递
- C语言参数传递
- 【leetcode_easy】101-SymmetricTree
- python3.6.3+opencv3.3.0学习笔记一
- 架构设计(2)-架构设计原则
- Zemax中的Mtf
- Android中的字体设置-Typeface
- c语言中参数传递(指针参数)
- 15、线程控制
- 【工作笔记】jquery、ajax省市区级联操作
- C# 解决引用dll,出现dll不可以使用等问题
- each函数
- 使用springMVC + ajaxfileupload上传文件
- 第一天 HTML基础教程
- Hibernate学习之 环境搭建
- 队列的入队、出队基本操作