C语言学习(2)函数复习

主题1:函数
1.为什么要用函数
1.1.避免主函数变得庞杂,头绪不清,方便阅读和维护程序。
1.2.避免一个功能多次编写代码
2.模块化程序设计
1.1目的:简化程序设计的过程。
1.2好处:一次写好后,以后随用随调。
3.函数就是功能。每一个函数用来实现一个特定的功能。函数的名字应反映其代表的功能。
4.函数声明的作用是把有关函数的信息(函数名、函数类型、函数参数的个数与类型)通知编译系统,以便在编译系统对程序进行编译时,在进行到main函数调用该函数时知道它们是函数而不是变量或其他对象。此外还对调用函数的正确性进行检查(如类型、函数名、参数个数、参数类型等是否正确)。
5.一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位进行编译的,而不是以函数为单位进行编译的。
6.函数的定义
7.空函数的作用:为了扩展程序的功能。同时使程序的结构清楚,可读性好,现在结构中占用一个位置
8.定义函数的目的是为了调用此函数,以得到预期的结果。
9.形参:是在函数括号里定义的 实参:是传来的值
10.形参和实参间的数据传递
在调用函数过程中,系统会把实参的值传递给被调用函数的形参。或者说,形参从实参得到一个值。该值在函数调用期间有效,可以参加该函数的运算。
11.函数定义:无分号,有函数体 函数声明:有分号,没函数体
12.实参可以是常量、变量或表达式。实参与形参的类型应相同或者复制兼容。
13.在定义函数中指定的形参,在未出现函数调用时,它们并不占内存的存储单元。在发生函数调用时,函数的形参被临时分配内存单元,和实参的内存单元不同。因为值内存单元不同,所有形参值的改变不会影响到实参值。
14.函数的首行称为函数原型。201
15.函数声明中形参名可以省写,而只写形参的类型。
16.如果已在文件的开头(在所有函数之前),已对本文件中所调用的函数进行了声明,则在各函数中不必对其所调用的函数再作声明。
17.函数不可以嵌套定义,但可以嵌套调用
18.在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。这是C语言的一大特点。
19.一个递归的问题可以分“回溯”和“递推”两个阶段。209
20.n-1,1,3,2 1,3 n-1,2,1,3
主题2:数组作为函数参数
1.1数组元素作函数参数,向形参传递的是数组元素的值。单向传递。数组元素只可以做实参。
1.2数组名做函数参数,向形参传递的是数组第一个元素的地址。数组名既可以做实参也可以做形参。
1.3例子
1.3.1.在main函数中 声明函数1:float average(float array[10]);
                   调用语句:average(score);//已定义数组的数组名
                   函数1的定义:float average(float array[10]);//也可以不指定数组大小,只写一个方括号
