C函数 (下)

10 随机数的生成
● 函数rand产生一个值在0和Rand_MAX之间的整数,其中RAND_MAX是C语言标准定义的至少是32767的符号常量
● 可以通过缩放和平移函数rand产生的值来产生一个指定范围内的值
● 使用C标准库函数srand,可以随机化一个程序
● srand函数为随机数产生器布下一个种子以便让随机数产生器在每次执行时产生出不同的序列,调用函数srand的语句一般只有一个程序已经完全排错后才被插入到程序中。在调试程序时最好不要使用srand。因为这样可以保证程序的可重复性,这对于检验一个随机数产生程序是否正确是很重要的。
● 函数 rand 和 srand 的函数原型包含在<stdio.h>头文件中。
● 不想每次都输入一个种子就实现随机化,请使用srand(time(NULL));
● 缩放和平移一个随机数的通用公式是
n=a+rand()%b;
其中,a是平移距离,(即用户期望的连续整数区间的起始值)。b是缩放因子(即用户期望的整数区间的宽度)
11 案例分析:运气游戏:引入enum
● 用关键字enum来定义的枚举类型是一组用标识符表示的整型常量的集合。一个枚举类型中的值是从零(0)开始,然后逐个增1.也可以分别给枚举类型中的每一个标识符富裕一个特定的整数值。枚举类型中的每一个标识符必须是唯一的,但是他们的值是可以重复的
12 存储类型
● 在程序中出现的每个标识符都有存储类型,存储周期,作用域,链接等属性
● C语言共有4种存储类型,它们对应的存储类型说明符分别是:auto,register,extern,static
● 一个标识符的存储周期是指标识符所代表的变量存在于内存中的时间
● 在一个由多个源文件组成的程序中,标识符的链接是说明这个标识符是仅仅能够被当前源文件所识别,还是可以通过适当的声明也能被其他源文件所识别
● 具有自动存储周期的变量在执行到定义它的执行块时才被创建,并在执行块的活动期间一直存在于内存中,在控制退出程序块后就被释放了。一个函数的局部变量通常都属于自动存储变量
● 关键字extern和static用于声明具有静态存储周期的变量名和函数名的标识符
● 静态存储周期变量是在程序开始运行之前进行分配和初始化的,而且只分配和初始化一次
● 具有静态存储周期的标识符可以分为两类:
1.外部标识符(如全局变量和函数名)
2.用存储类别限定符static声明的局部变量
● 创建全局变量的方法是将其变量定义语句写在任何一个函数体之外。全局变量在程序运行期间始终存在
● 静态存储变量在定义它的函数连续被调用的过程中保持它们的数值
● 如果程序中没有显式地对数值型静态存储周期变量进行初始化,则C语言会自动将它们初始化为0
13 作用域的规定
● 一个标识符的作用域是指程序中能够访问到这个标识符的区域
● 标识符可以具有函数作用域,文件作用域,程序块作用域或函数原型作用域
● 标号是唯一具有函数作用域的标识符。标号可以在定义它的函数中的任何位置被访问到,但是在定义它的函数之外就不能再访问到了
● 在所有函数之外定义的标识符具有文件作用域。这样的标识符从声明它的语句开始到整个程序结束的区间内,能被所有函数识别
● 在一个程序块内部定义的标识符具有程序块作用域。程序块作用域结束于表示程序块结束的右花括号(})
● 在函数开始时定义的局部变量以及函数的形参都是具有程序块作用域,因为形参也被函数视为局部变量
● 任何程序块都可以包含变量定义。对于嵌套出现的程序块,如果外层程序块中的一个标识符与内层程序块中的一个标识符具有相同名字,那么在执行内层程序块的过程中,外层程序块的标识符将一直被"隐藏"起来,直到内层程序块执行结束为止
● 唯一具有函数原型作用域的一类标识符是出现在函数原型的形参列表中代表形参名的那些标识符。这些标识符可以在程序的其他地方用于其他用途而不会引起混乱
14 递归
● 递归函数就是直接或间接调用自己的函数
● 如果用基线条件去调用递归函数,则函数就直接返回结果。如果用较复杂的情况去调用递归函数,则函数将问题从概念上分成两部分:
● 一部分是函数已经知道答案的
● 一部分是原始问题的一个较小规模的版本
● 由于面临的新问题与原始问题类似,函数就可以派出一个递归调用去求解那个规模较小的问题
● 为了保证递归调用最终终止,递归函数每次都是用规模更小的原始问题去调用它自己,而这些逐渐变小的问题最终必须收敛于基线条件。当函数识别出基线条件时,基线条件的解将被返回到它的上一个主调函数。然后就是一连串地直线式地返回操作,直到最终由函数的原始调用返回到原始问题的解
● 对大多数运算符(包括+)而言,标准C没有规定它们的操作数的定值顺序。只对与运算符(&&) 或运算符(||) 逗号运算符(,)和条件运算符(?:)这4个运算符规定了它们的多个操作数的定值顺序。前三个运算符属于二元运算符,它们两个操作数的定值顺序都是从左向右的。最后一个运算符是C语言中唯一一个三元运算符,它总是首先计算最左边操作数的值。如果最左边的操作数的值为非零,则计算中间那个操作数的值,而将最后那个操作数忽略掉。如果最左边操作数的值是零,则计算第三个操作数的值,而将中间那个操作数忽略掉
16 递归与迭代
● 递归与迭代都分别以一种控制结构为基础:迭代基于循环语句,而递归基于选择语句
● 递归和迭代都需要循环地执行:迭代是使用一个循环语句,而递归通过重复的调用函数来实现循环
● 递归和迭代都需要进行终止测试:当循环条件为假时,迭代结束,而递归是在遇到基线条件时终止
● 递归和迭代都可能会出现无限执行的情况:若一个循环继续条件永远不会为假,则发生无限循环,如果递归执行产生的新问题不是逐渐收敛于基线条件,也导致无限递归
● 递归需要不断的执行函数调用机制,因此会产生很大的函数调用开销,从而在处理器的时间和存储器的空间两方面付出很大的代价

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章