#include "stdio.h"

int main(void)
{
char s[] = "你好";
printf("%d %s
",sizeof(s),s);
return (0);
}

輸出

5 你好

--------------------------------

Process exited after 0.04922 seconds with return value 0請按任意鍵繼續. . .


對其他人的答案做一些補充吧。

Unicode 與 UTF-8

Unicode 本質上是一種標準,他描述了一個字符集裏都有什麼字元。

而 UTF-8、GBK、UTF-16 等是對 Unicode 的實現,他們採用了不同的映射關係來編碼字元。

以 UTF-8 為例,在 UTF-8 中,一個漢字一般採用兩個代碼單元(code unit)來編碼一個代碼點(code point)。

代碼點(code point)指的是一個字元對應的編碼表示,而這個編碼表示可能是一個位元組,也可能是兩個位元組,或更多。

對於 UTF-8 來說,他使用一個位元組來描述一個代碼單元,也就是說,一個代碼點可以由一個或多個代碼單元表示。

為什麼要這麼做?因為 UTF-8 是一種非常巧妙的字符集,他通過其巧妙的編碼方式實現了代碼點可變長這一特點。

對於 ASCII 字元僅使用一個位元組儲存,而對於某個漢字則可能使用兩個位元組,節省空間。


這東西應該和具體的環境有關。

在VisualStudio默認情況下,是GBK編碼,兩個位元組存一個漢字,因此如果引用不慎會造成亂碼。

#include &

int main()
{
unsigned char s[] = "你好";
unsigned char* p = s;

while (0 != *p)
{
printf("%x ",*p);
p++;
}
/*
* 輸出: c4 e3 ba c3
* 對應地址: s s+1 s+2 s+3
* 編碼: 你 : c4e3
* 好 : bac3
*/

printf("%s",s);
/*
* 輸出: 你好
* 註: 程序正常操作
*/

printf("%s", s+1);
/*
* 輸出: 愫胅
* 註: 輸出了亂碼,同時程序直接退出。要運行後面的程序應將本行語句注釋掉。
*/

printf("%s",s+2);
/*
* 輸出: 好
* 註: 正常運行。因為此處所用地址為s+2,只列印了好字元
*/

return 0;
}

同時,請看

譚九鼎:C語言與中文的一些測試 (Win, UTF8源碼)?

zhuanlan.zhihu.com圖標

每個漢字在特定的字符集中有一個唯一的「」索引「」,程序代碼中實際上記錄的是這個「索引」。

gb2312字符集中每個漢字的索引佔2個位元組。

utf8字符集中,每個漢字的索引佔2-4個位元組。

同樣的一段代碼,以gb2312格式存儲和以utf8格式存儲,字元串中記錄的內容不一樣的。

下面的代碼放到main函數中,分別存成gb2312和utf8編譯運行看結果。

int i;

char xcodw[] = "您好";

printf("%d,%s
", sizeof(xcode), xcode) ;

for(i=0;i&

printf("%x ", 0xff xcode[i]) ;


首先,不論漢字還是其它字元,存儲到內存都是要經過特定編碼方式編碼的。

比如,常見的「GBK」編碼方式裏,「知乎」二字的編碼分別是「知(D6AA)乎(BAF5)」,C語言的字元串按逐個位元組的方式存儲「知乎」,就是把上面的GBK編碼(D6AA)和(BAF5)存儲到內存裡面,由於「知乎」每個字佔用了兩個位元組的空間,所以共需要四個位元組的空間來存儲。

當然,不同的編碼方式,每個字元佔用的內存空間大小可能是不同的,只是上面提到的「GBK」編碼方式裡面,漢字通常佔用兩個位元組的空間。


推薦閱讀:
相關文章