C与指针 4-6章

来源:互联网 发布:java log4j使用实例 编辑:程序博客网 时间:2024/06/03 09:31

第四章  语句

 

由于C不具备布尔类型,所以语句在测试值时用的都是整型表达式

 

4.2  表达式语句

像下面的语句就是完全合法的

y+3;

getchar();

当这些语句被执行时,表达式被求值。但它们的结果不被保存在任何地方,因为它们没有使用赋值标识符,第一条不具备任何效果,第二条则读取输入中的下一个字符,接着就将其丢弃

 

 

4.6 for语句

  For循环有一个风格上的优势,它把所有操纵循环的表达式收集在一起,便于寻找

 

4.8 switch

每个case标签必须具有一个唯一的值,常量表达式是指在编译期间进行求值的表达式,它不能是任何变量

case标签并不把语句划分成几个部分,它们只是确定语句列表的进入点

switch语句里,continue语句没有任何效果

 

每个swtich语句只能出现一个default子句,但是,它可以出现在语句列表的任何位置

4.10

whiledo循环里,下一次循环开始的位置是表达式测试部分,但在for循环里,下一次循环开始的位置是调整部分

 

 

第5章 操作符和表达式

5.1 算术操作符

注意类似这种形式的移位:

a<<-5

这类移位的行为是未定义的,所以是由编译器决定的。应该避免使用这种类型的移位,因为它们的效果是不可预测的。使用这类移位的程序是不可移植的

 

赋值表达式的值就是左操作数的新值,它可以作为其它赋值操作符的操作数,如下:

a=x=y+1;

 

~对整数类型的操作数进行求补操作,操作数中所有原先为1的位变为0,原先为0的位变为1

 

++ ---)前缀和后缀形式的增值操作符都复制变量值的拷贝,用于周围表达式的值正是这份拷贝

前缀操作符在进行复制之前增加变量的值,后缀操作符在进行复制之后增加变量的值

这些 操作符的结果不是被它们修改的变量,而是变量值的拷贝。它解释了为什么不能像下面这样使用操作符

++a=10;

++a的结果是a值的拷贝,而不是变量本身,你无法向一个值进行赋值。

 

5.2 布尔值

C不具备显式的布尔类型,所以使用整数来代替

避免混合使用整型值和布尔值,如果一个变量包含了一个任意的整型值,应该显式地对它进行测试:

if(value != 0)  .....

 

如果一个变量用于表示布尔值,应该始终把它设置为01,例如:

positive_cash_flow=cash_balance>=0;

 

5.3 左值和右值

例:b+25=a;

当计算机计算b+25时,其结果必然保存在某个地方,但程序员没办法预测结果会存在哪个地方,也无法保证下次表达式的值还会在这个位置。因此,这个表达式不是一个左值,基于同样的理由,字面值常量也都不是左值

 

5.4 表达式求值

  5.4.2算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换成另一个操作数的类型,否则操作就无法运行

警告:

当整型值转换成float型,float型仅要求6位数字的精度,如果将一个超过6位数字的整型值赋值给float型,结果可能只是该整型值得近似值;

float型转换成整型值,小数部分被舍弃(并不四舍五入)。如果浮点数的值过于庞大,无法容纳在整型值中,那么其结果是未定义的。

5.4.3 操作符的属性

左值意味着一个位置,右值意味着一个值。所以,在使用右值的地方可以使用左值,在使用左值的地方不能使用右值。

5.4.4 优先级和求值的顺序

两个相邻操作符的执行顺序由它们的优先级决定。如果它们的优先级相同,它们的执行顺序由它们的结合性决定。除此以外,编译器可以自由决定使用任何顺序对表达式求值。

 

例:a()+b()+c();

如果顺序会导致结果产生区别,最好使用临时变量。

 

5.5 总结

%外,(+-*/)不仅可以作用于整型,还可以作用于float型。

位运算符都要求操作数为整数

表达式的结果如果依赖于求值的顺序,那么它在本质上就是不可移植的,应该避免使用。

 

 

6章 指针

6.1 内存和地址

名字和内存地址之间的关联并不是硬件提供的,它是由编译器实现的

 

6.2 值和类型

不能简单地通过检查一个值得位来判断它的类型。为了判断值的类型,必须观察程序中这个值的使用方式。类型是通过值的使用方法隐性地确定的

 

6.4 间接访问操作符

通过一个指针访问它所指向的地址的过程称为间接访问或解引用指针

 

6.5 未初始化和非法的指针

如果指针变量是静态的,它会被初始化为0;但如果变量是自动的,它不会被初始化。无论是哪种情况,声明一个指向整型的指针不会“创建”存储整型值的内存空间。

 

在对指针进行间接访问之前,必须确保它们已被初始化。

6.7 指针,间接访问和左值

指针变量可以作为左值,并不是因为它们是指针,而是因为它们是变量。

 

6.9 指针常量

间接访问操作只能作用于指针类型表达式

6.10 指针的指针

int a=12;

int *b=&a;

int *c=&b;

6.13指针运算

只有当两个指针指向同一数组中的元素时,才允许从一个指针减去另一个指针

如果当两个指针指向的不是同一数组中的元素时,它们相减的结果是未定义的

 

可以在任意两指针间执行相等或不相等测试

 

6.14总结

对未初始化的指针变量执行间接访问操作是非法的,而且这种错误常常难以检测。

其结果常常是一个不相干的值被修改。

NULL指针执行间接访问控制的后果因编译器而异。两个常见的后果就是返回内存位置零的值和终止程序。

指针运算只有作用在数组中其结果才是可以预测的