C语言-函数
无参函数
无参函数的定义形式
类型标识符 函数名()
{声明部分
语句
}
其中,类型标识符合函数名称为函数头。类型标识符指明了本函数的类型,函数的类型实际上是函数返回值的类型。函数名是由用户定义的标识符,函数名后有一个括号(),其中无参数,但是括号不可少。
{}中的内容称为函数体。在函数体中声明部分,是对函数体内部所用到的变量的类型说明。在很多情况下都不要求无参函数有返回值,此时函数类型符可以写为void。例如:
void Hello(){
printf("Hello, world\n);
}
这里只把main改为Hello作为函数名,其余不变。Hello函数是一个无参函数,当被其他函数调用时,输出Hello, world字符串。
有参函数
有参函数定义的形式
类型标识符 函数名(形式参数表列)
{
声明部分
语句
}
有参函数比无参函数多了形式参数表列。在形参表中给出的参数称为形式参数。他们可以是各种类型的变量,各参数之间用,隔开。在进行函数调用时,
主调函数将赋予这些形式参数实际的值。形参既然是变量,必须在形参表中给出形参的类型说明。例如:
int max(int a, int b){
if (a>b) return a;
else return b;
}
第一行说明max函数是一个整型函数,其返回的函数值是一个整数。形参为a,b均为整型量。a,b的具体值是由主调函数在调用时传送过来的。在{}中的函数体内,除形参外,没有其他变量,因此只有语句没有声明部分。
在max函数体中的return语句是把a(或者b)的值作为函数的值返回给主调函数。有返回值函数中至少有一个return语句。注意在C程序中,一个函数的定义可以放在任意位置,既可以放在主函数main之前,也可以放在main之后。
#include
//自定义函数
int max(int a, int b){
if (a>b) return a;
else return b;
}
int main(){
int max(int a, int b); // 先声明后使用,符合c语言先定义后使用的规范
int x,y,z;
printf("input two numbers:\n");
scanf("%d%d",&x,&y);
z = max(x,y);
printf("max number = %d\n",z);
}
结果显示:
![](https://img2023.cnblogs.com/blog/2583196/202304/2583196-20230413094320493-1657287275.png)
函数的参数和函数的值
形式参数和实际参数
函数的参数主要分为形参和实参。形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。实参出现在主调函数中,进入被调函数后,实参变量也不能使用。形参和实参的功能是做数据传送。
发生函数调用时,主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送。函数的形参和实参具有以下特点:
形参变量只有在被调用时才分配内存单元,在调用结束时,即可释放所分配的内存单元。因此形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使实参获得确定值。
实参和形参在数量上,类型上,顺序上应严格一致,否则会发生类型不匹配的错误
函数调用中发生的数据传送是单向的,即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。
实例:实现计算\(\sum n_{i}\)
#include
//函数调用
int main(){
int n;
printf("input number\n");
scanf("%d",&n);
s(n);
printf("n=%d\n",n);//打印输入值
}
int s(int n){
int i;
for(i=n-1;i>=1;i--)
n = n+i;
printf("n=%d\n",n);//打印结果
}
结果输出:
![](https://img2023.cnblogs.com/blog/2583196/202304/2583196-20230413100728598-1024826394.png)
函数的返回值
函数的值是指函数被调用之后,执行函数体中的程序段所取得的并返回给主调函数的值。如调用正弦函数取得正弦值,对函数的返回值有几点说明
函数的值只能通过return语句返回主调函数
return语句的一般形式:return 表达式;
或 return (表达式);
函数值的类型和函数定义中函数的类型应保持一致。如果两者不一致,则以函数类型为准,自动进行类型转换。
如函数值为整型,在函数定义时可以省去类型说明
不返回函数值的函数,可以明确定义为“空类型”,类型说明符为void
函数的调用
函数调用的一般形式
在C语言中,函数调用的一般形式为:函数名(实际参数表)
。对无参函数调用时则无实际参数表。实际参数表中的参数可以是常数,变量或其他构造类型数据及表达式。各实参之间用逗号分隔。
函数调用的方式
在C语言中,可以用以下几种方式调用函数:
函数表达式:函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数是有返回值的,例如z=max(x,y)是一个赋值表达式,把max的返回值赋予变量z。
函数语句:函数调用的一般形式加上分号即构成函数语句,例如printf("%d",a);,scanf("%d",&b);都是以函数语句的方式调用函数。
函数实参:函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因此要求该函数必须是有返回值的,例如printf("%d",max(x,y));即使把max调用的返回值又作为printf函数的实参来使用。
在函数调用中还应该注意的一个问题是求值顺序的问题。所谓求值顺序是指对实参表中各量是自左至右使用还是自右至左使用?对此,各系统的规定不一定相同。#include
int main() {
int i = 8;
printf("%d\n%d\n%d\n%d\n", ++i, --i, i++, i--);
}
结果显示:
被调函数的声明和函数原型
在主调函数中调用某函数之前应对该被调函数进行说明(声明),这与使用变量之前要先进行变量说明是一样的。在主调函数中对被调函数做说明的目的是使编译系统知道被调函数返回值的类型,以便在主调函数中按此种类型对返回值做相应处理。
其一般形式:类型说明符 被调函数名(类型 形参,类型 形参...);或者类型说明符 被调用函数名(类型,类型);例如:
int max(int a,int b);或者写成int max(int, int);
C语言中规定在以下几种情况下可以省去主调函数对被调函数的函数说明
- 如果被调函数的返回值是整型或字符型时,可以不对被调函数作说明,而直接调用。这时系统将自动对被调函数返回值按整型处理。
- 当被调函数的函数定义出现在主再作说明而直接调用。
- 如在所有函数定义之前,在函数外预先说明了各个函数的类型,则在以后的各主调函数中,可不再对被调函数作说明。
函数的嵌套使用
C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题。但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了
函数的嵌套调用。即在被调函数中又调用其它函数。这与其它语言的子程序嵌套的情形是类似的。
实例1:计算\(s = 2^{2}!+3^{2}!\)
解析:可以编写两个函数,一个用来计算平方值的函数,另一个计算阶乘。主函数先调用平方值计算函数,再调用阶乘函数
#include
//阶乘计算
long f2(int q){
long i,c=1;
for (i=1;i0)
printf("%d",v);
else
printf("%d",0);
}
int main(){
int a[5],i;
printf("input 5 numbers:\n");
for (i=0;isex='M';
ps->score=62.5;
#ifdef NUM //由于在程序的第 16 行插入了条件编译预处理命令,因此要根据 NUM 是否被定义过来决定
//编译 句。而在程序的第一行已对 NUM 作过宏定义,因此应对第一个 `printf`语句作编译故运行结果是输出了学号和成绩
printf("Number=%d\nScore=%f\n,ps->num,ps->score");
#else
printf("Name=%s\nSex=%c\n",ps->name,ps->sex);
#endif
free(ps);
}
结果输出:
第二种形式
#ifndef 标识符
程序段 1
#else
程序段 2
#endif
与第一种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被
#define 命令定义过则对程序段 1 进行编译,否则对程序段 2 进行编译。这与第一种形式的功能正相反。
第三种形式
#if 常量表达式
程序段1
#else
程序段2
#endif
它的功能是,如常量表达式的值为真(非 0),则对程序段 1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。
实例:#include
//条件编译
#define R 1
main(){
float c,r,s;
printf("input a number:");
scanf("%f",&c);
#if R
r=3.14159*c*c;
printf("area of round is:%f\n",r);
#else
s=c*c;
printf("area of square is:%f\n",s);
#endif
}
本例中采用了第三种形式的条件编译。在程序第一行宏定义中,定义 R 为 1,因此在条件编译时,常量表达式的值为真,故计算并输出面积。
|