C语言第七章重要知识总结

第七章 函数

7.1 分而治之与信息隐藏
  • 模块化程序设计体现了“分而治之”的思想,主要运用功能分解的方法来实现
  • 函数是C语言中模块化程序设计的最小单位

7.2 函数的定义
  • 函数是构成程序的基本模块
(1)标准库函数:如printf()、scanf()等。函数的行为也要符合ANSIC的定义,使用ANSI 的函数库,必须在程序的开头把该函数所在的头文件包含进来
(2)自定义函数:如果函数库不能满足程序设计者的编程需要,那么就需要自行编写函数来完成自己所需的功能
  • 函数名是函数的唯一标识,用于说明函数的功能。函数名标识符的命名规则与变量的命名规则形同
  • 函数体必须用一对花括号包围,这里的花括号{}是函数体的定界符。在函数体的内部定义的变量只能在函数体内访问,称为内部变量。函数头部参数表里的变量,称为形式参数,也是内部变量,只能在函数体内访问
  • 形象表是参数的入口
  • 若函数没有函数返回值,则需用void定义返回值的类型

7.3 向函数传递值和从函数返回值
  • main函数调用函数Fact()时,必须提供一个称为实际参数的表达式给被调用的函数
  • 调用其他函数的函数简称主调函数,被调用的函数简称为被调函数
  • 主调函数把实参的值复制给背调函数的形参的过程,称为参数传递
  • fact是一个函数名,为自定义函数,声明一个Fact函数,函数返回值是long int型,有一个参数,一般用于求阶乘
  • 有返回值的函数必须有return语句。return语句用于指明函数将返回给主调函数的值是什么。无论在函数的什么位置,只要执行到它,就立即返回到函数的调用者
  • 函数的返回值只能有一个,函数返回值的类型可以是除数组以外的任何类型。函数return语句可以有多个,但不表示函数可以有多个返回值
  • 函数对外界的影响也仅限于一个返回值和数组、指针类型的参数
  • 当函数需要返回值时,应确保函数中的所有控制分支都有返回值。函数没有返回值时应用void声明

7.4 函数的递归调用和递归函数
  • 递归:如果一个对象部分地由它自己组成或按它自己定义
  • 一般情况:由其自身定义的与原始问题类似的更小规模的子问题,它使递归过程持续进行
  • 基线情况:递归调用的最简形式,它是一个能够用来结束递归调用过程的条件
  • 递归调用:“在函数内直接或间接地自己调用自己”的函数调用,这样的函数称为递归函数
  • fib是斐波那契数列的意思。
著名的Fibonacci数列,定义如下
f(1)=1,f(2)=1,f(n)=f(n-1)+f(n-2),n>2
用文字来说,就是 斐波那契数列由 0 和 1 开始,之后的斐波那契系数就由之前的两数相加.首几个斐波那契系数是:
0,1,1,2,3,5,8,13,21

7.5 变量的作用域和储存类型
  • 语句块:程序中被花括号括起来的区域
  • 函数块是语句块,分支语句和循环体也是语句块
  • 变量的作用域的规则:每个变量仅在定义它的语句块(包含下级语句块)内有效,并拥有自己的存储空间
  • 全局变量:不在任何语句块内定义的变量
  • 全局变量的作用域为整个程序,即全局变量在程序的所有位置均有效
  • 局部变量:在除整个程序以外的其他语句块内定义的变量
  • 存储类型是指编译器为变量分配内存的方式,决定变量的生产期,决定变量何时“生”、何时“灭”
  • C语言的存储类型:自动变量 静态变量 外部变量 寄存器变量
(1)自动变量(也称动态局部变量) 格式:
auto 类型名 变量名;(auto可省略)
如果没有指定变量的类型,那么变量的储存类型就缺省为auto
在不同的并列语句块内可以定义同名变量,不会互相干扰,因为它们各自占据着不同的内存单元,并且有着不同的作用区域
swap函数一般是一个程序员自定义函数。通常是实现两个变量数值的交换
temp是一个变量。作用:是作为num1 和 num2两个变量互换值的中间变量,先将num1 的数存到temp中,然后在把num2 的数赋给num1,这样就不至于在num2赋值给num1时将num1 的数覆盖而使之消失,最后将temp的值赋给num2变量,这样就很准确的将两个变量值进行交换。
  • 在并列的语句块之间只能通过一些特殊通道传递数据,如函数参数、返回值,以及全局变量。因全局变量破坏了函数的封装性,所以不建议采用
  • 如果不希望形参值在函数内被修改,那么只要将关键字const放在形参前面,将形参声明为常量即可
  • 用const将形参声明为常量,可以有效防止形参值在函数内被修改
