参考资料:高教版《全国计算机等级考试二级教程——C语言程序设计》
传给main函数的参数
可以在运行C 程序时,通过运行C程序的命令行把参数传送给C程序。
main函数通常可用两个参数,如:
main(int argc, char **argv);
其中argc和argv是两个参数名,可由用户自己命名,但它们的类型是固定的。第一个参数必须是整型,第二个参数必须是一个指向字符型的指针数组的指针,这个字符型指针数组的每个指针都指向一个字符串。
因此,第二个参数argv还可以直接定义成基类型为字符型的指针数组:
char *argv[];
对包含以上主函数的、名为myc的文件进行编译连接,生成名为myc.exe的可执行文件后,即可在命令提示符下输入命令“myc”来执行该程序。这就成为命令行,myc即为执行程序的命令。
这时argc中的值为1,argv[0]中将存放字符串“ myc”的首地址(即指向字符串 myc)。
命令行中,各参数之间用空格符或tab符隔开,空格符不作为参数的内容。
注:如果要把空格也作为参数的内容,应该把字符串放在一对双引号内。
例1 若以下程序存放在myc.c文件中,在编译连接后,生成一个myc.exe文件,输出argc和argv中的数据。
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("argc = %d\n", argc);
for(i = 1; i < argc; i++)
printf("%s", argv[i]);
printf("\n");
}
若在命令行中输入:
myc A COMMAND LINE \n (\n代表回车键)
程序将输出:
argc = 4
A COMMAND LINE
通过实参向函数传递函数名或指向函数的指针变量
指向函数指针变量的定义
在C语言中函数名代表该函数的入口地址,因此可以定义一种指向函数的指针来存放这种地址。例如:
#include <stdio.h>
double fun(int a, int *p)
{
……
}
int main(void)
{
double (*fp)(int, int *), y;
int n;
fp = fun;
……
y = (*fp)(56, &n); //此处通过指向函数的指针调用fun函数
……
}
在这里,说明符(*fp)(int, int *)说明fp是一个指向函数的指针变量,这个函数必须是double类型。
注意:若写成fp(int, int ),则说明的fp就不是指针变量,而是说明fp是一个函数,该函数的返回值类型是基类型为double的指针类型**。
说明符后面一对圆括号中是类型名,用以说明所指函数的参数个数和参数的类型,这些类型名应该与所指函数参数的类型一一对应。
注意:如果函数没有形参,这一对圆括号也不可以省略。
表达式fp = fun把fun函数的地址赋予指针变量fp,此处fp的类型必须与fun的类型相同。
语句y = (*fp)(56, &n);实现对函数fun的调用,它与y = fun(56, &n);等价。
函数名或指向函数的指针变量作为实参
函数名或指向函数的指针变量可以作为实参传递给函数。这时,对应的形参应当是类型相同的指针变量。
例 2 通过给tran函数传送不同的参数名,求tan x和cot x的值。
#include <stdio.h>
#include <math.h>
double tran(double (*)(double), double (*)(double), double); //函数说明语句
int main(void)
{
double y, v;
v = 60 * 3.1416 / 180.0;
y = tran(sin, cos, v); //第一次调用
printf("tan (60) = %10.6f\n", y);
y = tran(cos, sin, v); //第二次调用
printf("cot (60) = %10.6f\n", y);
return 0;
}
double tran(double (*f1)(double), double (*f2)(double), double x)
{
return (*f1)(x) / (*f2)(x);
}
函数tran有三个形参f1,f2,x。其中f1和f2是两个指向函数的指针变量,它们所指函数的返回值必须是double类型,所指函数有一个double类型的形参。第三形参x是double类型的简单变量。
v的值是60°角的弧度。
在第一次调用中,把库函数sin的地址传送给指针变量f1,把库函数cos的地址传送给指针变量f2,tran函数的返回值是sin(x) / cos(x)。
在第二次调用中,把库函数cos的地址传送给指针变量f1,把库函数sin的地址传送给指针变量f2,tran函数的返回值是cos(x) / sin(x)。
函数的递归调用
函数的递归调用指的是:函数可以直接或间接地调用自己。前者称简单递归,后者称间接递归。
一个问题要采用递归方法来解决,必须符合以下三个条件:
- 可以把要解的问题转化为一个新的问题,这个新的问题的解法与原来的解法相同,只是所处理的对象有规律地递增或递减。
- 可以应用这个转化过程使问题得到解决。
- 必须要有一个明确的结束递归的条件。
例 3 用递归的方法求n!
#include <stdio.h>
int fac(int n)
{
int t;
if(n == 1 || n ==0)
return 1;
else
{
t = n * fac(n - 1);
return t;
}
}
int main(void)
{
int m, y;
printf("Enter m:");
scanf("%d", &m);
if(m < 0)
printf("Input data error!\n");
else
{
y = fac(m);
printf("\n%d! = %d\n", m, y);
}
return 0;
}
当函数自己调用自己时,系统将自动把函数中当前的变量和形参暂时保存起来,在新一轮的调用过程中,系统将为该次调用的函数所用到的变量和形参开辟另外的存储单元。因此,递归调用的层次越多,同名变量所占用的存储单元也就越多。
注意:函数的递归调用通常会降低程序的运行效率。