第四章:语句与第五章:操作符和表达式

第四章的语句没有什么特别的东西,都是if,while,for,等正常使用的语句,唯一需要注意的是,switch语句中加default语句形成好习惯,之后的学习中会提到使用函数指针来形成转接表代替某些switch操作。

goto语句不提倡使用虽然可以从最内层的循环直接跳出,但是很危险,容易产生依赖,跳出内层循环可以以如下的方式进行:

enum{exit,ok} status;
status = ok;
while( status == ok && condition1){
    while( status == ok && condition2)    {
        while(condition3){
            if(some disaster)
            {
                status = exit;//或者直接用return
                break;
            }
        }
    }
}
第五章操作符和表达式

1、移位操作符

左移对于无符号数和有符号数来说毫无争议,后面都用0填充,

右移对于无符号数是逻辑移位,左边都填入0,对于有符号数来说是算术移位还是逻辑移位取决于编译器,所以不具备可移植性。

左移-5类似于下边的式子

a << -5
这是未定义的,由编译器决定,有些机子上面会执行左移27位的操作。

2、位操作符

可以实现对一个数据的某一位置0或者1,或者测试其是否为1,

简单的例子来看:可以通过判断最后一位是否为1来判断是否为偶数。

3、赋值

这里比较重要的就是考虑如下2个式子

a[2*(y-f(x))] = a[2*(y-f(x))] + 1;
a[2*(y-f(x))] += 1
第一个式子计算了2次下标,如果f(x)有副作用,会改变x或者y的话,那么可想而知,第一个式子a[b] = a[c]+1了,由于计算了2次下表,效率还低下。

第二个式子只计算了一次下标,不会出现问题。

4、单目操作符

第一个要注意的是例如sizeof(a = b+1),是不会对表达式进行计算的,也就是说a是不会改变,通过判断括号里的类型,编译器就会输出一个类型大小。

++号:不能使用++a = 10这样的操作,++a的结果是a值的拷贝,不是变量本身,无法对值进行赋值

5、逗号表达式

逗号表达式是将多个表达式分隔开,从左到右求值,整个表达式的值就是最后那个表达式的值

非常经典的例子如下

a = get_value();
count_value(a);
while(a > 0){
        ...
        a = get_value();
        count_value;
}
在循环体开始前和结束的时候,有相同的语句,就可以转移近while的条件判断语句里,用逗号表达式分开。
while(a = get_value(),count_value(a),a>0)
6、表达式求值

C语言的整形算术运算至少以缺省的整型类型的精度来进行的,比如2个char相加,先提升为整型计算完之后再进行阶段,因为如果存在求补或者左移的操作,8位精度是不够的,标准要求进行完整的整型求值,这样就不会存在歧义性。

再看下面的代码

int a = 5000;
int b = 25;
long c = a*b;
在16位系统上,c就会错误,a*b就会溢出,32位不会产生问题,所以需要强制类型转换,long c = (long)a*b;

7、优先级顺序

比如

main()
{
    int i = 10;
    i = i-- - --i*(i = -3) * i++ + ++i;
    printf("i = %d\n",i);
}

我们不知道-- 在-之后还是之前进行或者++i在什么时候进行,所以存在歧义,不同的编译器都产生不一样的结果。也如c+ --c结果不一定。

如果一个连续表达式如if(x+y+1>0)存在溢出,那么x+y先溢出还是y+1先溢出,结果不一样,所以要分语句来执行。

像f()+h()+g(),不管先执行哪个函数,顺序不一样,结果就不同,就得单独语句执行:

temp = f();
temp += h();
temp += g();
简单的习题:编写函数 unsigned int reverse_bit(unsigned int value)

这个函数的返回值是把value的二进制位模式从左到右变化一下后的值,例如在32位机器上,25这个值包含下列各个位:

00000000000000000000000000011001.

程序如下:

int answer = 0;
for(i = 1;i > 0;i <<=1)
{
    answer << 1;
    if(value & 1 == 1)
        answer |=1;
    value >>=1;
}

发布了33 篇原创文章 · 获赞 16 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章