13.2.实际上,在编译时把形参数组名处理为一个指针变量,用来接收一个地址。
13.3.当需要数组长度来控制循环次数时,可以把数组的实际长度从实参传递给在形参列表增加的一个形参里。
14.多维数组名作函数参数,形参的一维的大小可不去限定,但第二维的大小要指定,而且要和实参数组的第2维度。实参就是数组名。
15.局部变量:复合语句(分程序)内的变量,在外面无效,出了这个范围,系统就会把它占用的内存单元释放掉。
16.全部变量的有效范围从定义变量的位置开始到本源文件结束。作用是增加了函数间数据联系的渠道。
17.C程序设计中的全局变量名的第1个字母用大写表示,但非规定。
18.全局变量的缺点
18.1.在全部执行过程中都占用存储单元
18.2.降低了函数的可靠性和通用性,因为函数移植另一个文件时,全部变量也要移动,当全局变量和其他文件的变量同名时,就会出现问题。
18.3.在程序设计中,在划分模块时要求模块的内聚性强,与其他模块的耦合性弱。即不要把许多互不相干的功能放到一个模块中,与其他模块的相互影响要尽量少。
18.4.使用全局变量过多,让人们无法清楚判断出每个时间点这个变量的值。降低了程序的清晰性。
19.在C语言中,每一个变量和函数都有两个属性:数据类型和数据的存储类别。存储类别指的是数据在内存中存储的方式(如静态存储和动态存储)。
20.局部变量的存储类别
20.1.自动变量 auto 不写就是默认的auto 动态存储区
20.2.静态变量,在函数调用结束后,它并不释放,保留当前的值。静态存储区
21.解释
21.1.对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。如果定义时没赋初值,系统给赋值0或者‘\0’。
21.2对自动变量,系统自动赋的值是不确定的。因为实质上是给它分配的存储单元内容是不可知的。比如被上一个变量使用过但内容没清空。
21.3.静态局部变量只能被本函数引用,不能被其他函数引用。
21.4.静态局部变量会长久占用内存。
22.寄存器变量(register 变量)可以将局部变量的值存放在CPU中的寄存器中,提高执行效率,适用频繁适用该变量的情况下。
23.全局变量的存储类型
 
 
主题3:全局变量的存储类型。
1.1.作用是用来扩展外部变量的作用域
2.全局变量都是存放在静态存储区中的。因此他们的生存期是固定的,存在于程序的整个运行过程。
3.在一个文件内扩展外部变量的作用域。
3.1.情况:如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件结束。在定义点之前的函数不能引用该外部变量。
3.2.解决:用关键字 extern
3.3.例子:在定义点之前写 extern int A,B,C;这个时候在定义点之前就可以使用它了 。
4.将外部变量的作用域扩展到其他文件
4.1.情况:如果程序由多个源程序文件组成,那么在一个文件中想引用另一个文件中已定义的外部变量
4.2.解决:在任一个文件中定义外部变量A,而在另一个文件中用extern对该变量名作声明:extern A;这时的A的作用域就扩展到了这个文件中。
4.3.问题:怎样编译和运行包括多个文件的程序。
5.系统怎么区分3.1和3.2的情况
答:在编译时遇到extern时,先再本文件中找外部变量的定义,如果找到,就在本文件中扩展作用域;如果找不到,就在连接时从其他文件中找外部变量的定义。如果从其他文件中找到了,就将作用域扩展到本文件;如果再找不到,就按出错
6.将外部变量的作用域限制在本文件中处理。
6.1.情况:在程序设计中希望某些外部变量只限于被本文件引用,而不能被其他文件引用。
6.2.解决:在定义外部变量时加一个static声明。
6.3.使用:在本文件中声明:static int A ;这时在另一个文件在 extern A;将会出错。这叫做:静态外部变量。
6.4.意义:1)避免被其他文件误用2)这相当于把本文件的外部变量对外界“屏蔽”起来,从其他文件的角度看,这个静态外部变量时“看不见,不能被引用的”。
6.5.注意:存储类别关键字不能单独使用
7.为什么要讨论局部变量和全局变量?
7.1.这个问题的本质是变量的作用域,那么为什么会引出作用域
7.2.因为有这么一个问题:在一个函数中定义的变量,在其他函数中能否被引用?在不同位置定义的变量,在什么范围内有效???而这就涉及到了变量的作用域。
8.存储类别小结
8.1。对一个数据的定义:要利用相关的关键字指定数据类型和存储类型这两种属性。用extern声明已定义的外部变量。
9.变量的三个角度:1)作用域[空间]2)生存期[时间]3)存放的位置 。其中1和2是变量的两个属性,有联系,但意思不同。
10.变量的声明和定义
10.1.本质都是声明,定义是一种特殊的声明,特殊在建立了存储空间。
10.2.只是为了叙述方面:才有了声明和定义看似不同的说法。1)把建立存储空间的声明称定义,不建立的,称为声明。
2)即定义性声明和引用性声明;前者简称定义后着简称声明;
10.3.所谓声明,其作用是声明该变量是一个已在其他地方已定义的外部变量,仅仅是为了扩展该变量的作用范围而作的“声明”。
 
主题4:内部函数和外部函数
1.1.引入:出于和变量相同的分析。根据函数能否被其他源文件调用,将函数区分为内部函数和外部函数。
2.内部函数 本文件
2.1.定义:static 类型名 函数名(形参表);只能被本文件使用
3.外部函数 其他文件
3.1.函数首部:extern int fun(int a,intb)表示是在其他文件中定义的外部函数
3.2.C语言规定,不写extern 默认是外部函数 233
 
主题5:对函数的声明用extern能够在本文件中调用在其他文件中定义的函数,或者说把该函数的作用域扩展到本文件。
2.函数的首行叫做函数的原型。extern声明的形式就是在函数原型基础上加关键字extern
3.函数的本质是外部的,于是extern可以省略。
4.由2,3知道用函数原型就能够把函数的作用域扩展到定义该函数的文件之外(不必用extern)。函数原型通知编译系统:该函数在本文件中稍后定义,或者另一个文件中定义。
5.#include指令的应用就是利用函数原型扩展函数作用域。因为它所指定的头文件里包含了输入输出等相关函数的原型和其他相关信息。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。