第四章:語句與第五章:操作符和表達式

第四章的語句沒有什麼特別的東西,都是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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章