1、char類型
char
的全稱是character
,也就是字符的意思。顧名思義,char
類型是專門為了存儲字符而設計的。
計算機存儲數字非常方便,只需要將其轉化成二進制即可。但存儲字符就有點麻煩了,一般都是通過對字符進行數字化編碼。這也就是為什么char類型本質上是另外一種整數,因為它存儲的其實是字符的數字編碼。
char
一共有8個二進制位,即一個字節,理論上能夠存儲256個字符。基本上足夠涵蓋計算機當中所有的字母、標點符號以及數字,即ASCII
碼。
ASCII的全稱是美國信息交換標準代碼,它是一套電腦編碼系統,包含了所有英文字母以及標點符號和一些特殊字符。全表一共有128個字符,剛好可以用一個char
(有符號)來存儲。
大家可以參考一下下表,Dec表示編號,Char
表示字符。
其中數字0的編號是48,字母a的編號是97,大寫字母A的標號是65。
當我們把一個字符賦值給char
型變量的時候,它會去查ASCII
表,找到字符對應的編號。同樣,當我們使用%c輸出一個字符的時候,它也會去尋找char
中存儲的編碼對應的符號進行輸出。
既然字符在C++
當中都是以數字的形式存儲的,那么我們就可以對它來進行加減運算。
比如:
char c = "a"; cout << ++c << endl;
得到的結果是"b",有加自然也有減,我們也可以對它做減法操作。
char c = "b"; cout << --b << endl;
得到的結果就是"a"。
另外,我們還可以對于兩個char
類型的變量進行減法操作。比如用得比較多的就是將字符型的數字轉成int型。
char c = "1"; int num = c - "0";
這樣我們得到的num
就是數字型的1。
再比如,我們還可以通過大于小于符號來判斷char類型的范圍:
char c = "1"; if (c >= "0" && c <= "9") { cout << "c is a number" << endl; }
2、getchar、putchar、cin.get、cout.put
getchar
和putchar
都是C語言當中專門面向字符IO的函數,也就是讀入和輸出字符的函數。
因為確定了處理的數據類型是字符,不需要額外的格式說明,因此getchar
和putchar
的效率要比scanf
和printf更高。
所以在算法競賽領域,有人為了提升程序的性能,喪心病狂地使用getchar
代替scanf
來讀入數據。
我這里貼一段使用getchar
來讀入int型的代碼,給大家做一個參考。這個屬于標準的奇淫技巧,不推薦使用。
void read(int &x) { int f = 1; x = 0; char s = getchar(); while (s < "0" || s > "9") { if (s == "-") { f = -1; s = getchar(); } } while (s >= "0" && s <= "9") { x = x * 10 + s - "0"; s = getchar(); } x *= f; }
cin.get
和cout.put
與getchar
和putchar
的用法類似,只不過是C++當中的特性。大家可以參考一下下面這個例子,就不過多贅述了。
char c; cin.get(c); cout.put(c);
3、輸入輸出中文
關于這一段我猶豫了很久要不要加,因為實在是沒有相關經驗,畢竟之前只刷題了。糾結了很久還是決定寫上,因為這個問題對于不少同學應該挺重要的,尤其是想要做C++工程的同學。本人水平有限,勉強整理了一下各方資料,如有錯誤,歡迎指出~
其實直接在C++當中是可以直接輸出中文的,這并不會有什么問題。
比如下列代碼,是可以完美運行的:
string str; cin >> str; cout << str << endl; cout << str.length() << endl;
只是為什么最后輸出的長度是6?因為我是在Mac
上跑的這段代碼。在Mac
當中默認使用utf-8
編碼,一個漢字的長度是3個字節。C++當中的字符串計算長度的時候統計的是字節的數量,所以兩個漢字的長度是6。
如果我們是在源代碼當中寫入了中文,比如:
string str = "中文"; cout << str << endl;
這就可能一些問題,最常見的問題就是代碼存儲環境和運行環境的默認編碼不同,比如IDE當中默認是utf-8
編碼,但是終端默認是gbk編碼(windows
系統常見)。這就會導致輸出的結果是亂碼。
解決方案是我們可以使用wchar_t,wchar_t
即char
的寬類型版本,它占據兩個字節。可以用來存儲unicode
編碼的字符:
const wchar_t* str = L"中文";
我們在中文兩個字之前加上了L修飾符,它告訴編譯器,這是一個寬字符,我們需要編譯器根據locale來進行翻譯。
locale是指根據計算機用戶使用的語言、所在的國家或地區以及文化傳統而定義的軟件運行時的語言環境。可以將locale
理解為一系列環境變量。locale
環境變量值的格式為language_area.charset。languag
表示語言,例如英語或中文;area
表示使用該語言的地區,例如美國或者中國大陸;charset表示字符集編碼,例如UTF-8
或者GBK
。
這些環境變量會對日期格式,數字格式,貨幣格式,字符處理等多個方面產生影響。在Linux
系統下打開Terminal
,輸入locale
命令,就可查看當前系統使用的語言環境。
locale
的結果包含12類,我在網上也找到了表格:
LANG
指的是未設置的默認值,大部分程序應用LANGUAGE
指定的語言作為界面語言。LC_ALL
同時設置所有的內容,并且其優先級比每個內容單獨設置的優先級都高,而LANG
的優先級最低。
cin
和cout
可以看成是針對char
的流,所以不適合應用在wchar_t
類型的處理上。與之對應我們應該使用wcin和wcout
。而wcout
默認采用的是C local
,并不認識中文,所以我們要先對wcout
的local
進行設置。將其設置成和運行環境的local一致。
大約有以下幾種設置方法:
#include <codecvt> const wchar_t* str = L"中文"; // 使用默認local locale loc(""); wcout.imbue(loc); // 使用local命令顯示的結果 locale loc("en_US.UTF-8"); wcout.imbue(loc); // 使用標準facet locale utf8(locale(), new codecvt_utf8_utf16<wchar_t> ); wcout.imbue(utf8); // 使用系統local locale sys_loc(""); wcout.imbue(sys_loc); wcout << str << endl; cout << wcslen(str) << endl;
我們可以使用wcslen
來計算寬字節字符串的長度,它輸出的結果是2,而不是6。
C++當中的編碼設置是一個很大的問題,因為在刷題當中幾乎不會遇到,我們這里也只是做一個淺嘗輒止的討論。大家如果有需要,可自行深入研究。
到此這篇關于C++char類型和輸入輸出優化的文章就介紹到這了,更多相關C++char類型和輸入輸出優化內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
注:文章轉自微信公眾號:Coder梁(ID:Coder_LT)