1. 程式人生 > >C語言程式設計入門之--第五章C語言基本運算和表示式-part2

C語言程式設計入門之--第五章C語言基本運算和表示式-part2

5.1.4 再來一個C庫函式getchar吸收回車鍵

  回車鍵也是一個字元,在使用scanf的時候,輸入完畢要按下回車鍵,這時候回車鍵也會被輸入到stdin流中,會搞亂我們的程式。

  注意:stdin是輸入流,stdout是輸出流,這兩個流就是在記憶體中流進流出的資料,根據流向不同命名也不同。

  比如以下程式碼執行後,

#include <stdio.h>

void main()
{
    int b;
    char f;    
    
    printf("please input int:");
    scanf("%d", &b);

    printf("please input char:");
    scanf("%c", &f);

    printf("b = %d, f = %c", b, f);
}

  執行結果如圖5.7,

圖5.7  回車鍵被變數f吸收的結果

  原本以為,根據程式碼的邏輯操作:先輸入變數b的值,然後按下回車,再輸入變數f的值,然後再回車,最後printf這兩個變數的值,皆大歡喜!

  沒想到實際操作中:輸入了100賦值給變數b,再按下回車就輸出瞭如圖5.7的結果。

  仔細想想,輸出結果中,“f = ” 後面感覺換了一行,聯想到平時在使用word或者txt打字的時候,回車鍵也有換行的作用,那麼現在就有理由相信,回車鍵賦值給了變數f。可能筆者之前沒有講明,回車鍵也是一個字元,就像a、b、c、d一樣,是可以賦值的。為了吸收這個回車鍵,可以使用C庫函式getchar,更改後,程式碼如下,其實就是在scanf後面新增一句getchar來吸收輸入流,

#include <stdio.h>

void main()
{
    int b;
    char f;    
    
    printf("please input int:");
    scanf("%d", &b);
    
    getchar();
    
    printf("please input char:");
    scanf("%c", &f);

    printf("b = %d, f = %c", b, f);    
}

  結果如圖5.8,

  

圖5.8  新增getchar吸收回車鍵

  讀者肯定這時候會有困惑,到底什麼是標準輸入流stdin,什麼是標準輸出流stdout,為啥使用了scanf後要用回車鍵,筆者一時半會也解釋不清,先把疑問擱著,說不定後續慢慢就能明白這些概念了,先明白怎麼使用吧,在多次使用中瞭解它們的用意。

 

5.1.4 第一次自主練習題,做個簡單的註冊功能

  學習寫程式,一定要多練習,多上機,機你太美!這是肺腑之言,更是經驗之談。

  題目:做個註冊功能介面,輸入賬戶,輸入密碼,輸入性別,然後顯示出來。

  思路:第一次使用微信,第一次使用抖音,第一次使用部落格園的時候,都會有個註冊功能,註冊功能就是填寫基本資訊。

  由於現在掌握的知識有限,做不到輸入姓名名字,也做不到輸入一長串數字如身份證號碼等,所以加了個限制,就讓賬戶名是一串數字吧,並且要在int的可容許範圍內,也就是第四章查看錶4.1中,整型範圍在-2,147,483,648 到 2,147,483,647之內的數字,密碼也是如此,至於性別就暫時用‘m’(male)代表男性,‘f’(female)代表女性。很簡單吧,開始練習吧。練習完以後,可以檢視筆者給出的參考程式碼,如下:

 

#include <stdio.h>

void main()
{
    int account;
    int passwd;
    char sex;    

    printf("歡迎進入註冊介面!\n");
    
    printf("請輸入賬戶名:");
    scanf("%d", &account);
    getchar();
    
    
    printf("請輸入密碼:");
    scanf("%d", &passwd); 
    getchar();
    
    printf("請輸入性別,m代表男性,f代表女性:");
    scanf("%c", &sex);
    
    
    printf("註冊成功,賬戶名是%d, 密碼是%d, 性別是%c \n", account, passwd, sex); 
}

  執行結果圖5.9,

  

