《C程序设计语言》笔记 (四) 函数与程序结构

 

目录

4.1  函数的基本知识
4.2  返回非整型值的函数
4.3  外部变量
4.4  作用域规则
4.5  头文件
4.6  静态变量
4.7  寄存器变量
4.8  程序块结构
4.9  初始化
4.10 递归
4.11 C预处理器
     文件包含
     宏替换
     条件包含

4.1 函数的基本知识 

函数可以把大的计算任务分解成若干个较小的任务

C语言在设计中考虑了函数的高效性与易用性这两个因素

程序可以看成是变量定义和函数定义的集合

函数之间的通信可以通过参数、函数返回值以及外部变量进行

函数在源文件中出现的次序可以是任意的,只要保证一个函数不被分离到多个文件中

  

4.3 外部变量

C语言程序可以看成是由一系列的外部对象构成,这些外部对象可能是变量或函数

external与internal是相对的,internal用于描述定义在函数内部的函数参数及变量

外部变量定义在函数之外,因此可以在许多函数中使用

由于C语言不允许在一个函数中定义其他函数,因此函数本身是"外部的"

通过同一个名字对外部变量的所有引用实际上都是引用同一个对象

外部变量的用途还表现在它们与内部变量相比具有更大的作用域和更长的生存期

自动变量只能在函数内部使用,从其所在的函数被调用时开始存在,在函数退出时变量也将消失

外部变量是永久存在的,它们的值在一次函数调用到下一次函数调用之间保持不变

  

4.4 作用域规则

构成C语言程序的函数与外部变量可以分开进行编译

一个程序可以存放在几个文件中,原先已编译过的函数可以从库中进行加载

名字的作用域指的是程序中可以使用该名字的部分

对于在函数开关声明的自动变量来说,其作用域是声明该变量名的函数

不同函数中声明的具有相同名字的各个局部变量之间没有任何关系

函数的参数也是一样的,实际上可买将它看作是局部变量

外部变量或函数的作用域从声明它的地方开始,到其所在文件的末尾结束

如果要在外部变量的定义之前使用该变量,或者外部变量的定义与变量的使用不在同一个源文件中,则必须在相应的变量声明中强制性地使用extern

将外部变量的声明与定义严格区分开来很重要。变量声明说明变量的属性,而变量定义除此之外还将引起存储器的分配

在一个源程序的所有源文件中,一个外部变量只能在某个文件中定义一次,而其他文件可以通过extern声明来访问它

外部变量的定义中必须指定数组的长度,但extern声明则不一定要指定数组的长度

外部变量的初始化只能出现在定义中

  

 4.6 静态变量

用static声明限定外部变量与函数,可以将其后声明的对象的作用域限定为被编译源文件的剩余部分

通过static限定外部对象,可以达到隐藏外部对象的目的

外部的static声明通常多用于变量,也可以用于声明函数

通常情况下函数是全局可以访问的.但是,如果把函数声明为static类型,则该函数名除了对该函数声明所在的文件可见外,其他文件多无法访问

static也可以声明内部变量.

static类型的内部变量和自动变量一样,是某个特定函数的局部变量,只能在该函数中使用,但它和自动变量不同的是,不管其所在函数是否被调用,它一直存在,而不像自动变量那样,随着所在函数的被调用和退出而存在和消失.

static类型的内部变量是一种只能在某个特定函数中使用但一直占据存储空间的变量

  

4.7 寄存器变量

register声明告诉编译器,它声明的变量在程序中使用的频率较高

其思想是,将register变量放在机器的寄存器中,这样可以使程序更小,执行速度更快.但编译器可以忽略此选项

register声明只适用于自动变量以及函数的形式参数.

实际使用时,底层硬件环境的实际情况对寄存器变量的使用会有一些限制.每个函数中只有很少的变量可以保持在寄存器中,且只允许某些类型的变量

但是,过量的寄存器声明并没声明害处,这是因为编译器可以忽略过量的或不支持的寄存器变量声明.另外,无论寄存器变量实际上是不是存放寄存器中,它的地址都是不能访问的

  

4.8 程序块结构

变量的声明除了可以紧跟在函数开始的花括号之后,还可以紧跟在其他标示复合语句开始的左花括号之后.
以这种方式声明的变量可以隐藏程序块与之同名的变量,它们之间没有任何关系,并在左花括号匹配的右花括号出现之前一直存在.

  

4.9 初始化

在不进行显式初始化的情况下,外部变量和静态变量都将初始化为0,而自动变量和寄存器变量的初值则没有定义(即初值为无用的信息)

对于外部变量和静态变量来说,初始化表达式必须是常量表达式,且只初始化一次(从概念上讲是在程序开始执行之前进行初始化)

对于自动变量与寄存器变量,则在每次进入函数或程序块时都将被初始化

对于自动变量和寄存器变量来说,初始化表达式可以不是常量表达式:表达式中可以包含任意此表达式之前已经定义的值

  

4.10 递归

C语言中的函数可以递归调用,即函数可以直接或间接调用自身

函数递归调用自身时,每次调用都会得到一个与以前的自动变量集合不同的新的自动变量集合

递归并不节省存储器的开销,因为递归调用过程中必须在某个地方维护一个存储处理值的栈

递归的执行速度并不快,但递归代码比较紧凑,并且比相应的非递归代码更易于编写和理解

  

4.11 C预处理器

C语言通过处理器提供了一些语言功能

从概念上讲,预处理器是编译过程中单独执行的第一个步骤.两个最常用的预处理器指令是:#include 指令和#define指令

  

4.11.1 文件包含

#include "文件名"
#include <文件名>

如果文件名用引号引起来,则在源文件所在位置查找该文件;如果在该位置没有找到文件,或者如果文件名是用尖括号<>括起来,则将根据相应的规则查找该文件,这个规则同具体的实现有关

  

4.11.2 宏替换

#define 名字 替换文本

后续所以出现名字记号的地方都将被替换为替换文本

#define指令中的名字与变量名的命名方式相同,替换文本可以是任意字符串

通常情况下#define指令占一行,替换文本是#define指令行尾部的所以剩余部分内容

也可以把一个较长的宏替换分成若干行,需要在待续的行末尾加上一个反斜杠\

#define指令定义的名字的作用域从其定义点开始,到被编译的源文件的末尾结束

宏定义可以带参数,这样可以对不同的宏使用不同的替换文本

  

4.11.3 条件包含

#ifndef  HDR
#define HDR

#endif

  

原文地址:https://www.cnblogs.com/dafume/p/7792169.html