文章目錄
- 一.C語言的輸入輸出
- 1.printf
- i. 輸出整數
- ii. 浮點數
- iii.字符 & 字符串
- 2.scanf
- i.整數
- ii.浮點數
- iii. 字符 & 字符串
- 3.特殊用法
- i. * 的應用
- ii. %n 的應用
- iii. %[] 的應用
- 二.C++中的輸入輸出
- 1.cout
- i. 緩沖區(buffer)
- ii. cout之格式化輸出
- 2.cin
- i. cin.get()
- ii. cin.getline()
- iii. 流狀態
- 三.取消同步流
一.C語言的輸入輸出
在講 c++ 的輸入輸出之前,有必要先回顧一下最經典的 c 語言的輸入輸出 —— s c a n f ——scanf ——scanf 和 p r i n t f printf printf,他們被聲明在頭文件 #include <stdio.h>
中
scanf & printf
的優勢:
- 格式化輸入輸出
- 效率高
1.printf
p r i n t f printf printf 函數為格式輸出函數,其功能是按照用戶指定的格式,將指定的數據輸出到屏幕上:
printf("格式控制字符串", 輸出表項);
格式控制字符串有兩種:格式字符串、非格式字符串,非格式字符串在輸出的時候原樣打印;格式字符串是以 % \% % 開頭的字符串,后面跟不同格式字符,用來說明輸出數據的類型、形式、長度、小數位數等,就像一個模具,用來控制希望得到的物體的形態
類型 | 格式字符串 |
---|---|
int | %d |
float | %f |
double | %lf |
char | %c |
char[] | %s |
long long | %lld |
格式字符串的形式為:% [對齊方式][輸出最小寬度] [.精度] 類型
- 對齊方式:
-
表示左對齊,不填表示右對齊(沒有% +
的寫法),默認為右對齊,如% -d
,表示左對齊 - 最小寬度 N N N:當實際寬度小于 N N N時,用指定的字符填充剩余部分(默認以空格填充),使其長度為 N N N并輸出;當實際寬度大于 N N N時,按實際位數輸出,如
% 010d
,表示最小寬度為 10,不足部分用 0 填充 - 精度控制:這里精度表示保留小數點后幾位,如
%.2f
,表示保留小數點后兩位
i. 輸出整數
代碼實現:
#include<stdio.h>
int main()
{int a=100;printf("%d\n", a); //100printf("%5d\n", a); // 100printf("%05d\n", a); //00100printf("%.2d\n", a); //100.00return 0;
}
ii. 浮點數
浮點數有兩種類型: f l o a t 、 d o u b l e float、double float、double:
- f l o a t float float是單精度浮點數類型,通常在內存中占據 4 4 4個字節,它可以表示大約6到7位的有效數字
- d o u b l e double double是雙精度浮點數類型,通常在內存中占據 8 8 8個字節,它可以表示大約15到16位的有效數字
當使用 p r i n t f printf printf輸出時,若不控制精度,均默認保留至小數點后 6 6 6 位
代碼實現:
#include<stdio.h>
int main()
{float a=2.01;printf("%f\n", a); //2.010000printf("%.3f\n", a); //2.010printf("%10f\n", a); // 2.010000printf("%10.3f\n", a); // 2.010double b=5.01;printf("%lf\n", b); //5.010000printf("%.3lf\n", b); //5.010return 0;
}
iii.字符 & 字符串
const char*
和 char[]
都可以用來表示字符串:
const char*
是一個指向常量字符的指針,即指針指向的字符內容是不可更改的char[]
是一個字符數組,可以通過索引修改字符串
均可以通過 % s \%s %s 得到整個字符串
代碼實現:
#include<stdio.h>
int main()
{char a = 'A';printf("%c\n", a); //Aconst char* str="Hello World!";char buf[]="Hello World!";printf("%s\n", str); //Hello World!printf("%s\n", buf); //Hello World!return 0;
}
2.scanf
s c a n f scanf scanf 函數稱為格式輸入函數,即按照格式字符串的格式,從鍵盤上把數據輸入到指定的變量之中,其調用的基本格式為:
scanf("格式控制字符串",輸入項地址列表);
其中,格式控制字符串的作用與 p r i n t f printf printf函數相同,地址表項中的地址給出各變量的地址,地址是由地址運算符 &
后跟變量名組成的
🔺為什么需要加上取址符
&
?- 因為 s c a n f scanf scanf函數需要知道變量的內存地址才能將輸入的值存儲到正確的位置上,當我們使用 s c a n f scanf scanf函數時,我們需要將輸入的值存儲到一個變量中,而不是直接給出變量的名稱,通過使用
&
操作符,我們可以獲取該變量的內存地址,從而告訴 s c a n f scanf scanf函數將輸入的值存儲到這個地址所對應的內存位置上
特別地,對于數組而言,可以不用加 &
,因為數組名本身就是指向數組首地址的指針
s c a n f scanf scanf 的返回值:
s c a n f ( ) scanf() scanf() 函數返回成功讀入的項目的個數,如果它沒有讀取任何項目(比如它期望接收一個數字而實際卻輸入的一個非數字字符時就會發生這種情況),scanf()
則會返回 0 0 0
當它檢測到 文件末尾 (end of file)
時,它返回 E O F EOF EOF, E O F EOF EOF 在是文件 stdio.h
中的定義好的一個特殊值,通常 #define
指令會將 E O F EOF EOF 的值定義為 ? 1 -1 ?1,則可以結合 w h i l e while while 循環實現多行輸入,通常有兩種 c 的寫法:
while(scanf("%d",&a) != EOF)
while(~scanf("%d",&a))
代碼實現:
#include <stdio.h>
int main() {int a,b;while(scanf("%d %d", &a, &b) != EOF)printf("%d\n", a+b);return 0;
}
也就是說,若不按下 Ctrl+Z
,循環就不會結束
W i n d o w s Windows Windows允許通過鍵盤模擬文件尾: C t r l + Z Ctrl+Z Ctrl+Z
i.整數
代碼實現:
#include <stdio.h>
int main(){int a, b;scanf("%d %d",&a, &b); //1 2printf("%d,%d\n", a, b); //1,2return 0;
}
ii.浮點數
代碼實現:
#include <stdio.h>
int main(){double c, d;scanf("%lf %lf", &c, &d); //1 2printf("%.2lf,%.3lf\n", c, d); //1.00,2.000return 0;
}
iii. 字符 & 字符串
- 輸入單個字符
代碼實現:
#include<stdio.h>
int main(){char e, f;scanf("%c %c", &e, &f); //a bprintf("%c,%c\n", e, f); //a,breturn 0;
}
- 利用
%s
輸入字符串
🔺注意:%s 輸入遇到空格或者回車就會停下(截斷)
#include<stdio.h>
int main(){char s[10];scanf("%s", s);printf("%s", s);return 0;
}
輸出結果:
- 利用正則表達式輸入字符串
[]
是正則表達式,表示只要不是回車就讀入字符串(空格不會截斷)
#include<stdio.h>
int main(){char s0[15];scanf("%[^\n]", s0);printf("%s", s0);return 0;
}
輸出結果:
3.特殊用法
i. * 的應用
① ′ ? ′ '*' ′?′ 在 p r i n t f printf printf 中的應用
控制寬度和精度:假如在輸出時,不想事先指定字段寬度 / / /精度,而是希望由程序來制定該值,則可以在字段寬度 / / /精度部分使用 *
代替數字來達到目的,同時需要在后面多增加一個參數來告訴函數寬度 / / /精度的值是多少,具體的說,如果轉換說明符為%*d
,那么參數列表中應該包括一個*
的值和一個d
的值,來控制寬度 / / /精度和變量的值
代碼示例:
#include<stdio.h>
int main(void)
{printf("%0*d\n", 5, 10); //00010printf("%.*f\n", 2, 10.12345); //10.12printf("%*.*f\n", 5, 1, 10.0); // 10.0return 0;
}
② ′ ? ′ '*' ′?′ 在 s c a n f scanf scanf 中的應用
忽略賦值:*
在 s c a n f scanf scanf 函數中通常用來指定忽略某個輸入值的賦值,這在處理輸入時非常有用,因為有時候我們可能只想跳過一些輸入,而不需要將其賦值給特定的變量
例如:有以下的輸入數據 “10 20”,但是我們只想讀取第二個整數而不關心第一個整數,則可以使用 *
:
#include <stdio.h>
int main(){int num;scanf("%*d %d", &num); //10 20printf("%d", num); //20return 0;
}
ii. %n 的應用
① % n \%n %n 在 p r i n t f printf printf 中的應用
統計字符數: p r i n t f ( ) printf() printf() 中,%n
是一個特殊的格式說明符,它不打印某些內容,而是會將目前為止打印輸出字符的數量存儲到參數列表中指向的變量中
代碼示例:
#include<stdio.h>
int main()
{int k=0;printf("hello %nworld", &k); //輸出 hello worldprintf("%d",k); //6return 0;
}
② % n \%n %n 在 s c a n f scanf scanf 中的應用
統計字符數: s c a n f ( ) scanf() scanf() 中,%n
會將目前為止讀入字符的數量存儲到參數列表中指向的變量中
代碼示例:
#include <stdio.h>
int main() {char str[100];int count;scanf("%s%n", str, &count); //abcdprintf("%d\n", count); //4return 0;
}
iii. %[] 的應用
常見用法:
%[0-9]
: 表示只讀入’0’到’9’之間的字符%[a-zA-Z]
: 表示只讀入字母%[^\n]
: 就表示讀入除換行符之外的字符,^ 表示除…之外%k[^=]
: 讀入"="號前的至多 k k k個字符
當讀取到范圍之外的字符時,就會做截取,也就是之后的數據將不會放入字符串中
代碼示例:
//1
#include <stdio.h>
int main() {char number[10];scanf("%[0-9]", number); //123abcprintf("%s\n", number); //123return 0;
}//2
#include <stdio.h>
int main() {char letters[20];scanf("%[a-zA-Z]", letters); //abc121efgprintf("%s\n", letters); //abcreturn 0;
}//3
#include<stdio.h>
int main(){char s0[15];scanf("%[^\n]", s0); //123abc abcprintf("%s", s0); //123abc abcreturn 0;
}//4
#include <stdio.h>int main() {char str[20];scanf("%10[^=]", str); //123=abcprintf("%s\n", str); //123return 0;
}
二.C++中的輸入輸出
現在來到 C++ 中,其輸入輸出通過頭文件 #include <iostream>
來完成,其命名空間為 s t d std std
流( S t r e a m Stream Stream)是一個抽象概念,用于表示數據的序列,它可以是從一個地方到另一個地方的數據傳輸通道,流可以用于從文件、內存、網絡或其他設備中讀取數據,也可以用于向這些地方寫入數據,而 C++ 的 I / O I/O I/O 就是發生在流:
- 輸入流( i s t r e a m istream istream):用于從數據源中讀取數據,比如從鍵盤讀取用戶輸入、從文件中讀取數據、從網絡連接中讀取數據等
- 輸出流( o s t r e a m ostream ostream):用于向目標位置寫入數據,比如將數據輸出到屏幕、寫入到文件、發送到網絡等
1.cout
cout
是 C++ 標準庫中的標準輸出流對象
cout << "hello world" << endl;
<<
是輸出運算符,左側必須是 o s t r e a m ostream ostream 對象,右側是要打印的值:此運算符將給定的值寫到給定的 o s t r e a m ostream ostream 對象中,計算結果就是我們寫入給定值的那個 o s t r e a m ostream ostream 對象
cout
是一個輸出對象,輸出語句本質上就是不斷創造 o s t r e a m ostream ostream 對象的過程,第一個計算的結果是第二個的輸入,從而形成鏈條,最終將所有信息輸出到屏幕上,例如:
cout << "hello" << endl;
等價于
1.cout << "hello";
2.cout << endl;
第一個 <<
給用戶打印一條消息,這個消息是一個字符串字面值常量,在雙引號之間的文本會被打印到標準輸出;第二個 <<
打印 endl
,這是一個被稱為操作符的特殊值,寫入 endl
的效果是結束當前行,并將與設備關聯的緩沖區中的內容刷到設備中
i. 緩沖區(buffer)
當程序向輸出設備(比如屏幕、打印機)輸出數據時,數據通常不是立即傳遞到設備上,而是先存儲到緩沖區中,這樣做的好處是可以減少向設備頻繁傳輸數據的開銷,而是利用緩沖區將數據一次性傳輸,從而提高效率,類似地,當數據從輸入設備(比如鍵盤、網絡)輸入進來時,也會先存儲到輸入緩沖區中,程序可以逐步讀取這些數據。
在 C++ 中,對于標準輸出流 c o u t cout cout,也存在一個輸出緩沖區,當程序使用 c o u t cout cout 進行輸出時,數據首先被存儲在輸出緩沖區中,直到緩沖區滿了或者遇到顯式的刷新操作時,數據才會被真正輸出到屏幕上:
- 使用
std::flush
操縱符:手動刷新輸出緩沖區 - 輸出末尾添加
std::endl
:自動刷新緩沖區并插入換行符
ii. cout之格式化輸出
通過 #include <iomanip>
頭文件來實現格式化的輸出:
std::setw(int n)
: 設置域寬為 n n n,默認為右對齊std::setprecision(int n)
: 設置浮點數的精度為 n n n 位小數std::setfill(char c)
: 設置填充字符為 c c cstd::left
: 設置輸出在設定的寬度內左對齊std::right
: 設置輸出在設定的寬度內右對齊std::boolalpha
: 將布爾類型的輸出從 0 / 1 0/1 0/1 改為 t r u e / f a l s e true/false true/falsestd::hex
: 以十六進制形式輸出值std::oct
: 以八進制形式輸出值std::dec
: 以十進制形式輸出值
代碼示例:
#include <iostream>
#include <iomanip>int main() {int n = 255;double pi = 3.1415926;std::cout << "Default: " << n << " " << pi << std::endl;std::cout << "setw: " << std::setw(10) << n << " " << std::setw(10) << pi << std::endl;std::cout << "setprecision: " << std::setprecision(4) << n << " " << std::setprecision(3) << pi << std::endl;std::cout << "setfill: " << std::setfill('*') << std::setw(10) << n << " " << std::setfill('#') << std::setw(10) << pi << std::endl;std::cout << "left/right: " << std::left << std::setw(10) << n << std::right << std::setw(10) << pi << std::endl;std::cout << "boolalpha: " << std::boolalpha << true << " " << false << std::endl;std::cout << "Hex/Oct/Dec: " << std::hex << n << " " << std::oct << n << " " << std::dec << n << std::endl;return 0;
}
輸出結果:
2.cin
cin
是 C++ 標準庫中的標準輸入流對象,在查看輸入流的時候, c i n cin cin 會自動跳過空白(空格,換行符,制表符)直到遇到非空白字符
int a, b;
cin >> a >> b;
>>
是輸入運算符,其左側為一個 i s t r e a m istream istream 運算對象,再接受一個變量作為右側運算對象,可以連續讀取多個數據,并將它們存儲到不同的變量中
一些簡單代碼示例:
- 整數
#include <iostream>
using namespace std;
int main(){int a, b;cin >> a >> b;cout << a << ' ' << b << endl;return 0;
}
- 浮點數
#include <iostream>
using namespace std;
int main(){double c, d;cin >> c >> d;cout << fixed << setprecision(3) << c << ' ' << d << endl; //保留三位有效數字return 0;
}
- 單個字符
#include <iostream>
using namespace std;
int main(){char ch;cin >> ch;cout << ch << endl;return 0;
}
- 字符串
#include <iostream>
using namespace std;
int main(){char str[10];cin >> str; //cin輸入字符串也是遇到空格或回車就會結束cout << str << endl;return 0;
}
🔺注意: c i n > > cin>> cin>> 接受一個字符串時,遇到 ‘空格’、‘ t a b tab tab’、'回車’就會結束,當需要輸入包含空格的整行文本時,可以使用 std::getline
函數來讀取輸入流,而不是直接使用 >>
運算符,這樣可以確保整行文本被完整地存儲到字符串中
getline(cin, string)
:
- 頭文件:
#include <string>
- 第一個參數是輸入流(比如 s t d : : c i n std::cin std::cin 或文件流),第二個參數是用來存儲讀取的文本的字符串
代碼示例:
#include <iostream>
#include <string>
using namespace std;
int main(){string s;getline(cin, s); //可以實現整行輸入cout << s << endl;return 0;
}
i. cin.get()
① cin.get(字符變量名)
:
- 每次接受單個字符,逐個字符讀取
- 當讀取的輸入流有空格或回車時,會讀取空格或回車,并將其視為普通字符,而不會將其作為流結束的標志來處理: A S C I I ASCII ASCII 中,空格 ? 32 -32 ?32,回車 ? 10 -10 ?10
代碼示例:
#include <iostream>
using namespace std;
int main (){char a, b;cin.get(a);cin.get(b);cout<<a<<" "<<b<<endl;cout<<(int)a<<" "<<(int)b<<endl;return 0;
}
輸出:
示例1:輸入 a[回車]
a
a97 10
結果得到的是字母 a 和 換行符(\n)示例2:輸入 a[空格]b[回車]
a b
a
97 32
結果得到的是字母 a 和 空格符
② cin.get(字符數組名,接收字符數目,結束符)
:
- 接收一定長度的字符串
- 接受字符數目:如
cin.get(s, 5)
會讀取最多 5 5 5 個字符到數組 s s s 中,并且在必要時加上空字符'\0'
以表示字符串的結束,也就是說,實際讀取的長度會減 1 1 1,因為結尾的'\0'
占了一位 - 結束符:默認為回車
'\n'
,也就是說,可以接受空格,不接受回車,但不讀取不代表丟棄,回車仍然在輸入緩沖區內
代碼示例:
#include <iostream>
using namespace std;
int main (){char ch1,ch2[10];cin.get(ch2,5); //在不遇到結束符的情況下,最多可接收5-1=4個字符到ch2中,注意結束符為默認Entercin.get(ch1); //讀取單個字符cout<<"ch2="<<ch2<<endl;cout<<ch1<<"="<<(int)ch1<<endl;return 0;
}
輸出:
示例1:輸入 a[回車]
a
ch2=a=10
由于第二個就讀取到了換行符,因此直接結束,之后換行符被第二個 cin.get() 讀取示例2:輸入長度為 7 的字符串 abcdefg
abcdefg
ch2=abcd
e=101
③ cin.get()
:
- 無參數,可用于舍棄輸入流中的不需要的字符,或者舍棄回車
'\n'
,彌補cin.get(字符數組名,字符數目,結束符)
的不足
代碼示例:
#include <iostream>
using namespace std;
int main()
{char ch1,ch2[10];cin.get(ch2,5);cin.get(); //舍棄一個緩沖區中的字符cin.get(ch1);cout<<ch2<<endl;cout<<ch1<<"\n"<<(int)ch1<<endl;return 0;
}
輸出:
示例1:輸入長度為 7 的字符串
abcdefg
ch2=abcd
f=102
結果表明,第二個 cin.get() 跳過了字符 'e',使得第三個 cin.get() 讀取到了 'f'示例2:輸入 1a[回車]bcdef
1a
bcdef
ch2=1a
b=98
同理,第二個 cin.get() 跳過了換行符
ii. cin.getline()
cin.getline(字符數組名,接收長度,結束符)
與 cin.get(...)
的用法極為類似,但存在幾個🔺注意點:
- c i n . g e t ( ) cin.get() cin.get() 當輸入的字符串超長時,不會引起 c i n cin cin 函數的錯誤,后面若有 c i n cin cin 操作,會繼續執行,只是直接從緩沖區中取數據,但是 c i n . g e t l i n e ( ) cin.getline() cin.getline() 當輸入超長時,會引起 c i n cin cin 函數的錯誤,后面的 c i n cin cin 操作將不再執行
代碼示例:
#include <iostream>
using namespace std;
int main()
{char ch1, ch2[10];cin.getline(ch2, 5);cin>>ch1;cout<<ch2<<endl;cout<<ch1<<"\n"<<(int)ch1<<endl;return 0;
}
輸出結果:
可以看到,此時出現輸入超長, c h 2 = 1234 ch2=1234 ch2=1234,此時緩沖區剩余:5[回車]
,但是結果得到了 0 0 0(g++環境下),說明 c i n cin cin 已失效!
- c i n . g e t ( ) cin.get() cin.get() 每次讀取一整行并把由
Enter鍵
生成的換行符'\n'
留在輸入隊列中,然而 c i n . g e t l i n e ( ) cin.getline() cin.getline() 每次讀取一整行后會將換行符'\n'
丟棄 !
代碼示例:
#include <iostream>
using namespace std;int main() {cout << "Enter your name:";char name[15];cin.getline(name, 15); //輸入xjc(enter)cout << "name:" << name << endl;char ch;cin.get(ch); // 輸入123(enter) 注:因為cin.getline把最后一個換行符丟棄了,所以此處ch讀取字符'1'cout << ch << "=" << (int)ch << endl; //輸出49 '1'的ASCII碼值return 0;
}
輸出結果:
iii. 流狀態
流狀態是顧名思義就是輸入或輸出流的狀態, c i n cin cin 和 c o u t cout cout 對象都包含了一個描述流狀態的變量( i o s t a t e iostate iostate 類型),它由三個元素組成: e o f b i t , f a i l b i t , b a d b i t eofbit,failbit,badbit eofbit,failbit,badbit,其中每一個元素都由一位來表示( 1 1 1代表是, 0 0 0代表否)
成員 | 描述 |
---|---|
eofbit | 到達文件尾則此位設置為1 |
badbit | 如果流被破壞則此位設置為1 |
failbit | 如果輸入未能讀取預期的字符或輸出操作沒有寫入預期字符,則此位設置為1 |
goodbit | 流狀態正常,也代表所有位為 0 即表示 0 |
good() | 如果流正常則返回 true |
eof() | 如果 eofbit 為 1 返回 true |
bad() | 如果 badbit 為 1 返回 true |
fail() | 如果 badbit 或 failbit 為 1 返回 true |
rdstate() | 返回流狀態 |
exceptions() | 返回一個位掩碼,指出哪些標記將導致異常發生 |
exceptions(iostate ex) | 設置哪些狀態將導致 clear() 引發異常 |
clear(iostate s) | 將流狀態設置為 s,s 默認為 0 即goodbit |
setstate(iostate s) | 設置與 s 中對應位的流狀態,其他位保持不變,相當于用 s 與 當前流狀態做 “或運算” |
來看一個緩沖區未讀取完,導致 f a i l b i t = 1 failbit=1 failbit=1 的例子:
#include <iostream>
using namespace std;int main()
{
char ch, str[20];cin.getline(str, 5);cout<<"flag:"<<cin.good()<<endl; // 查看goodbit狀態,即是否有異常cin.clear(); // 清除錯誤標志cout<<"flag:"<<cin.good()<<endl; // 清除標志后再查看異常狀態cin>>ch;cout<<"str:"<<str<<endl;cout<<"ch :"<<ch<<endl;system("pause");return 0;
}
輸出結果:
可以看出,因輸入緩沖區未讀取完造成輸入異常 cin.good()=false
通過cin.clear()
可以清除輸入流對象 c i n cin cin的異常狀態,不影響后面的 cin>>ch
從輸入緩沖區讀取數據,因為 cin.getline
讀取之后,輸入緩沖區中殘留的字符串是:5[回車]
,所以 c i n > > c h cin>>ch cin>>ch 將 5 5 5 讀取并存入 c h ch ch,打印輸入并輸出 5 5 5
如果沒有 cin.clear()
,cin>>ch
將讀取失敗, c h ch ch 為空
輸出結果:
三.取消同步流
在算法題中,涉及到大量數據讀入的時候,通常避免使用cin
讀入數據而改用scanf
,原因是scanf
相對速度更快
🚀解決方法:
-
c i n cin cin 效率低的原因一是在于默認 C++ 中的 c i n cin cin (輸入流對象) 與 C語言中的 s t d i n stdin stdin (輸入流指針) 總是保持同步, c i n cin cin 會把要輸出的東西先存入緩沖區,進而消耗時間,通過關閉同步,可以有效提高 c i n cin cin 效率,可以用
sync_with_stdio(0)
實現異步 -
默認情況下 c i n cin cin 綁定的是 c o u t cout cout,每次執行
<<
的時候都要調用 f l u s h flush flush,當cout
的緩沖區刷新的時候,cin
的緩沖區由于綁定的存在也同時進行了刷新,進而增加 I / O I/O I/O 負擔,因此可以通過tie(0)
解綁
關閉同步后, c i n cin cin 的速度將與 s c a n f scanf scanf 相差無幾:
int main(){//取消同步流ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);//其余操作不變int x;cin >> x;cout << x;system("pause");return 0;
}
🔺注意:
- 關閉同步之后請不要同時使用C與C++的讀寫方式,避免不必要的麻煩,如
printf(),scanf(),gets(),pus(),getchar()
不要與cin,cout
共用 - c o u t cout cout 中不要使用 e n d l endl endl,每次使用 e n d l endl endl,都要 f l u s h flush flush 緩沖區,造成大量時間耗費
ch$ 為空