LV01-10-C语言-函数传参问题
本文主要是C语言基础——函数传参问题总结相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
Windows | windows11 |
Ubuntu | Ubuntu16.04的64位版本 |
VMware® Workstation 16 Pro | 16.2.3 build-19376536 |
SecureCRT | Version 8.7.2 (x64 build 2214) - 正式版-2020年5月14日 |
开发板 | 正点原子 i.MX6ULL Linux阿尔法开发板 |
uboot | NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03) |
linux内核 | linux-4.15(NXP官方提供) |
STM32开发板 | 正点原子战舰V3(STM32F103ZET6) |
点击查看本文参考资料
参考方向 | 参考原文 |
--- | --- |
前边在《LV01-07-C语言-函数》这篇笔记中,我们已经知道了形参有三种传递方式,地址传递,值传递和全局变量。后边学习进程和线程的时候,有遇到过通过地址传递强行完成值传递的,本篇笔记主要是想记录一些自己的疑问点。
1.变量的地址传递
我们看一个例子:
1 |
|
注意函数中打印 p 的值的时候可以用 %p ,因为大多数时候指针变量中存放的是地址,都会超过一般数据类型长度,用 %p 的话可以完整的打印地址。我们编译完,运行可执行程序后,会有以下信息:
1 | 17--> &a=0x7ffc14cfa724, a=3 |
这其实就是一个正常的变量的地址传递和变量值修改的问题,我们在传递的时候就相当于:
1 | int *p; |
2.变量值作为地址
我们传参的时候,要是不传地址,直接传一个 a ,又会怎样呢?因为理论上来说,我们传进去的是一个地址,地址无非就是一个很大的数罢了, a 的值不也是个数嘛,不也可以当做地址来用?我们来尝试一下:
1 |
|
我们编译的话,可能会报一些警告,但是问题不大,运行可执行程序后,会有以下信息:
1 | 17--> &a=0x7ffdb20f8194, a=3 |
会发现,在访问 *p 的时候,报了段错误,这是为啥?由打印结果可以看出,我们传入参数的时候,传递的是 a ,我们传递的时候就相当于:
1 | char *p; |
0x3 这个地址我们应该是无法访问的,自然就报了段错误,但是我们发现指针变量 p 中的值与 a 的值是一样的,这样就完成了值传递,在后边会有用到此种方法的场景。
3.字符指针问题
上边是一个变量的两种传递方式吗,会有不一样的效果,那一个字符指针传递的的时候会有什么不同之处吗,字符指针的指针变量可以指向一个字符串的首地址,指针名就可以代表这个字符串,我自己理解的就是,这个字符指针变量指向字符串的时候,及是一个指针,又代表了字符串的值,它在进行传递的时候会是怎样的呢?
3.1字符指针的使用
1 |
|
经过编译,运行可执行程序,我们会的到下边的提示:
1 | 8--> &str=0x7ffc14a12830 |
对字符指针 str 进行 *str 操作的话取到的是整个字符串的首字符,而 str 就直接代表了整个字符串。
3.2字符指针名传给函数
1 |
|
这样进行编译运行后,我们会得到以下信息:
1 | 18--> &str=0x7ffde7028a40 |
传参的时候就相当于:
1 | char *p; |
关系就如下图所示:
3.3字符指针取地址后传递
1 |
|
我们编译运行后,会得到以下输出信息:
1 | 18--> &str=0x7ffe24d193d0 |
传参的时候就相当于:
1 | char *p; |
关系如下图: