目录
序言:
函数的定义:
函数的声明:
函数的调用:
函数的嵌套调用:
函数的递归调用:
数组作为函数参数传递:
局部变量和全局变量:
静态变量和动态变量:
■. 啥是函数?
所谓“函数”是从英文funtion翻译过来的,其意思既是“函数”,也是“功能”。
计算机里的函数侧重于后者--功能。
从本质上来说,函数就是用来完成一定功能的,是把实现功能的代码封装起来,然后给这些打包起来的代码取个名字。
每一个函数用来实现一个特定的功能,函数的名字对应其代表的功能。
■. 为啥使用函数?
为了提高代码的复用性,提高程序的可读性,在使用过程中比较灵活,更加方便了程序代码的编写。
基本格式:
数据类型 函数名(参数列表)
{
函数体; // 函数的功能
//return语句 // 函数的返回值
}
■. 说明
C语言中要求,在程序中用到的所有函数,必须“先定义,后使用”。
定义函数应包括以下几个内容:
(1) 指定函数的类型,即函数返回值的类型。
(2) 指定函数的名字,以便后续按名调用。
(3) 指定函数的数据类型及参数个数,以便在调用函数时向它们传递数据(无参函数不需要)。
(4) 指定函数所完成的功能,也就是函数要完成怎样的操作,函数的功能写在函数体中。
(它说明了函数是做什么的)
■. 定义类型:
1. 定义无参数无返回值函数:
void 函数名() // 或者void 函数名(void)
{
函数体
}
2. 定义有参数无返回值函数:
void 函数名(参数1,参数2,......)
{
函数体
}
3. 定义无参数有返回值函数:
类型名 函数名()
{
函数体 // 函数体最后有return语句
}
4. 定义有参数有返回值函数:
类型名 函数名(参数1,参数2,......)
{
函数体 // 函数体最后有return语句
}
void为空类型,一般用于函数没有返回值时给定函数的类型。
例如:
void weixiao() // 或者 void weixiao(void)
{
printf("hello world\n");
}
int main()
{
weixiao();
return 0;
}
附加:
比较两数的大小:
int MAX(int x, int y) //求两个数中较大数的函数
{
int z = x > y ? x : y;
return z;
}
int main()
{
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", MAX(a, b));
return 0;
}
或
void MAX(int x, int y) //输出较大数的函数
{
int z = x > y ? x : y;
printf("两数中较大数为:%d\n", z);
}
int main()
{
int a, b;
scanf("%d%d", &a, &b);
MAX(a, b);
return 0;
}
或
int MAX(int x, int y) // “准确“判断较大数
{
if (x == y)
{
return printf("两数相等都为:%d\n", x);
}
int z = x > y ? x : y;
return printf("两数中较大数为:%d\n", z);
}
int main()
{
int a, b;
scanf("%d%d", &a, &b);
MAX(a, b);
return 0;
}
补充:
参数列表:函数的参数,可以没有,也可以有一个或者多个。
函数体:实现函数功能的代码,用于完成具体的操作。
return:函数的返回值语句,用于返回函数体执行的结果;
返回值可以没有,如果有有且仅有一个;
函数体返回值的类型需要与函数的类型保持一致;
(函数类型设置为怎样的类型,返回值语句中就应返回相应类型的数据)
(返回值语句中返回了什么类型的数据,函数类型就为相应的类型)
函数名在理论上可以使用中文,但目前不推荐。
在现有技术中,因无法预知编译器解析可能产生的问题,以及代码文件的文本编辑、c++标准的自适应等种种问题,就可能造成编译或运行错误。
所以,我们的变量名、函数名、对象名,甚至文件名和路径目前暂且都推荐使用英文。
函数的定义只能放在主函数前面或后面,
(主函数内定义函数会报错:本地函数定义是非法的)
______________
一般函数先定义后使用,
若函数的使用在定义之前,就需要在使用之前进行函数的声明,然后补上定义。
如果函数先使用后定义且不事先进行函数声明,会报错:"该函数名":找不到标识符
基本格式:
数据类型 函数名 (参数列表) ;
例如:
#include
int main()
{
int a, b;
scanf("%d%d", &a, &b);
int MAX(int c, int d); // 函数MAX的声明
MAX(a, b);
return 0;
}
int MAX(int x, int y)
{
if (x == y)
{
return printf("两数相等都为:%d\n", x);
}
int z = x > y ? x : y;
return printf("两数中较大数为:%d\n", z);
}
同一函数可进行多次声明,但只能进行一次定义。
如果定义两次及以上,报错:函数"数据类型 函数名(参数列表)"已有主体
______________
即,使用函数
基本格式:
函数名(参数列表);
主调函数:调用其他函数的函数
被调函数:被其他函数调用的函数
C语言中,main()就为主调函数。
■. 函数参数:
在调用有参函数时,需进行参数的传递。
实参:实际参数,是主调函数中用于给被调用函数参数传递数据的参数。
形参:形式参数,是被调函数中用于接收主调函数参数传递过来的数据的参数。
也称为虚拟参数
■. 实参和形参之间的数据传递:
在调用函数的过程中,系统会把实参的值传递给被调函数的形参。
(即形参从实参得到一个值,“复制”操作)
■. 函数调用过程中,以下几点需注意:
(1)实参可以是常量、变量或表达式。(后二者均已被赋值)
(2)实参和形参的数据类型应相同或赋值兼容,
且实参和形参在各自参数列表中的位置一 一对应。
(3)函数遇到return返回语句过后,不再继续执行return之后的语句(return作用域内)。
(4)形参只参与其所在函数的函数体中的运算,不能用于其他函数中;
且未被调用函数时,形参不占用存储单元;
开始被调用时才给形参开辟存储空间;
函数调用结束后,形参的存储单元会被释放。
(5)函数的形参和实参是两个不同的变量,
一般请况下,形参值的改变不影响实参的值,
除非函数参数的传递类型为地址传递(引用传递)。
___________________
函数的定义是相互平行独立的,也就是说,一个函数内不能再定义另一个函数(不能嵌套定义)。
但是,
函数可以嵌套调用,即在一个函数执行的过程中,可以调用另一个函数,诸如此类。
在调用一个函数的过程中又直接或间接的调用此函数本身,称为函数的递归调用。
递归的函数中应有结束递归的条件,否则会和死循环一样,陷入无限递归,称为死递归。
例1:函数递归输出整数10~0
#include
void fun1(int n)
{
printf("%d\n", n);
if (n >0)
fun1(n - 1); // 函数的递归调用
}
int main()
{
fun1(10);
return 0;
}
例2:函数递归输出整型0~10
#include
void fun1(int n)
{
static int i = 0;
printf("%d\n",i++);
if (i<=n)
fun1(n);
}
int main()
{
fun1(10);
return 0;
}
例3:函数递归输出整型数组的逆序
#include
void int_arr1_print(int arr1[], int n) //函数名说明函数的功能
{
printf("%d\n", arr1[n - 1]);
if (n-1 > 0)
int_arr1_print(arr1, n - 1);
}
int main()
{
int arr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int_arr1_print(arr1, 10);
return 0;
}
例4:函数递归输出整型数组的正序
#include
void int_arr1_print(int arr1[], int n) // 形参arr1[]代表地址
{
static int i = 0;
printf("%d\n", arr1[i]);
if (++i
___________________________
数组作为函数参数传递:
数组名为该数组的首地址
因此,
这个数组作为函数参数传递实际上是引用传递,传递的是地址,
形参的改变会影响到实参。
即,
在调用函数中,改变形参数组元素的值,实参数组元素的值会改变。
例如:
#include
void gaibian(int arr2[],int n)
{
static int i = 0;
if (i < n)
{
arr2[i] += 1;
printf("%d\t", arr2[i++]);
gaibian(arr2, n);
}
else
putchar('\n');
}
int main()
{
int arr2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
printf("原来的实参数据为:\n");
for (int j = 0; j < 10; j++) // 输出arr2数组数据(原始数据)
{
printf("%d\t", arr2[j]);
}
putchar('\n');
gaibian(arr2, 10); // 调用函数
printf("现在的实参数据为:\n");
for (int j = 0; j < 10; j++) // 输出arr2数组数据(当下数据)
{
printf("%d\t", arr2[j]);
}
putchar('\n');
return 0;
}
_________________________
局部变量和全局变量:
按照作用域的不同,可将变量分为局部变量和全局变量。
■. 局部变量
局部变量的作用范围只在一定范围内有效(作用域和生命周期有限)
局部变量的定义:
(1)在函数开头定义
(2)在函数内部的复合语句中定义
■. 全局变量
全局变量的作用范围相对于局部变量来说更为广泛,也称为外部变量(作用域和生命周期为全局)
在定义完成后都能使用,到程序结束时才释放。
全局变量的定义:
(1)在函数外部定义(一般在预处理指令后)。
——————————————
静态变量和动态变量:
■. 动态变量
程序中所定义的变量默认为时动态变量(auto)。
■. 静态变量
(1)在定义变量前加一个关键字static,即可定义一个静态变量(作用域为局部,生命周期为全局)。
(2)细分为静态局部变量和静态全局变量
(3)静态变量在一个程序中只会被定义和初始化一次(当再次执行到定义语句时,其值不会被重置(初始化),会保留上次改变的值)。
例1:
#include
void fun2() // 循环输出0~无穷
{
static int i = 0; // 静态局部变量
printf("%d\n", i++);
fun2();
}
int main()
{
fun2();
return 0;
}
例2:
#include
static int i = 0; // 静态全局变量
void fun2()
{
printf("%d\n", i++);
if(i==22)printf("最后下一次:\n");
if(i<=22)fun2();
}
int main()
{
fun2();
printf("%d\n", i); // i 可用
return 0;
}
或
#include
static int a = 0; // 静态全局变量
void fun4()
{
printf("%d\n", a++);
}
int main()
{
while (1)
{
fun4();
if (a > 22) // a 可用
break;
}
return 0;
}
_____________________#
你可能感兴趣的:(1:C语言,c语言)