C语言-实参和形参数据传递的特点及使用技巧
CSDN 2024-10-04 15:05:04 阅读 51
🌏个人博客:尹蓝锐的博客
引言:
在我们介绍实参和形参数据传递的特点及使用技巧之前,我们先拿一个有关值传递的典型错误案例来剖析一下。
典型错误举例:
<code>#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void fun(int a)
{
a = 2;
}
int main()
{
int a = 0;
fun(a);
printf("%d", a);
return 0;
}
错误原因解析:
实参向形参的数据传递是“值传递”,单向传递,只能由实参传给形参,而不能由形参传给实参。实参和形参在内存中占有不同的存储单元,实参无法得到形参的值,也就是说,在该函数中,无法将主函数中的a变量的值进行修改。
使用技巧:
通过上述错误案例,我们思考该如何实现在外部函数中改变主函数中已经初始化了的变量,那么有这么一种方法或者说技巧(传引用)如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void fun(int *a)
{
*a = 2;
}
int main()
{
int a = 0;
fun(&a);
printf("%d", a);
return 0;
}
该方法是把变量的地址作为参数,通过解引用的方式重新给地址指向的变量赋值。该方法就能够实现在在外部函数中改变主函数内已经初始化了的变量。
使用技巧进阶1:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int k = 5;
void f(int** s)//step3.
{
*s = &k;//step4.
}
void main()
{
int m = 3 ,* p = &m;//step1.
f(&p);//step2.
printf("%d,%d\n", m, *p);
}
输出:
3,5
分析:
step1.把变量m的地址赋给指针变量p,指针变量p的值为m的地址
step2.把指针变量p的地址作为函数参数
问:为什么要把指针变量p的地址作为函数参数?
答:同样的,实参向形参的数据传递是“值传递”,单向传递,只能由实参传给形参,而不能由形参传给实参,我们把指针变量p的地址作为函数参数,是为了通过解引用的方式,改变实参指针变量p的值,即改变指针变量p的指向
值 | 指向 | 解引用 | |
一级指针 | 6的地址 | 6 | 6 |
二级指针 | 一级指针的地址 | 一级指针 | 一级指针 |
step3.用二级指针变量s接收指针变量p的地址
step4.将函数形参,二级指针变量s的值(即一级指针)重新赋值为变量k的地址,也就是说实参 ‘指针变量p的地址’ 成功的重新赋值为k的地址,同样也意味着指针变量p重新指向变量k的值
使用技巧进阶2:
<code>#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void openFile(FILE **fpa,FILE **fpb, FILE **fpc) //打开文件函数
{
*fpa = fopen("A.txt", "r");
if (*fpa == NULL)
{
printf("打开文件A失败\n");
exit(1);
}
*fpb = fopen("B.txt", "r");
if (*fpb == NULL)
{
printf("打开文件B失败\n");
exit(1);
}
*fpc = fopen("C.txt", "w");
if (*fpc == NULL)
{
printf("打开文件c失败\n");
exit(1);
}
}
int main()
{
FILE* fpa, *fpb, *fpc;
openFile(&fpa, &fpb, &fpc);//打开全部文件,A,B以只读方式,C以写入方式
return 0;
}
三个FILE类型的指针在主函数中我们没有给它们指向任何文件,也就相当于没有给他们三个初始化。那么我们想通过外部函数的方式让这三个FILE类型的指针重新指向一个文件。如果将一级指针传给openFile函数,然后在openFile函数中将一级指针指向fopen函数即以下代码,那么根据值传递的特点,main函数中的File类型指针实际上根本没有指向fopen函数,这显然是错误的。那么我门就需要在外部函数中拿指针的指针,也就是地址的地址,通过解引用的方式,重新给主函数中的FILE类型指针初始化
void openFile(FILE *fpa,FILE *fpb, FILE *fpc) //打开文件函数(错误写法)
{
fpa = fopen("A.txt", "r");
if (fpa == NULL)
{
printf("打开文件A失败\n");
exit(1);
}
fpb = fopen("B.txt", "r");
if (fpb == NULL)
{
printf("打开文件B失败\n");
exit(1);
}
fpc = fopen("C.txt", "w");
if (fpc == NULL)
{
printf("打开文件c失败\n");
exit(1);
}
}
int main()
{
FILE* fpa, *fpb, *fpc;
openFile(fpa, fpb, fpc);//(错误写法)
return 0;
}
对比理解:
如果我的博客能给您带来启发,请不吝点赞、评论和收藏,也欢迎您关注我的博客。
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。