目录

  • 1 第一章 C语言简介
    • 1.1 C语言前世今生
    • 1.2 主流开发环境介绍
    • 1.3 第一个小程序解析
    • 1.4 常见编译错误
    • 1.5 章节知识点小结
  • 2 算法基础
    • 2.1 算法-程序的灵魂
    • 2.2 算法的描述-流程图
  • 3 数据类型与运算符
    • 3.1 数据描述
    • 3.2 运算符和表达式1
    • 3.3 运算符和表达式2
    • 3.4 章节知识点小结
  • 4 顺序结构程序设计
    • 4.1 输入和输出
    • 4.2 顺序结构程序设计
    • 4.3 章节知识点小结
  • 5 选择结构程序设计
    • 5.1 关系运算符和关系表达式
    • 5.2 逻辑运算符和逻辑表达式
    • 5.3 if语句
    • 5.4 条件运算符
    • 5.5 switch语句
    • 5.6 章节知识点小结
  • 6 循环结构程序设计
    • 6.1 while循环结构
    • 6.2 do_while循环结构
    • 6.3 for循环结构
    • 6.4 循环的嵌套
    • 6.5 break语句和continue语句
    • 6.6 章节知识点小结
  • 7 数组
    • 7.1 一维数组
    • 7.2 二维数组
    • 7.3 字符数组
    • 7.4 章节知识点小结
  • 8 函数
    • 8.1 子程序设计
    • 8.2 函数定义
    • 8.3 函数的调用
    • 8.4 局部变量和全局变量
    • 8.5 参数传递
    • 8.6 函数递归调用
    • 8.7 章节知识点小结
  • 9 指针
    • 9.1 指针的基本概念
    • 9.2 指针变量的定义及引用
    • 9.3 通过指针引用数组元素
    • 9.4 指向多维数组的指针和指针变量
    • 9.5 用指向数组的指针作函数参数
    • 9.6 指针与字符串
    • 9.7 函数指针和指针函数
    • 9.8 章节知识点小结
  • 10 用户自己建立数据类型
    • 10.1 定义和使用结构体变量
    • 10.2 使用结构体数组
    • 10.3 结构体指针
    • 10.4 章节知识点小结
  • 11 编译预处理
    • 11.1 宏定义预处理
    • 11.2 文件包含预处理
    • 11.3 条件编译预处理
    • 11.4 章节知识点小结
  • 12 文件
    • 12.1 文件的基本知识
    • 12.2 文件的基本操作
    • 12.3 章节知识点小结
子程序设计


子程序(routines)是为实现一个特定功能而编写的一个可被调用的方法(method)、函数(function)或过程(procedure)。如Java中的方法,C/C++里的函数。现代编程语言如Java、C++、VB、JavaScript、Ruby等都同时支持函数和过程。

一般认为函数指具有返回值的子程序,过程指没有返回值的子程序。C++中把所有子程序成为函数,其实那些返回值为void的函数在语义上也是过程。函数与过程的区别更多是语义上的区别,而不是语法的区别。

语言纯化论者认为一个函数应该只有一个返回值,这和数学函数一样。即函数只接受输入(参数),通过参数运算返回结果。 除此之外的效果被称为函数的副作用,比如修改全局变量。

好的子程序需要遵循以下原则

  • 高内聚

  • 好的命名

  • 长度适中

  • 合理的参数

 

一、高内聚性

内聚性是计算机科学里很重要的一个概念,由Larry Konstantin在1974年的一篇论文提出。它由分为以下

1. 功能内聚(Functional cohesion,最高)

最好最强的一种内聚性,即一个子程序仅执行一个操作,有的书也称“只做一件事,做好一件事”。这种子程序执行的操作与其名称多数是相符的,如sum执行相加,deletePage删除页面。

2. 顺序上的内聚(Sequential cohesion)

指子程序内需按特定顺序执行操作,这些步骤需要共享数据,且在全部执行后才完成子程序的完整功能。比如需要先计算A,再使用A计算B,接着取B计算C。

3. 通信上的内聚(Communicational cohesion)

是指子程序不同操作使用了相同数据,但不存在任何联系。

4. 临时的内聚性(Temporal cohesion)

是指含有一些因为需要同时执行才放到一起的操作的子程序。

5. 逻辑上的内聚性(Logical cohesion)

是指若干操作被放入同一个程序中,通过传入的控制标志选择执行其中的一项操作。

6. 偶热的内聚性(Coincidental cohesion 最低)

指子程序中各个操作直接没有可以看到的内联,也称为“无内聚性”或“混乱的内聚性”。

二、好的命名

好的命名能清晰的描述子程序所做的一切。以下是一些命名注意事项

1. 描述子程序所完成的功能

2. 避免使用无意义的、模拟或表达不清的词

3. 不要仅通过数字来区分不同的子程序名

4. 根据需要确定子程序名字的长度

5. 对返回值要有所描述

6. 一般是动词+名词形式

7. 使用对仗词,如add/remove, begin/end, first/last, get/put, up/down/, show/hide, open/close。

 

三、长度适中

“子程序/函数的第一要素就是短小,第二条规则还是短小”,鲍勃大叔如此说。理论上认为子程序的长度最大长度通常是一屏代码,大约50-150行。

一项对子程序的研究发现,平均100-150行代码的子程序需要修改的几率最低(Lind and Vairavan 1989)。

四、合理的参数

子程序之间的接口是程序中最易出错的地方,Basili和Perrricone所做的一项研究发现程序中39%的错误都是属于内部接口错误。也就是子程序间互相通信时所发生的错误。应该按以下原则处理

1. 按照输入-修改-输出的顺序排列参数。不要随机地按字母顺序排列参数,而应先列出输入参数,然后是即作为输入又作为输出的参数,最后是输出的参数。比如Ada就要专门的关键字in,out。

2. 如果几个子程序都用了类似的一些参数,应该让这些参数的排列顺序一致。

3. 使用所有的参数,既然定义了该参数就应该使用它,如果不用它就应该删掉它。

4. 把状态或出错的变量放在后面,状态和那些用于指示发生错误的变量应放在参数表最后。它们只是程序的附属功能且只用于输出的参数。

5. 不要把子程序的参数用于工作变量

6. 子程序的参数个数限制在7个以内。鲍勃大叔说的更极端 “最理想的参数数量是零,其次是单参数函数,再次是双参数函数,应尽量避免三参数函数”。心理学研究发现,人类很难记住超过7个单位的信息。这一发现已应用在各个领域。