一、概述
区分好库函数和自定义函数
库函数:由C语言编译系统提供,用户无需定义,也不必在程序中做类型说明,只需要在程序前包含函数原型的头文件即可。如:scanf(),printf(),pow(),sqrt()都是库函数。
自定义函数:由用户写的函数,在程序中要定义函数本身,也要进行类型说明。
1、函数的形式参数于实际参数
#include<stdio.h>
/*
function:输出较大的数
*/
int gain_max(int a, int b);
void change(int a, int b);
int main()
{
int a, b;
printf("请输入两个数:");
scanf("%d%d", &a, &b);
printf("max = %d\n", gain_max(a, b));
change(a, b);
printf("主函数中:a = %d;b = %d\n", a, b);
return 0;
}
int gain_max(int a, int b)
{
if (a > b)
return a;
else
return b;
}
void change(int a, int b)
{
a = 3;
b = 4;
printf("在change函数中有输出:a = %d;b = %d\n", a, b);
}
输出结果为:
这里可以看到:尽管change函数中改变了a和b的值,但是在接下来程序的执行过程中,a和b的值并不改变。用户自定义函数在调用时才会分配储存空间,此时,change函数中的a和b被分配新的储存空间,和main函数中定义的a和b的储存空间不一样。调用时只是将main函数中定义的a和b的值分别赋值给change函数中的a和b。change函数调用结束后,change函数中的a和b占据的空间会被释放。在C语言中,函数允许有多个return语句,但是只有一个return语句会被执行 ,也就是说一般只有一个返回值。
2、递归调用是一种很灵活的处理方法,在人工智能方面有重要应用。
#include<stdio.h>
/*
function:递归计算n!
*/
int jiecheng(int);
int main()
{
int n;
printf("请输入一个正整数:");
scanf("%d", &n);
printf("%d的阶乘为:%d\n", n, jiecheng(n));
return 0;
}
int jiecheng(int n)
{
if (n == 1) //基例
return 1;
else //链条
return n * jiecheng(n - 1);
}
递归分成两部分,一部分是基例,就是递归的终点,即上面代码中的当n = 1时,n! = 1;另一部分是链条,链条就是数学中数列说的a(n)和a(n-1)之间的关系,即上面代码中的n! = n*((n-1)!)。有了前后的关系,并且知道终点是什么 ,我们就可以解决递归问题。
3、局部变量和全局变量
变量的有效范围称为变量的作用域。
①局部变量:
函数内定义的变量。不同函数之间的变量不能相互调用。在复合语句中可以定义变量,如main函数中for循环中可以定义几个变量,但是这几个变量的作用域就限制在了for循环的花括号中。不同函数中定义的变量占据不同的内存地址。不同函数定义的变量同名没有关系。
②全局变量:
函数外部定义的变量,它不属于哪一个函数,它属于它所在的源程序文件。
int a;
int main()
{
}
int b,c;
int fun()
{
}
变量a,b,c都是外部变量,a的作用域为main函数和fun函数,b,c的作用域为fun函数。如果想要在main函数中使用b,c变量,则要在main5函数中申明b,c为外部变量,即extern b, c;
注意:全局变量和局部变量同名时,在函数中把全局变量暂时隐藏起来,而局部变量起作用。
4、动态储存和静态储存
①动态储存:
动态储存就是分配给变量的地址是会改变的,可以是形式参数、局部变量、函数调用时的现场保护、返回地址等。这些动态储存变量在函数调用时分配储存空间,函数调用结束后释放储存空间。
②静态储存:
分配好的固定的储存空间。它可以是全局变量或着是局部变量,其定义和初始化在程序编译时进行。
由上面可以看出:局部变量既可以是动态变量,也可以是静态变量。动态变量不难理解,可以是静态变量是因为可以用static来修饰局部变量,使其变为静态变量。
5、auto变量和static变量
①auto变量:就是以动态形式储存的变量,都是局部变量。
②static变量:分为静态局部变量和静态全局变量。
(1)静态局部变量:它的数据存储在静态存储区,它与局部变量的区别在于函数退出时,变量始终存在,但不能被其他函数使用,当再次进入该函数时,将保存上次的结果,其他与局部变量一样。其在整个程序运行的过程中空间都不释放。静态局部变量是在编译时赋初值的,只赋值一次,在程序运行时它就有值了,以后每次调用函数时不再重新赋值而是保留上次函数调用结束时的值。如何定义的静态局部变量没有赋初值,则编译时自动赋初值0或空字符。
(2)静态全局变量:指只在定义它的源文件中可见而在其他源文件中不可见的变量。它与全局变量的区别是全局变量可以再说明为外部变量( extern),被其他源文件使用,而静量却不能再被说明为外部的,只能被所在的源文件使用。
5、register变量
6、内部函数和外部函数
函数默认都是全局的函数(即外部函数),可以被其他函数或者是其他文件调用。可以用static指定函数不能能被其他文件调用(即内部函数)。如:
static int fun()
{
}
例子:
#include<stdio.h>
/*
function:求两个数的最小公倍数
*/
//两个数的乘积除以两个数的最大公约数就是两个数的最小公倍数。
int gcd(int, int);
int hcd(int, int, int);
int main()
{
int a, b, result;
printf("输入两个正整数:");
scanf("%d%d", &a, &b);
result = hcd(a, b, gcd(a, b));
printf("两个数的最小公倍数为:%d", result);
return 0;
}
int gcd(int a, int b, int c) //求最大公约数
{
int r;
do
{
r = a % b;
a = b;
b = r;
}while (r != 0);
//printf("%d", a);
return a;
}
int hcd(int a, int b, int c) //求最小公倍数
{
int d;
d = a * b / c;
return d;
}
思考:求最大公约数的程序如果用while()来写,可不可以写为
int gcd(int a, int b, int c) //求最大公约数
{
int r;
r = a % b;
while (r > 0);
{
r = a % b;
a = b;
b = r;
}
//printf("%d", a);
return a;
}
其实是不可以的,想想为什么,不能哪又如何修改?