1.輸入和輸出
在程序的使用中,我們經常可以看的這么一個場景:用戶需要輸入數據,經過程序運算,得到結果后輸出。在C語言中,輸入數據和輸出數據都是由庫函數完成的,通過語句來輸入/輸出。
2.格式化輸出—printf()函數
C語言程序運算的結果在內存中,我們需要將其輸出到指定設備中,我們才可以看到數據。printf是print format的縮寫,意思是“格式化打印”。“打印”的意思就是在屏幕上顯示內容,所以我們稱printf是格式化輸出。
2.1 printf()函數
在前面我們有簡單的使用過printf()函數,printf()函數的一般語法格式如下:
printf("<格式化字符串>",<輸出列表>);
- 格式化字符串:用雙引號括起來的字符串,字符串包含的普通字符,printf()函數將其原樣輸出到屏幕上;以"%"開頭的格式字符,printf()函數將數據轉換為指定的格式輸出到屏幕上。
- 輸出列表:需要輸出到屏幕的數據,數據可以是常量、變量或者表達式。
【實例5.1】printf()函數輸出“C語言入門教程”。
#include <stdio.h>
int main()
{
printf("關注公眾號:程序員基礎知識");
return 0;
}
執行以上程序,輸出結果為:
關注公眾號:程序員基礎知識
實例解析:
printf()函數用於格式化輸出到屏幕,在頭文件(標准輸入輸出頭文件)中聲明。當編譯器調用printf()函數時,如果沒有頭文件,會發生編譯錯誤。實例中,printf()函數只有“格式化字符串”,省略了“輸出列表”。該語句字符串只包含的普通字符,printf()函數將其原樣輸出到屏幕上。
2.2 printf()函數的字符格式
格式化字符串中如果包含以“%”開頭的格式字符,printf()函數將數據轉換為指定的格式輸出到屏幕上。格式化字符串中包含三部分,即原樣輸出文字、控制字符、轉義字符。如果輸出列表有兩個變量或者多個組成,變量之間需要用逗號隔開,多個變量與格式字符串的控制字符一一對應。
輸出不同的類型需要使用不同的控制符,這里匯總了一些常見的控制符,如下表所示。
| 格式字符 | 意義 |
|---|---|
| %d | 輸出十進制整數,一般對應int類型 |
| %i | 輸出十進制整數,與%d相同 |
| %c | 輸出字符,一般對應char類型 |
| %f | 輸出十進制實數,一般對應float類型,也可以是double類型 |
| %lf | 輸出十進制實數,一般對應double類型,也可以是float類型 |
| %% | 輸出百分號(%) |
C語言中定義了一些字母前加"\"來表示那些不能直接顯示的ASCII字符,稱為轉義字符。匯總了幾個常用的轉義字符,如下表所示。
| 轉義字符 | 意義 |
|---|---|
| \n | 換行,將當前位置移到下一行開頭 |
| \t | 水平制表,跳到下一個Tab位置 |
| \\ | 代表一個反斜線字符'\' |
【實例5.2】通過格式化輸出蓋倫屬性。
#include <stdio.h>
int main()
{
char garenName = 'G';
printf("名字:%c\n", garenName);
int garenHp = 455;
int garenMoveSpeed = 340;
printf("生命值:%d\t移動速度:%d\n", garenHp, garenMoveSpeed);
float garenAttackSpeed = 0.625;
printf("攻擊速度:%f\n", garenAttackSpeed);
printf("攻擊速度:%lf\n", garenAttackSpeed);
return 0;
}
執行以上程序,輸出結果為:
名字:G
生命值:455 移動速度:340
攻擊速度:0.625000
攻擊速度:0.625000
實例解析:
控制字符%c輸出一個字符G,轉義字符\n代表換行。生命值和移動速度之間有一個Tab的間隔,這是因為中間有轉義字符\t。float型的控制字符既可以用%f也可以用%lf。在printf()中,%f或者%lf控制字符既可以輸出float型又可以輸出double型。但在輸入的時候則需要注意,float型對應%f,double型對應%lf,本節后面會講到。
3.格式化輸入—scanf()函數
輸入的意思是向程序填充一些數據,scanf()函數用於從標准輸入(比如鍵盤)讀取並格式化。scanf是scan format的縮寫,意思是“掃描格式化”。我們稱scanf是格式化輸入。
3.1 scanf()函數
scanf()函數也是一個標准庫函數,在頭文件中。scanf()函數的一般語法格式如下:
scanf("<格式化字符串>",<地址列表>);
- 格式化字符串:用雙引號括起來的字符串,一般只有"%"開頭的格式字符。
- 地址列表:各個變量的地址,變量的地址通過取地址符號"&"和變量名得到。比如,&a代表變量a的地址。我們不需要關心具體的地址是什么,只需要在變量名前加上取地址符號"&"即可。我們需要注意,scanf()函數要求給出地址,如果只有變量名則會報錯。scanf()函數也可以和printf()函數一樣可以接受多個值,變量之間需要用逗號隔開,需要一一對應。
【實例5.3】通過格式化輸入並且輸出蓋倫屬性。
#include <stdio.h>
int main()
{
char garenName;
printf("Please input garenName:");
scanf("%c", &garenName);
printf("名字:%c\n", garenName);
int garenHp;
int garenMoveSpeed;
printf("Please input garenHp and garenMoveSpeed:");
scanf("%d%d", &garenHp, &garenMoveSpeed);
printf("生命值:%d\t移動速度:%d\n", garenHp, garenMoveSpeed);
float garenAttackSpeed;
printf("Please input garenAttackSpeed:");
scanf("%f", &garenAttackSpeed);
printf("攻擊速度:%f\n", garenAttackSpeed);
return 0;
}
執行以上程序,輸出結果為:
Please input garenName:G
名字:G
Please input garenHp and garenMoveSpeed:455 340
生命值:455 移動速度:340
Please input garenAttackSpeed:0.625
攻擊速度:0.625000
實例解析:
scanf()函數不能輸出提示信息,所以我們一般會在前面使用printf()函數來提示。實例中,Please input garenName:就是提示語句,我們輸入一個字符'G',然后回車鍵表示輸入完成。生命值和移動速度的輸入值,需要分別保存到兩個變量中,scanf()函數使用空白字符(空格、換行、制表符Tab)來分隔輸入的數據。455和340之間使用了空格來分隔也可以使用回車來分隔開,scanf()函數將455保存到變量garenHp中,將340保存到garenMoveSpeed中。使用scanf()函數當輸入數據是float類型時用%f,當輸入數據是double類型時用%lf。
注意:如果用VS遇到scanf報錯,將報錯的宏定義(_CRT_SECURE_NO_WARNINGS)添加到項目屬性 -- C/C++ -- 預處理器 -- 預處理器定義。要注意自己使用的調試平台和屬性頁的配置是一致的。比如用的是Debug的x64調試,在進入項目屬性也要配置一致。
3.2 scanf()函數的其他使用情況
1)寬度
我們可以在scanf()函數中指定輸入的寬度,達到寬度后,后面的數據將會賦給下一個變量,如果只有一個變量則會將后面的數據舍棄。
scanf("%2d", &garenHp);
當輸入"455"時,將只有45保存到變量garenHp中,其余數據被舍棄。
scanf("%2d%d", &garenHp, &garenMoveSpeed);
當輸入"455"時,將45保存到變量garenHp中,5保存到變量garenMoveSpeed中。
2)星號
在格式字符串中使用星號,將會跳過這個輸入值。
scanf("%d%*d%d", &garenHp, &garenMoveSpeed);
上面語句中,當輸入"1 2 3"時,scanf()將第一個數1保存到變量garenHp,第二個數2將會被跳過,然后將第三個數3保存到變量garenMoveSpeed中。
4.getchar()函數和putchar()函數
getchar()函數用於接收鍵盤輸入的下一個字符,並把它返回為一個整數,在同一個時間內只會讀取一個字符。當調用getchar()函數時,程序就會等待。我們輸入的字符被存放在輸入緩沖區中,直到按回車為止。輸入的字符會回顯在屏幕上,能被我們所看見。getchar()函數從輸入緩沖區中讀入第一個字符。其函數原型如下:
int getchar(void);
該函數的參數是void,不需要任何參數。當發生讀取錯誤的時候,返回-1。當讀取正確的時候,它會返回從鍵盤輸入的第一個字符的ASCII碼。
putchar()函數把字符輸出到顯示器上,並返回相同的字符,在同一個時間內只會輸出一個字符。其函數原型如下:
int putchar(int ch);
該函數的參數是int類型。然后參數被轉換為對應字符的ASCII碼,最后輸出該ASCII碼對應的字符。
【實例5.4】getchar()函數和putchar()函數
#include <stdio.h>
int main()
{
char ch;
printf("Please input a ch:");
ch = getchar();
printf("ch is:");
putchar(ch);
return 0;
}
執行以上程序,輸出結果為:
Please input a ch:a
ch is:a
實例解析:
getchar()和putchar()函數也在頭文件中。首先定義了一個字符類型的ch變量,然后我們從鍵盤輸入"a"加上回車。這個時候,輸入緩沖區中有字符a以及回車符號。getchar()函數從輸入緩沖區中讀取第一個字符,將a存入到變量ch中,然后putchar()函數將其輸出。
5.getch()函數和putch()函數
getch()函數和前面講到的getchar()函數功能基本相同,也是接收輸入的一個字符。getch()函數直接從鍵盤獲取值,不等待回車鍵。只要獲取到一個值,便立即返回。getch()函數輸入的字符不回顯,我們在屏幕上也看不到。因此,getch()函數常用來做調試。我們使用vs調試程序時,如果不使用Ctrl+F5,直接使用F5,控制台輸出窗口將會一閃而逝。我們可以在程序中加上getch()函數,讓程序暫停,這樣就不會一閃而逝了,當從鍵盤按任意鍵后程序會繼續運行。其函數原型如下:
int getch(void);
putch()函數在使用上和putchar()函數沒什么區別,也是用來向屏幕中輸出一個字符。其函數原型如下:
int putch(int ch);
【實例5.5】getch()函數和putch()函數
#include <stdio.h>
#include <conio.h>
int main()
{
char ch = 'a';
_putch(ch);
_getch();
return 0;
}
執行以上程序,輸出結果為:
a
實例解析:
getch()函數和putch()函數在頭文件中。這個程序中,我們使用putch()函數輸出變量ch,然后調用getch()函數使程序暫停,從鍵盤輸入任意鍵,程序成功執行完畢。在VS2012之后,我們直接使用getch()和putch()會報錯,我們需要在前面加上下划線變成_getch()和_putch(),像實例中一樣。
6.總結
總結一下,本節內容主要介紹了C語言程序的格式化輸入和輸出。介紹了scanf()函數和printf()函數、getchar()函數和putchar()函數、getch()函數和putch()函數。
7.練習
5-1 下面一段程序將會輸出什么?
#include <stdio.h>
int main()
{
int a = 10;
printf("%d %d", a);
return 0;
}
5-2 編寫一個程序,要求輸出兩個百分號"%%"和兩個"\"。
5-3 編寫一個程序,要求輸入兩個變量,一個變量代表蓋倫血量,一個變量代表提莫攻擊力。然后模擬提莫攻擊蓋倫,輸出蓋倫剩余血量。蓋倫剩余血量 = 蓋倫血量 - 提莫攻擊力。
5-4 編寫一個程序,使得輸入字符,可以直接轉換為ASCII碼值。
可以在評論中,寫下你們的練習答案。
之后的文章會給大家帶來更精彩的內容
歡迎關注我的知乎專欄:程序員基礎知識
獲取練習答案以及更多實戰項目
歡迎關注我的公眾號:程序員基礎知識
交(gao)流(ji)群:493584686