(2)静态变量 格式:
static 类型名 变量名;
  • func就是函数的入口地址
1.自动变量在定义时不会自动初始化,除非程序员在程序中显示指定初值,否则自动变量的值是不确定的,即乱码
2.自动变量在退出函数后,其分配的内存立即被释放
  • 静态变量是与程序“共存亡”的,而自动变量是与程序块“共存亡”的
  • 在函数内定义的静态变量称为静态局部变量,静态局部变量只能在定义它的函数内被访问,而在所有函数外定义的静态变量,称为静态全局变量,静态全局变量可以在定义它的文件内的任何地方被访问,但不能像非静态的全局变量那样被程序的其他文件所访问
  • 静态变量在退出函数后仍能保持到下一次进入函数时
(3)外部变量 格式:
external 类型名 变量名;
  • 外部变量保存在静态储存区内,在程序运行期间分配固定的储存单元,其生存期是整个程序的运行期。没有显式初始化的外部变量由编译程序自动初始化为0
(4)寄存器变量 格式:
register 类型名 变量名;
  • 寄存器是CPU内部的一种容量有限但速度极快的存储器
  • 现代编译器能自动优化程序,自动把普通变量优化为寄存器变量,并且可以忽略用户register指定,所以一般无须特别声明变量register

7.6 模块化程序设计
  • 模块分解的基本原则是:高聚合,低耦合,保证每个模块的相对独立性
高聚合:模块内部的联系越紧密越好,内聚性越强越好
低耦合:模块之间的联系越松散越好,模块之间交换那些为完成系统功能必须交换的信息
自底而上:先编写基本程序段,然后再扩大、补充和升级
自顶向下:自顶向上方法的逆方法
  • 逐步求精是一种自顶而下的程序分析和设计方法
  • 逐步求精技术可以理解为是一种由不断的自底向上修正所补充的自顶向下的程序设计方法
逐步求精步骤:
1.对实际问题进行全局性分析、决策,决定数学模型
2.确定程序的总体结构,将整个问题分解成若干相对独立的子问题
3.确定子问题的具体功能及其相互关系
4.在抽象的基础上,将各个子问题逐一精细化,直到能用确定的高级语言描述为止

7.7 本章扩充内容
  • 代码行:
(1)一行内只写一条语句,一行代码只定义一个变量。
(2)在定义变量的同时初始化该变量。
(3)if、for、while、do等语句各自占一行,分支或循环体内的语句一律用“{”和“}”括起来
  • 对齐与缩进
(1)程序的分界符“{”和“}”一般独占一行,且位于同一列,同时与引用它们的语句左对齐。
(2)采用梯形层次对应好各层次,同层次的代码在同层次的缩进层上,即位于同一层“{”和“}”之内的代码在“{”右边数格处左对齐。
(3)一般用设置为4个空格的Tab键缩进。
  • 空行及代码行内的空格
(1)在每个函数定义结束后加一空行,能起到使程序布局更加美观、整洁和清晰的作用。
(2)在一个函数体内,相邻的两组逻辑上密切相关的语句块之间加空行。
(3)关键字之后加空格。int、float等后至少加一个空格,if、for、while后面一般只加一个空格。
  • 长行拆分
  • 程序注释
(1)在重要的程序文件首部,对程序的功能、编程者、编程日期以及其他相关信息加以注释说明。
(2)在用户自定义函数的前面,对函数接口加以注释说明。
(3)在一些重要的语句行的右方,如在定义一些非通用的变量、函数调用、较长的多重嵌套的语句块结束处,加以注释说明。
(4)在一些重要的语句块的上方,尤其是在语义转折处,对代码的功能、原理进行解释。

你可能感兴趣的:(C语言笔记)