圖5.9  執行結果

  程式碼解析:

  1. 變數名,可以是單詞account還有sex等?之前有講過,變數名可以使用英文單詞或者自己建立的字母組合,如果不想用英語的話,可以給變數名取名為zhanghu,但是變數名不可以用C語言關鍵詞,比如int,char等。變數名也可以新增下劃線,這個看個人口味了。

  2. 可以輸出中文?因為有的編譯器支援中文輸出,很榮幸,Dev-C++是支援的,之前不用是為了鼓勵使用英文。現在還是建議儘量使用英文。

  3. 在printf中,“\n”是啥?在ASCII中,它代表換行符,是轉義字元中的一個,有了它,就能輸出一個回車鍵的效果。C語言中有多個轉義字元,後續逐步介紹。

5.2 運算子

5.2.1 加減乘除取餘運算

  回顧之前的變數,printf,scanf,有了它們,就能夠製作簡單的計算器了。

  在鍵盤中,找幾個按鍵,其中,“+”可以用在加法上,“-”可以用在減法上,“*”用在乘法上,“/”用在除法上,“%”用在取餘數上,“=”表示賦值。

  小學學習加減法的時候,一般這麼寫運算表示式:x1+x2=y;

  在C語言中,由於“=”這個賦值表示式是從右往左邊賦值,所以要這麼寫y=x1+x2;體現在程式碼中,如下:

#include <stdio.h>

void main()
{
    int x1, x2;
    int y;
    
    x1 = 100;
    x2 = 50;
    
    y = x1 + x2;
    
    printf("x1 + x2 = %d \n", y);    
}

  執行後輸出結果是:x1 + x2 = 150

  注意:C語言支援變數名後面加數字。

  讀者可以自行吧“+”改為“-”或者改為“*”或者改為“/”或者改為“%”,試試看結果,就能夠知道“-”為減法運算子,“*”為乘法運算子,“/”為除法運算子,“%”為取餘運算子。

  注意:取餘的意思就是求兩個數相除的餘數,比如100除以50的餘數為0,100除以49的餘數為2。

  掌握了以上,就可以做個簡單的加減乘除計算器了,希望讀者自行完成,功能就是輸入兩個數,然後輸出這兩個數的運算結果。

 

5.2.2 混合表示式及運算優先順序

  小學題,已知表示式y = x1 + x2 * x3,且x1等於10,x2等於5,x3等於7,求y值?

  結果是多少,一目瞭然,按照正常思維,乘法運算的優先順序高於加法運算,所以應該先計算x2*x3得35,然後再計算加法,得到y值等於45。

  C語言中也是如此,運算子那麼多,應該誰先誰後,都是規定的死死的,如表5.1,

優先順序運算子結合律
1 字尾運算子:[]    ()    ·    ->    ++    --(型別名稱){列表} 從左到右
2 一元運算子:++    --    !    ~    +    -    *    &    sizeof_Alignof 從右到左
3 型別轉換運算子:(型別名稱) 從右到左
4 乘除法運算子:*    /    % 從左到右
5 加減法運算子:+    - 從左到右
6 移位運算子:<<    >> 從左到右
7 關係運算符:<<=    >>= 從左到右
8 相等運算子:==    != 從左到右
9 位運算子 AND:& 從左到右
10 位運算子 XOR:^ 從左到右
11 位運算子 OR:| 從左到右
12 邏輯運算子 AND:&& 從左到右
13 邏輯運算子 OR:|| 從左到右
14 條件運算子:?: 從右到左
15 賦值運算子:
     =         +=        -=       *=       /=      %=       &=       ^=      |=   
   <<=      >>=
