引言:
在我们介绍实参和形参数据传递的特点及使用技巧之前,我们先拿一个有关值传递的典型错误案例来剖析一下。
典型错误举例:
#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;
}
该方法是把变量的地址作为参数,通过解引用的方式重新给地址指向的变量赋值。该方法就能够实现在在外部函数中改变主函数内已经初始化了的变量。
使用技巧进阶:
#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;
}