此章讲的主要是自定义函数
函数的定义
形式:
函数类型 函数名 (形参列表)
{
函数体
}
可以把函数看成个加工厂,形式参数是原料,返回值是加工好的成品
举个例子具体化一下
eg.
int compare(int a, int b)
{
if(a>=b)
return a;
if(a<b)
return b;
}
不难看出,本自定义函数的作用是对比两个整型,并返回较大的数
把原料a,b送到函数里加工,返回“较大数”这个成品
tips:
-
函数类型对应的是返回值的数据类型
此例中,返回值是a或者b,为整型
-
函数的定义一般放在总函数main(){}的前面或者后面,即外部,最后会放总例
-
不要漏了形式参数的定义,并且要分别定义,上例中int a,b就是错误的
-
当函数类型为int 或char时,可以省略,此例子中就可以省略compare前的int
-
return 语句为返回语句,可以类比为加工好的成品,此例中“成品”为较大数
-
没有返回值时,函数类型为void
eg.
void display(int x)//无返回值
{
printf("较大数为%d",x);
}
函数的声明
形式:
函数类型 函数名(形参列表);
tips:
-
与函数定义的第一行一模一样,结尾加个分号
-
函数定义若在主函数前,不需要函数声明;
-
函数定义若在主函数后,主函数内一定要函数声明;(除非你不用这个函数,那多半是不可能的,函数都定义了就会用啊)
-
别忘记分号!
具体化举例:
eg1:
#include<stdio.h>
int compare(int a, int b)
{
if(a>=b)
return a;
if(a<b)
return b;
}
void display(int x)//无返回值
{
printf("较大数为%d",x);
}
main()
{
...//调用部分,无需函数声明
}
eg2:
#include<stdio.h>
main()
{
int compare(int a, int b);//必须有函数声明!注意分号
void display(int x);//必须有函数声明!注意分号
...//调用部分
}
int compare(int a, int b)
{
if(a>=b)
return a;
if(a<b)
return b;
}
void display(int x)//无返回值
{
printf("较大数为%d",x);
}
函数的调用
形式:
函数名 (实参列表);
tips:
-
实参必须与形参数量相同,顺序相同,一一对应。
-
当有返回值的时候要有变量承接返回值。
-
调用的时候不用加数据类型。
-
形参和实参重名没有关系,分别独立
-
调用函数的时候不要写函数类型
直接上总例,调用部分标注在总例中
type1:
#include<stdio.h>
int compare(int a, int b)
{
if(a>=b)
return a;
if(a<b)
return b;
}
void display(int x)//无返回值
{
printf("较大数为%d",x);
}
main()
{
int m,n,x;//同种数据类型的变量可以同时申明
scanf("%d",&m);
scanf("%d",&n);
x=compare(m,n);//调用compare函数,用变量x承接函数返回值
display(x);//调用display函数,没有返回值,不需要变量承接
}
type2:(就是函数定义位置不同的区别)
#include<stdio.h>
main()
{
int m,n,x,compare(int a, int b);//同种数据类型的变量和函数可以同时申明
void display(int x);//函数定义在主函数后,此处需要进行函数声明
scanf("%d",&m);
scanf("%d",&n);
x=compare(m,n);//调用compare函数,用变量x承接函数返回值
display(x);//调用display函数,没有返回值,不需要变量承接
}
int compare(int a, int b)
{
if(a>=b)
return a;
if(a<b)
return b;
}
void display(int x)//无返回值
{
printf("较大数为%d",x);
}
tips:
-
函数可以嵌套调用,但不可以嵌套定义。
-
与循环、分支结构相同,函数可以进行嵌套,即函数内部调用函数。
-
函数调用自身往往称之为函数的递归
故上例也可以改成这样:(结果相同,差别是两个数比较的最大值不会被保存)
#include<stdio.h>
int compare(int a, int b)
{
if(a>=b)
return a;
if(a<b)
return b;
}
void display(int a, int b)//无返回值
{
int x;//要用到变量x承接compare返回值,此时x不再是形式参数,需要定义
x=compare(a,b);//函数的嵌套调用
printf("较大数为%d",x);
}
main()
{
int m,n,x;//同种数据类型的变量可以同时申明
scanf("%d",&m);
scanf("%d",&n);
display(m,n);//调用display函数,没有返回值,不需要变量承接
}
传值V.S.传地址
传值 | 不改变实参 |
传地址 | 改变实参 |
记住以下例子
传值:
#include <stdio.h>
void swap(int a, int b)//自定义函数
{
int c;
c=a;a=b;b=c;//调换两个数的一般算法
}
main()
{
int m=2,n=3;
printf("原来的数:%d,%d\n",m,n);
swap(m,n);//调用自定义函数
printf("调用后的数:%d,%d\n",m,n);
}
会发现m,n的值并没有变,这就是值传递
传地址:
#include <stdio.h>
void swap(int *a, int *b)//自定义函数,“*”表示取内容,此处定义地址,形参对应地址变量
{
int c;
c=*a;*a=*b;*b=c;//调换两个数的一般算法
}
main()
{
int m=2,n=3;
printf("原来的数:%d,%d\n",m,n);
swap(&m,&n);//调用自定义函数,&表示取地址,实参为地址,与形参对应
printf("调用后的数:%d,%d\n",m,n);
}
会发现m,n的值交换了,这就是地址传递
这个 值传递和地址传递 的例子为初学者常考点,留意一下
通过简单的举例可以发现,自定义函数能简化主函数部分,并使其结构更简单清晰。
函数的递归等具体算法举例,在第九章后具体化呈现
下一章节:结构体(章节:8/9)
p.s.
小红书,知乎等平台搜索知识薪火站(或youzuos),也会上传相应笔记,感谢关注。
有建议欢迎提出!