写 C 语言函数的时候,你是不是遇到过这种情况?想在函数里改个变量的值,传过去之后函数里确实变了,可回到主函数一看,还是老样子。这时候有人告诉你,用指针传参就行,可你试了试,要么编译报错,要么结果更乱。到底指针该怎么正确传递参数呢?今天兔子哥就用大白话给你讲明白,新手也能一看就懂,一起往下看吧!
首先得弄明白,为啥普通参数传过去改不了?C 语言里函数传参默认是 “值传递”,意思就是把变量的值复制一份给函数里的参数。就像你把作业本借给同学抄,他在自己本子上改得再花,你的原作业本还是原样。
比如这个例子:
c运行
#include void change(int x) {x = 100; // 改的是复制的副本}int main() {int a = 10;change(a); // 传的是a的值printf("%d", a); // 还是10,没变化return 0;}这就是因为函数里改的是副本,根本影响不到外面的 a。那指针怎么解决这个问题呢?
用指针传递普通变量的地址,就能改原值了
指针存的是地址,把变量的地址传给函数,函数里通过指针就能找到原变量,这时候修改的就是真身了。
正确的写法应该是这样:
c运行
#include void change(int *x) { // 用指针接收地址*x = 100; // 通过指针找到原变量,修改它}int main() {int a = 10;change(&a); // 传a的地址(&是取地址符)printf("%d", a); // 变成100了,成功修改return 0;}这里要注意三个点:
- 函数参数得是指针类型,比如
int *x - 调用函数时传的是变量的地址,得加
& - 函数里修改时要用
*x,意思是 “找到 x 指向的变量”
很多新手容易忘写
&,或者在函数里直接用x = 100(少了*),这样肯定改不了,得特别注意。传递数组的时候,指针传参更方便
数组名本身就是首元素的地址,所以传数组的时候不用加
&,直接传数组名就行,函数里用指针接收。比如给数组每个元素加 1:
c运行
#include void addOne(int *arr, int len) { // 指针接收数组for (int i = 0; i < len; i++) {*(arr + i) += 1; // 用指针访问数组元素}}int main() {int nums[3] = {1,2,3};addOne(nums, 3); // 直接传数组名// 打印结果:2 3 4for (int i = 0; i < 3; i++) {printf("%d ", nums[i]);}return 0;}为啥数组传参不用加
&?因为数组名天生就是地址,这是 C 语言的规定。如果你写成addOne(&nums, 3)反而会报错,类型对不上。想修改指针本身,得用二级指针传参
这是个难点。如果函数里想改变指针的指向,比如给指针分配内存,这时候传一级指针就不行了,得传指针的地址(二级指针)。
看这个错误的例子:
c运行
#include #include void allocMem(int *p) {p = (int*)malloc(sizeof(int)); // 试图改指针指向*p = 10;}int main() {int *ptr = NULL;allocMem(ptr); // 传的是一级指针printf("%d", *ptr); // 崩溃!ptr还是NULLreturn 0;}为啥会崩溃?因为
allocMem里的p是ptr的副本,函数里改p的指向,ptr本身没变,还是 NULL。这时候就得用二级指针:c运行
void allocMem(int **p) { // 二级指针接收指针的地址*p = (int*)malloc(sizeof(int)); // 改的是原指针的指向**p = 10; // 给分配的内存赋值}int main() {int *ptr = NULL;allocMem(&ptr); // 传指针的地址printf("%d", *ptr); // 输出10,成功了free(ptr);return 0;}二级指针有点绕,但记住:想改谁,就传谁的地址。改普通变量传变量地址(一级指针),改指针变量就传指针的地址(二级指针)。
不同传参方式对比表
| 想做什么 | 传参方式 | 函数参数类型 | 例子 |
|---|---|---|---|
| 只用变量的值,不改它 | 传变量本身 | int x | change(a) |
| 想修改变量的值 | 传变量地址 | int *x | change(&a) |
| 操作数组元素 | 传数组名 | int *arr | addOne(nums) |
| 想修改指针的指向 | 传指针地址 | int **p | allocMem(&ptr) |
可能有人会问,是不是所有情况都得用指针传参?也不是。如果只是用变量的值,不用修改,普通传参更简单。指针传参主要是为了解决 “修改外部变量” 和 “高效传递大块数据”(比如数组)的问题。
兔子哥刚开始学的时候,二级指针这块卡了好久,总觉得
*和&太多绕不过来。后来发现,只要记住 “传地址才能改原值”,多写几次代码,打印一下指针的值和指向的值,慢慢就明白了。其实指针传参没那么玄乎,关键是分清 “传值” 和 “传地址” 的区别。写代码的时候多问自己一句:这个参数是想改它本身,还是只用它的值?想明白这个,就不容易出错了。遇到问题也别慌,用 printf 多打印几个中间值,调试着调试着就找到规律了。希望这些能帮到你,多练几次肯定能掌握!
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~