动手学习C语言--S8函数调用

特点

分类:标准库函数和自定义函数
一个C程序,有且只有一个main()主函数;
C程序总是从main()函数开始执行,在main()函数中结束;
自定义函数必须先申明再调用,即定义完成后,在头文件下面申明;可以嵌套调用;

fn(){printf(“To be developed…”);} //定义空函数–可无限扩展更多功能

函数的作用和特点

1、分解大任务,将大程序功能划分成小程序模块;
2、利用现有成果,函数更符合结构化的系统程序设计;
3、函数可增加系统程序的可读性,功能特定或可维护性;
4、函数使程序相对独立,功能特定,便于创新与调用;
5、函数的利用,减少了程序设计的复杂性;
6、使用函数,提高了整个程序的可靠性;
7、避免程序算法实现的重复编程
8、易于系统级程序开发、维护和功能扩充
9、更适合自上向下的软件系统开发和功能模块逐步分解等系统设计思想;

系统标准库函数

常用标准库函数:
在这里插入图片描述

自定义函数

[ertern/static] TypeName FunName(形参,…){
// 函数说明
语句;

}
方括号内为可选项,如果前面省略,则表示为auto存储类型的整型函数;如果后面省略,则表示该函数调用时无需传参;

自定义函数与函数类型

函数类型-是由函数调用的返回值决定的;函数被调用执行完后,向调用函数的调用点。返回一个执行结果–即为函数返回值;
函数返回值—是通过函数中的 return语句返回获得的;
形式结构为:
return 表达式;//不是复制语句,是表达式
或者
return (表达式);

例子:

float sum(float a ,float b){
	float ans;
	ans=a+b;
	
	return ans;
}

函数的参数定义及参数传递

形参作用:实现函数调用时数据传递功能: 实参---->形参;
1、形参只有在函数被调用时时:才会被分配内存单元;在调用结束后,立即释放所分配的内存空间。形参只在函数内部有效;
2、实参变量无论是何种数据类型,必须有确定的实际值;才能再函数调用时,对应传递被调参数的形参变量;
3、实参与形参在数量、类型和顺序上,必须严格一一对应,否则会产生“类型不匹配”的错误;
4、函数调用过程中的数据传送石单向的。即只能把实参值传送给形参变量。而不能反向传递;
在函数调用过程中,形参值发生改变,实参值也不会有任何变化,即使是同名变量也是如此

扫描二维码关注公众号,回复: 9815047 查看本文章

数组名作为函数参数

实参数组首地址赋予形参数组,共同拥有同一个数组连续存储空间;
数组名作为函数参数应注意:
1、形参数组与实参数组数据类型一致;
2、形式数组与实参数组的长度可以不相同;
3、在函数形参表中,可以不给出形参数组的长度
// 将数组元素逆序存放
// 将数组元素逆序存放
// 形参传递的是指针名,可以操作改变实际参数变量值

#include "stdio.h"
#include "string.h"

void opposite(char str[]);

void main(){
	char str[60];
	int length,i;
	
	printf("输入字符:\n");

	gets(str);
	length=strlen(str);

	printf("the length is %d \n",length);

	// 输出变换前字符
	puts("输出变换前字符:");

	for(i=0;i<length;i++){
		printf("%c",str[i]);
	}
	printf("\n");
	// 变换字符
	opposite(str);  // 对应函数数组形参名怎么使用

	puts("输出变换后的:\n");

	for(i=0;i<length;i++){
		printf("%c",str[i]);
	
	}
	printf("\n");

}

// 数组名传递的是内存指针,这个是指向的同一块内存,所以形参操作的是实际内存值,可以改变实参的值

void opposite(char str[]){      // 注意怎么定义数组的形参名
	int i;
	char c;
	int n=strlen(str);

	// 逆序存放
	for(i=0;i<n/2;i++){
		c=str[i];
		str[i]=str[n-i-1];
		str[n-i-1]=c;
	
	}


}

函数的调用

调用各类函数时注意
1、被调用函数必须是已经存在的库函数或者自定义函数;
2、调用库函数,必须使用#include 命令,将对用头文件包含在源程序中;
3、调用自定义函数,在调用之前先在头文件下进行申明,函数定义在主函数体最后面;
为了代码的可读性-不要随意进行省略;

所有自定义函数之间是平行关系,不存在由于定义位置的前后而有上下级关系,可以互相嵌套调用,但是不允许嵌套定义

// 实现数组的输入,逆序排放和输出

**分析在函数相互嵌套调用的过程中,应该注意在什么情况下,可能会出现函数的代用相互等待的“死锁”状态;

函数的递归调用

递归函数特点是在函数内部直接或者间接调用函数自身;
直接调用与间接调用
在这里插入图片描述

定义递归函数两个条件:1、递归算法 2、终止条件
递归函数求解过程:回推和递推 两个过程;
在这里插入图片描述

函数变量的存储与作用域 //定义位置 作用范围 生命期 显性和隐匿

变量作用域作用在定义的对应的大括号内;

动态存储变量和静态存储变量

动态存储变量:是在程序执行过程中,调用它时才分配存储单元,调用结束后,立即释放;
静态存储变量:通常是在变量定义时就分配存储单元,并一直保持不变,直至整个程序结束;
在这里插入图片描述

Auto型动态存储变量
**C语言规定任何函数内定义变量时,未加存储类型说明符时的变量均视为Auto行自动变量;是局部变量
特点:
1、作用域:仅限于定义该变量的函数体内;
2、动态存储方式:属于动态存储方式,只有在使用时才开始其生存期;
3、由于上述两点:不同的函数体内部允许使用同名变量;
Extern 变量:
是全全局变量。主要用于多个 .C程序源代码联调调用时使用;
Static 静态变量
分为局部变量和全局变量
1、静态全局变量
static 静态局部变量的生存期为整个.C源程序执行器。其作用域与Auto自动变量相同;
但是推出这个函数后,该变量继续存在,并且保留上一次的变量值,就是屏蔽掉初始化操作。但这个值不能被常规引用。只有下一次函数被调用时,才会自动使用这个static静态局部变量值。
在这里插入图片描述

// 比较动态与静态 局部变量的变化
// 分析比较函数调用时,动态局部变量与静态局部变量的变化

#include"stdio.h"

int fn();

void main(){
	int i;
	for(i=0;i<5;i++){
		fn();
	}

}

int fn(){
	int auto_v =0;
	static int static_v = 0; // 静态局部变量,每次调用保留上次调用值

	static int n=1; // 静态局部变量
	printf("fn(%d):auto_v is %d,static_v is %d \n",n,auto_v,static_v);
	auto_v++;
	static_v++;
	n++;
	return;


}

Register 型寄存器变量
register型寄存器变量常用于循环次数较多的循环变量等频繁访问变量的计算;提高运算速度而已;

全局函数和局部函数

全局函数和局部函数,也成外部函数和内部函数。其内外之分是对所存在的.c源程序操作范围而言;
如果省略了存储类型extern说明符,则系统会默认为是ertern全局函数,也成外部函数,可以为其他外部.C源文件声明和调用;外部函数是系统调试调用的程序级函数。
具体案列:
在这里插入图片描述
ertern:两个作用:1、是说明引用外部文件的变量或者函数 2、定义本函数或者变量可为外部引用(可以省略);
static 定义的变量不能为外部文件引用,只在本文件内有效;

发布了39 篇原创文章 · 获赞 3 · 访问量 2520

猜你喜欢

转载自blog.csdn.net/li_kin/article/details/104705368