1.do/while语句
while语句先测试控制表达式的值再执行循环体,而do/while语句先执行循环体再测试控制表达式的值
。如果控制表达式的值一开始就是假,while语句的循环体一次都不执行,而do/while语句的循环体仍然要执行一次再跳出循环。
2.goto语句
goto语句,实现无条件跳转
。我们知道break只能跳出最内层的循环,如果在一个嵌套循环中遇到某个错误条件需要立即跳出最外层循环做出错处理,就可以用goto语句,例如:
for (...)
for (...) {
...
if (出现错误条件)
goto error;
}
error:
出错处理;
goto语句过于强大了,从程序中的任何地方都可以无条件跳转到任何其它地方,只要在那个地方定义一个标号就行,唯一的限制是goto只能跳转到同一个函数中的某个标号处,而不能跳到别的函数中。滥用goto语句会使程序的控制流程非常复杂,可读性很差。
通常goto语句只用于这种场合,一个函数中任何地方出现了错误条件都可以立即跳转到函数末尾做出错处理(例如释放先前分配的资源、恢复先前改动过的全局变量等),处理完之后函数返回。
替代方法:使用标志位
int cond = 0; /* bool variable indicating error condition */
for (...) {
for (...) {
...
if (出现错误条件) {
cond = 1;
break;
}
}
if (cond)
break;
}
if (cond)
出错处理;
3.复合类型与结构体
在编程语言中,最基本的、不可再分的数据类型称为基本类型(Primitive Type),例如整型、浮点型;根据语法规则由基本类型组合而成的类型称为复合类型(Compound Type),例如字符串是由很多字符组成的。有些场合下要把复合类型当作一个整体来用,而另外一些场合下需要分解组成这个复合类型的各种基本类型
,复合类型的这种两面性为数据抽象(Data Abstraction)奠定了基础。
在学习一门编程语言时要特别注意以下三个方面:
- 这门语言提供了哪些Primitive,比如基本类型,比如基本运算符、表达式和语句。
- 这门语言提供了哪些组合规则,比如基本类型如何组成复合类型,比如简单的表达式和语句如何组成复杂的表达式和语句。
- 这门语言提供了哪些抽象机制,包括数据抽象和过程抽象(Procedure Abstraction)。
类型定义也是一种声明,声明都要以;号结尾
struct a {
int x;
int y;
};
a b;
b = {1, 2}; // c++可以,c不能使用{}赋值,只能初始化
有些时候结构体或数组中只有某一个或某几个成员需要初始化,其它成员都用0初始化即可,用Designated Initializer语法可以针对每个成员做初始化(Memberwise Initialization),很方便。
a b{.y = 1};
4.数据抽象
“抽象”这个概念并没有那么抽象,简单地说就是“提取公因式”:ab+ac=a(b+c)。如果a变了,ab和ac这两项都需要改,但如果写成a(b+c)的形式就只需要改其中一个因子。
在我们的复数运算程序中,复数有可能用直角座标或极座标来表示,我们把这个有可能变动的因素提取出来组成复数存储表示层:real_part、img_part、magnitude、angle、make_from_real_img、make_from_mag_ang。这一层看到的数据是结构体的两个成员x和y,或者r和A,如果改变了结构体的实现就要改变这一层函数的实现,但函数接口不改变,因此调用这一层函数接口的复数运算层也不需要改变。复数运算层看到的数据只是一个抽象的“复数”的概念,知道它有直角座标和极座标,可以调用复数存储表示层的函数得到这些座标。再往上看,其它使用复数运算的程序看到的数据是一个更为抽象的“复数”的概念,只知道它是一个数,像整数、小数一样可以加减乘除,甚至连它有直角座标和极座标也不需要知道。
这里的复数存储表示层和复数运算层称为抽象层(Abstraction Layer),从底层往上层来看,复数越来越抽象了,把所有这些层组合在一起就是一个完整的系统。**组合使得系统可以任意复杂,而抽象使得系统的复杂性是可以控制的,任何改动都只局限在某一层,而不会波及整个系统。**著名的计算机科学家Butler Lampson说过:“All problems in computer science can be solved by another level of indirection.”这里的indirection其实就是abstraction的意思。
5.enum
enum day {sunday = 1, tuesday, wednesday, thursday, friday, saturday};
int main()
{
enum day d = thursday;
printf("The day number stored in d is %d", d);
return 0;
}
enum写好以后括号内每个名称都分配一个整数值,我们可以直接使用括号内名称,也可以使用enum类型确定一个唯一整数。