C语言函数参数、指针参数本质及与&取地址符相关疑问咨询
C语言函数参数的本质属性
- 函数形参是真实存在的独立局部变量,不是语法层面的虚拟占位符。函数被调用时,系统会在当前函数的栈帧空间内,为每一个形参分配专属的内存区域,它的生命周期、内存管理逻辑和函数内部手动定义的普通局部变量完全一致:函数进入执行流时分配内存,函数返回后随栈帧销毁一同被回收。
- 不存在“形参是专门用来存储其他变量的特殊变量”的模糊定义,它的核心属性是C语言值传递机制下的拷贝接收载体:函数调用发生时,传入的实参会先完成一次值拷贝,拷贝出的副本会被写入形参对应的内存空间,后续函数内部对形参的所有读写操作,都只作用在这块独立的内存上,默认无法直接修改调用方持有的原始实参。
注意不要把C语言的形参规则和C++的引用形参混淆:C语言原生没有引用语义,所有参数传递统一走值拷贝逻辑,形参永远是独立的实体,不会和外部变量绑定为别名。
指针参数的核心规则答疑
为什么传参时已经用&拿到了内存地址,函数定义阶段仍需要声明指针类型形参?
&运算符取到的结果本质是一个代表内存地址的整数值,但C语言是强类型静态语言,所有变量必须明确声明类型,指针类型的标记有两个不可替代的作用:
- 给编译器传递合法语义标记:只有当形参被声明为指针类型时,编译器才会认可对该变量做
*解引用操作是合法语法;如果把存地址的形参声明为普通整型,后续写解引用逻辑会直接触发编译报错。 - 明确内存访问的规则:指针类型携带了它指向的目标的数据类型信息,编译器会根据这个信息确定解引用时的访问步长、数据解析规则。比如形参声明为
int*时,解引用会从存储的地址开始读取对应int长度的字节,把内容解析为整型;如果错声明为char*,解引用只会读取1个字节,最终得到的数据会完全错误。
指针参数是否确实用于存储内存地址?
- 是,但指针参数本质没有任何特殊性,它就是一个类型为指针的普通局部变量,只是存储的数值被约定为「某块内存的地址」而已。
- 传参时传入
&变量的逻辑,和传普通整型值没有本质区别:都是把实参的值做一次拷贝,写入形参的内存空间。这也是为什么在函数内部直接给指针形参本身赋值(比如写p = NULL),只会修改形参这个局部变量自己存储的地址值,完全影响不到外部变量;只有通过*p的方式解引用,顺着形参里存储的地址找到对应的外部内存空间,才能修改外部变量的值——这就是“指针可以修改函数外变量”的本质,不存在什么特殊的跨作用域魔法。
可以配合一段简单的代码验证逻辑:
#include <stdio.h> void demo(int normal_arg, int *ptr_arg) { // 两个形参都是demo函数栈帧内的独立局部变量 normal_arg = 999; // 仅修改局部的normal_arg,外部实参不受影响 *ptr_arg = 888; // 顺着ptr_arg存的地址,修改外部变量的内存内容 ptr_arg = NULL; // 仅修改局部的ptr_arg存储的地址值,外部指针不受影响 } int main() { int num1 = 10; int num2 = 20; demo(num1, &num2); // 输出结果为 num1 = 10, num2 = 888 printf("num1 = %d, num2 = %d\n", num1, num2); return 0; }
内容的提问来源于stack exchange,提问作者PuuRaidur
相关产品推荐
相关产品推荐

