目录
1.语法形式
ret_type fun_name(形式参数)
{
}
void print_star()
{
printf("******************\n");
}
ret_type 是函数返回类型 eg:int、void·····
void表示什么都不返回
fun_name、 print_star是函数名
起名字时候要尽量根据函数的功能来取
2.进入学习前的说明
(1)一个C程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件。对较大的程序,一般不希望把所有内容全放在一个文件中,而是将它们分别放在若干个源文件中,由若干个源程序文件组成一个 C程序。这样便于分别编写和编译,提高调试效率。一个源程序文件可以为多个C程序共用。
(2)一个源程序文件由一个或多个函数以及其他有关内容(如指令、数据声明与定义等)组成。一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位进行编译的,而不是以函数为单位进行编译的。
(3)C程序的执行是从main函数开始的,如果在 main 函数中调用其他函数,在调用后流程返回到main函数,在main 函数中结束整个程序的运行。
(4)所有函数都是平行的,即在定义函数时是分别进行的,是互相独立的。一个函数并不从属于另一个函数,即函数不能嵌套定义。函数间可以互相调用,但不能调用main 函数。main 函数是被操作系统调用的。
(5)从用户使用的角度看,函数有两种。
① 库函数。它是由系统提供的,用户不必自己定义,可直接使用它们。应该说明,不同的C语言编译系统提供的库函数的数量和功能会有一些不同,当然许多基本的函数是共同的。
②用户自己定义的函数。它是用以解决用户专门需要的函数。
(6)从函数的形式看,函数分两类。
①无参函数。如上面程序中 print_star就是无参函数。在调用无参函数时,主调函数不向被调用函数传递数据。无参函数一般用来执行指定的一组操作。例如,上面程序中的 print_star 函数的作用是输出18个星号。无参函数可以带回或不带回函数值,但一般以不带回函数值的居多。
②有参函数。在调用函数时,主调函数在调用被调用函数时,通过参数向被调用函数传递数据,一般情况下,执行被调用函数时会得到一个函数值,供主调函数使用。
3.函数举例
如下的max函数就是有参函数,从主函数把a和b的值传递给max函数中的参数x 和y,经过 max 的运算,将变量 z 的值带回主函数。此时有参函数应定义为与返回值相同的类型(例1.3的max函数定义为int型)。
#include<stdio.h>
int max(int x,int y)//扔到这里,用x,y来接收
{
int z;
if(x>y)
z=x;
else
z=y;
return(z);
}
int main()
{
int a,b,c;
scanf("%d %d",&a,&b);
c=max(a,b);//调用函数,相当于从这里扔球a,b扔到
printf("max=%d\n",c);
return 0;
}
4.实参和形参
在调用有参函数时,主调函数和被调用函数之间有数据传递关系。从前面已知:在定义函数时函数名后面括号中的变量名称为"形式参数"(int max后面的x,y),(简称"形参")
为什么叫形参?
如果只是定义了max函数,而不去调用它,这俩个参数就只是形式上存在的
主调函数中调用一个函数时,函数名后面括号中的参数称为"实际参数"(简称"实参")。实际参数可以是常量、变量或表达式。
注意:在调用函数中发生实参和形参之间的数据传递称为“虚实结合”。
5.return 语句
retum语句使用的注意事项。
1) return后边可以是一个数值,也可以是一个表达式,如果是表达式时先执行表达式,再返回表达式的结果。
2) return后边也可以什么都没有,直接写return;这种写法适合函数返回类型是void的情况。
3)return返回的值和函数返回类型不一致,系统会自动将返用的值隐式转换为函数的返回类型。
return语句执行后,函数就彻底返回,后边的代码不再执行。
4)在定义函数时指定的函数类型一般应该和return语句中的表达式类型一致。例如3.函数举例中的,max函数为整形,变量z也指定为整形
函数类型决定返回值的类型。
5)对于不带返回值的函数,应当用定义函数为“void”类型,此时在函数中不得出现return语句。
6)如果函教中存在if等分支的语句,则要保证每种情况下都有return返回,否则会出现编译错误。如下举例。
#include <stdio.h>
int is_leap_year(int year)
{
if(((0 == year%4)&&(0!=year%100))||(0==year%400))
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int year,y;
scanf("%d",&year);
y=is_leap_year(year);
printf("%d",y);
}
6.数组做参数
将一个整形数组的元素全部置为-1 ,如下
注意:
- 数组在传参的时候,实参就写数组名就行,形参也是数组的形式
- 实参和形参的名字可以相同也可以不相同
- 函数在设计的时候一定要功能单一,就可以想设置就设置,想打印就打印
- 数组在传参的时候,形参和实参的数组是同一个
- 形参和实参的个数要匹配
- 形参如果是一维数组,数组的内容是可以省略的,上面的arr[10]可以写成arr
- 形参如果是二维数组,数组的内容行可以省略,列不可以
7.嵌套调用
C语言的函数定义是相互平行、独立的,也就是说,在定义函数时,一个函数内不能再定义另一个函数,即不能嵌套定义,但可以嵌套调用函数,即在调用一个函数的过程中,又调用另一个函数。
例子:求某年某月多少天
#include <stdio.h>
int is_leap_year(int year)
{
if(((0 == year%4)&&(0!=year%100))||(0==year%400))
{
return 1;
}
else
{
return 0;
}
}
int get_days_of_mouth(int y,int m)
{
int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//加上0会更方便,月份和下标一一对应了
int day=days[m];
if(is_leap_year(y)==1&&m==2)//这就是嵌套调用,这个函数里又调用了另一个函数
{
day++;//闰年的2月是29天所以要加一
}//闰年的2月是29天所以要加一
return day;
}
int main()
{
int year,mouth,day;
scanf("%d %d",&year,&mouth);
is_leap_year(year);
day=get_days_of_mouth(year,mouth);
printf("%d",day);
}
8.递归调用
在我的主页,大家可以看一下
9.函数的定义
如果我将主函数和定义的函数换个位置,就会出现这样的报错,所以我们应该将它定义一下
我们只用把调用的函数放在主函数的第一行或者放在主函数的上面,如下
10.局部变量
定义变量可能有3种情况:
(1)在函数的开头定义;
(2)在函数内的复合语句内定义;
(3)在函数的外部定义。
在一个函数内部定义的变量只在本函数范围内有效,也就是说只有在本函数内才能引用它们,在此函数以外是不能使用这些变量的。在复合语句内定义的变量只在本复合语句范围内有效,只有在本复合语句内才能引用它们。在该复合语句以外是不能使用这些变量的,以上这些称为"局部变量"。
例如,在funl函数中定义了变量a,b,在fun2函数中定义了变量a,c。funl函数中的变量a和fun2函数中的变量a不是同一个对象。它们分别有自己的有效范围。正如高一甲班有一学生叫王建国,高一乙班也有一学生叫王建国,二者不是同一个人。不同的班允许有同名的学生,互不干扰。高一甲班点名时,只有该班的王建国喊"到",乙班的王建国不在甲班活动,不会同时喊"到"的。他们的活动范围局限在本班,或者说这些名字的有效范围是局部的(只在本班有效)。
注意:
(1)主函数中定义的变量(如m,n)也只在主函数中有效,并不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。
(2)不同函数中可以使用同名的变量,它们代表不同的对象,互不干扰。例如,f1函数中定义了变量b和c,倘若在f2函数中也定义变量b和c,它们在内存中占不同的单元,不会混淆。
(3)形式参数也是局部变量。例如 fl函数中的形参a,也只在函数中有效。其他函数可以调用 fl 函数,但不能直接引用 fl 函数的形参 a(例如想在其他函数中输出a的值是不行的)。
(4)在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这种复合语句也称为"分程序"或"程序块"
11.全局变量
一个源文件可以包含一个或若干个函数。在函数内定义的变量是局部变量,而在函数之外定义的变量称为外部变量,外部变量是全局变量(也称全程变量)。全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。
注意:定义的变量是局部变量,在函数外定义的变量是全局变量
注意:若全局变量与局部变量同名,局部变量优先