從右到左
16 逗號運算子:, 從左到右

  表5.1  運算子優先順序規定表

  哇塞,運算子那麼多,還有的沒用過呢?記不住啊,我太難了,好累啊!

    沒辦法,這些都得記住,但不是現在馬上全部記住,用著用著就能夠記住的,相信我,先把這份表收藏,用的時候拿出來看,要死記硬背也行,看個人習慣怎麼記憶了。

  請記住,C語言運算子遵循一個原則,優先順序最高先運算,同級別的從左往右運算。

  比如,一個表示式 (x1+x2*x3)/(x4-x5+x6-x7)中,

  括號等級最高,所以先運算括號運算子,有兩個括號運算子,所以這是同級別運算,先運算左邊的括號,在左邊的括號中(x1+x2*x3),有加法有乘法,先執行高等級的乘法,然後再執行加法。然後執行右邊的括號運算裡面的表示式(x4-x5+x6-x7),有加法有減法,是同級別的運算,所以先運算左邊的減法再依次運算加法和減法,最終把兩邊運算的值進行除法計算即可。

   

5.2.3 表示式練習題之求平均數 

  要求:輸入三個整數,求它們的平均值。簡單吧,程式碼如下:

#include <stdio.h>

void main()
{
    int x1, x2, x3;
    int y;
    
    printf("please input three data: \n");
    
    scanf("%d, %d, %d", &x1, &x2, &x3);
    getchar();
    
    y = (x1 + x2 + x3)/3;
    
    printf("average y = %d\n", y);
}

  編譯執行後,輸入2,4,6得到結果:average y = 4。

  但是如果輸入3,5,6得到的結果居然也是:average y = 4。開啟計算器,計算出平均值為3.666666......

  這是由於計算機計算精度不同導致的,由於整型int只能精確到小數點左邊,也就是int取值範圍在-2,147,483,648 到 2,147,483,647,所以為了精度高一些,可以用上float型別,它的取值範圍是1.2E-38 到 3.4E+38。

  改進後,程式碼如下:

#include <stdio.h>

void main()
{
    float x1, x2, x3;
    float y;
    
    printf("please input three data: \n");
    
    scanf("%f, %f, %f", &x1, &x2, &x3);
    getchar();
    
    y = (x1 + x2 + x3)/3;
    
    printf("average y = %f\n", y);
}

  這時候,再輸入3,5,6得到的結果就是:average y = 4.666667。

  修改的部分有,1. 宣告的型別由int改為float。

         2. scanf中,%d改為%f。

         3. printf中,%d改為%f。

  有了這些修改就能夠支援精度高的浮點型float資料運算了。

 

5.2.4 表示式練習題之求個位數和萬位數的和

  出這個題純粹練習思維,題:輸入一個5位數的整型,求個位數和萬位數的和。

  希望讀者自行編寫完程式後,再看參考程式碼。

  大體思路:通過scanf輸入一個5位數,比如輸入的是32145,取個位5,取萬位數3,求和。

  具體思路:

  1. 定義一個變數用來存放上面所說的32145,定義一個變數用來存放個位數,定義一個變數用來存放萬位數,定義一個變數用來存放個位和萬位的和,總共需要定義四個變數。

  2. 求個位數,需要用到取餘表示式,即32145%10。開啟草稿紙,如圖5.10所示,計算32145除以10的餘數為5,剛好就是獲得的個位數,

圖5.10  計算32145%10的結果

  3. 求萬位數,只需要用到除法表示式,即32145/10000,要開啟草稿紙算也行,筆者就不發圖了。

    4. 計算個位數和萬位數的和。程式碼如下:

#include <stdio.h>

void main()
{
    int data;
    int first, fifth;
    int getAddWorth;
    
    printf("please input a 5 digit data\n");
    scanf("%d", &data);
    getchar();
    
    first = data % 10;
    fifth = data / 10000;
    
    getAddWorth = first + fifth;

    printf("data = %d, first = %d, fifth = %d, getAddWorth = %d \n", data, first, fifth, getAddWorth);
}

  執行後,輸入32145可得getAddWorth的值為8,正解!

  注意:變數命名也可以由大寫字母和小寫字母的組合,如getAddWorth。

 

    關鍵的拓展,為了自身打鐵能力過硬,可以給自己出些更苛刻的題,剛才的題給出了思路,以下的題建議自行完成,如果實在完成不了,讀者可以在評論區索要正確答案。

  題1:一個六位數中,取千位數和十位數的和。

  題2:一個六位數中,個位數和萬位數調換位置,輸出結果。

 

&n