一、函数定义1、难点: 思想自上而下 逐步拆解将大问题拆成小问题 小问题拆成更小问题 ---- 更小的问题 往往都对应一个简单独立的功能C语言提供了实现 功能的 语法:2、函数 ---function//一个函数就是来完成一个功能的 独立 单一//getchar/putchar//scanf/printf//rand()//strcpy//strcmp//strcat3、说明1、一个 C 程序由一个或多个程序模块组成每一个程序模块作为一个源程序文件。2、一个源程序文件由一个或多个函数以及其他有关内容如命令行、数据定义等 组成。3、C 程序的执行是从 main 函数开始的。4、从用户使用的角度看函数有两种1标准函数2用户自己定义的函数5、所有函数都是平行的即在定义函数时是分别进行的是互相独立的即函数不能嵌套定义。6、从函数的形式看函数分两类1有参函数2无参函数7、main函数 称为 程序的入口函数8、 函数可以实现嵌套调用9、 所有程序的运行都在内存上运行4、函数模型1、语法:类型标识符 函数名(形式参数){函数体//声明部分//语句部分}(1)类型标识符 --- 数据类型 ---反映的是 函数带出来的结果的类型注意: 不能是数组类型(2)函数名 --- 标识符命名规则和变量名命名规则一致函数名 一般 反映函数功能(3)形式参数 --- 函数处理数据模型 (输入-处理-输出)形式参数 表示函数要处理的数据数据来源 实际给到的参数 (实参)(4)函数体 --- 完成函数功能的那部分代码2、使用步骤step1: 先确定函数名 --- 功能相关addsumstep2: 从函数模型角度 (输入数据-处理数据-带出结果)考虑 要处理哪些数据(个数)哪种类型的数据(数据类型eg:两个整数求和 ---确定形参变量 的个数 以及 每个变量的类型形参语法:格式: 数据类型 形参变量名1, 数据类型 形参变量名2, 数据类型 形参变量名3,......int a,int b注意:每个形参变量都需要说明类型step3: 处理数据---函数核心功能代码result abstep4: 返回值 //返回值类型 相关此时 函数返回值的类型 就是整型补充:return (表达式);eg: return result;3、函数调用方式:1.函数调用语句2.函数调用表达式3.作函数调用的实参5、注意1.实参 和 形参注意:1. 每个形参变量都需要说明类型2. 实参和形参 做到 个数相同 类型匹配 一一对应2.返回值类型如果不写 默认是int类型3.返回类型返回值类型 与 返回结果的类型不一致时以返回值类型设计为准4.函数定义的位置可以放在main函数之前 --- 同时起到定义和声明的效果可以放在main函数之后 --- 需要在使用之前做函数的声明5. 函数声明把函数头复制一份 加上 ; //函数调用语句打印mp3菜单void printMenu(void){printf(----MP3-----\n);printf(Play\n);printf(Next\n)return ; //如果返回值类型为void 此时可以有return 但是return后面什么值都不要写}5.如果 函数不需要 传入数据 此时形参 设计为 void (空类型)返回值 如果没有此时也设计为 void6、函数的好处1.降低重复代码的编写提高编程效率2.实现了程序的模块化 提高程序可靠性和可维护性二、扩充1、栈栈 --- 数据结构 --- 数据组织方式 ----本身是一块内存空间程序 代码 数据1、特点先进后出 FILO入栈出栈局部变量 都放在栈上栈上变量特点 --- 自动申请自动释放栈 空间 在linux系统上 默认8M 但是可以修改2、C语言程序运行之后 在内存中布局2、堆区特点:特别大手动申请手动释放32位系统4G 操作系统 大约占1G32位 一般 数据总线宽度地址总线宽度0000 0000 0000 0000 0000 0000 0000 00001024 2^101024*1024*10241024字节 1Kb * 1024 1MB * 1024 1GB三、递归1、定义函数嵌套调用:自己调用自己 --- 递归func1(){func1(); //直接递归}-------------------------------------------func2() //间接递归{func1();}func1(){func2();}--------------------------------------------func1(){123func2();}2、递归1、递归:1.自己调用自己2.递归是一种特殊的循环forwhiledo-while2、效率从效率上来说 for、while、do-while 效率高有些时候 有些问题的解决用递归的方式 更容易实现3.递归解决问题的思路 ---函数调用倒着来思考的解决问题n看看 问题n-1能不能解决还需要知道 问题n和问题n-1直接递推关系实现递归:1.问题n 和 问题n-1之间递推关系2.递归结束条件4. 注意递归的深度 不要太深太深 可能栈空间不够用了导致段错误四、数组作为函数参数1、整型一维数组 作为函数参数1、 形参//形式上 ---数组形式printArray(int a[],int len) //需要一个数组形式的形参 和 数组长度的形参//本质上 ---指针变量(编译器理解的本质)printArray(int *a,int len) //指针变量 用来接收数组首元素的地址2、 实参printArray(数组名,数组长度) //实参传递 要传 数组名 和 数组长度//数组名 从代表值的角度 代表的是 首元素的地址2、字符型一维数组1.字符型一维数组 --- 用来存放一个字符串//语法点:字符型 一维数组 做函数参数形参 数组形式 //不需要数组长度 ---字符串本身有结束标志实参 数组名3、二维数组作为函数参数整型:int a[3][4] {1,2,3,4,5,6,7,8,9,10,11,12};void printArray(int a[3][4]) //形参 可以写成数组的形式void printArray(int(*a)[4]) //本质编译器还是当作指针看的//二维数组的本质 --- 一维数组的一维数组void printArray(int[4] a[3]) //形参 可以写成数组的形式void printArray(int[4] *a) //本质编译器还是当作指针看的注意:二维数组作为函数参数形参 二维数组形式 行数的变量实参 二维数组数组名 行数的值4、二维字符型数组作为函数参数二维字符型数组一维字符型数组----存放一个字符串二维字符型数组----存放多个字符串字符型二维数组做 函数参数 与 整型二维数组作为函数参数 --写法一致形参 二维数组形式 行数的变量实参 二维数组数组名 行数的值五、标识符的作用域 与 可见性问题1、说明:1.变量名2.函数名3.数组名2、作用域:发挥作用区域{} //C语言中 一个 {} 就是一个作用域作用域:局部作用域只要是在{} 范围内的 都是局部作用域局部作用域定义的变量 --- 局部变量全局作用域不在任何一个 {} 范围内的是全局作用域全局作用域定义的变量 --- 全局变量3、可见性:站在程序角度看程序运行到某一刻时哪些标识符可见(可用)标识符的可见性的规则:1.先定义后使用2.同一作用域中不能有同名标识符3.在不同的作用域同名标识符相互之间没有影响4.如果是不同的作用域但是作用域之间存在嵌套关系则内层的作用域的同名标识符会屏蔽外层的作用域的同名标识符。 (就近原则)4、C语言5个区:栈堆全局区(静态区)字符串常量区代码区5、存储类别关键字1、定义变量main(){int a 10; //局部变量 --- 定义变量 意味着开空间 --- 空间开在哪里}2、指定关键字 来表示 数据可以放到来auto int a 10; //auto 就表示这个变量空间开在栈上static int a 10; //static 静态的 表示将变量 空间 开在 静态区//静态区变量的特点:// 1.只会被初始化一次// 2.不能用变量初始化// 全局变量也不能用变量初始化 --- 全局变量和静态变量都是放在全局区(静态区)// 3.静态局部变量的值具有继承性3、从变量角度看1、空间上:局部变量全局变量2、时间上:生命周期局部变量 生命周期 ---定义定义处开始到所在作用域结束//程序执行到定义时变量创建程序执行到 作用域结束 变量销毁全局变量 静态变量 的生命周期 ---程序运行开始后就存在直到整个程序结束才销毁./a.out (整个程序的生命周期)4、registerregister int a 10; //register --- 寄存器//告诉编译器 将变量a 存放到 寄存器中//关键字 ---- 建议性关键字// 如果是register修饰的变量 ,不能做 (取地址)运算原因 --- 内存空间可以取地址寄存器取不了5、计算机的存储体系寄存器cache内存硬盘从上到下容量越来越大价格越来越便宜速度原来越慢CPU 内存 硬盘32G 1T16G6、externextern int a; //extern --- 外部的意思 --- extern相当于是扩展了变量的作用域//相当于将a的作用域扩展到本文件//修饰表示变量存储在别的文件中要使用式到别的文件中寻找。//extern 和 static//static 也可以修饰全局变量,表示 将该变量的作用域限定为本文件别的文件中无法引用(extern int a;) ----static修饰全局变量 --- 限定了作用域也可以修饰函数//多文件编程作用和修饰全局变量作用相同用途:分模块好多个函数全局变量 int cnt;函数7、static 保护数据作用