运行以下内容时:
char acute_accent[7] = "éclair";
int i;
for (i=0; i<7; ++i)
{
printf("acute_accent[%d]: %c\n", i, acute_accent[i]);
}
我明白了:
acute_accent[0]:
acute_accent[1]: �
acute_accent[2]: c
acute_accent[3]: l
acute_accent[4]: a
acute_accent[5]: i
acute_accent[6]: r
这让我觉得多字节字符é
是2字节宽。
然而,当运行它时(在忽略编译器警告我multi-character character constant
之后):
printf("size: %lu",sizeof('é'));
我得到size: 4
。
不同尺寸的原因是什么?
编辑:这个问题与this不同,因为它更多地是关于多字节字符编码,不同的UTF及其大小,而不仅仅是对字符大小的理解。
答案 0 :(得分:2)
您看到差异的原因是因为在您的第一个示例中,编译器将字符é
编码为双字节UTF-8代码点0xC3 0xA9
。
见这里:
http://www.fileformat.info/info/unicode/char/e9/index.htm
如dbush所述,字符'é'
被编码为UTF-32码点并存储在整数中;因此它被表示为四个字节。
您的部分困惑源于通过以未定义的方式存储Unicode来使用实现定义的功能。
为了防止未定义的行为,您应该始终清楚地标识字符串文字的编码类型。
例如:
char acute_accent[7] = u8"éclair"
这是非常糟糕的表单,因为除非你自己计算,否则你无法知道字符串的确切长度,除非。事实上,我的编译器(g ++)对我大吼大叫,因为虽然字符串是7个字节,但总共有8个字节,最后是空字符。所以你实际上已经超出了缓冲区。
使用它更安全:
const char* acute_accent = u8"éclair"
注意你的字符串实际上是8字节:
#include <stdio.h>
#include <string.h> // strlen
int main() {
const char* a = u8"éclair";
printf("String length : %lu\n", strlen(a));
// Add +1 for the null byte
printf("String size : %lu\n", strlen(a) + 1);
return 0;
}
输出结果为:
String length : 7
String size : 8
另请注意, C和C ++之间的字符大小不同 !!
#include <stdio.h>
int main() {
printf("%lu\n", sizeof('a'));
printf("%lu\n", sizeof('é'));
return 0;
}
在C中,输出为:
4
4
在C ++中,输出为:
1
4
答案 1 :(得分:0)
来自C99 standard,第6.4.4.4节:
你机器上的2整数字符常量是一个或多个多字节的序列 用单引号括起来的字符,如'x'。
...
10整数字符常量的类型为int。
sizeof(int)
可能是4,这就是你得到这个结果的原因。
所以'é'
,'c'
,'l'
都是整数字符常量,因此所有类型都是int
,其大小为4.事实上有些是多字节的,有些是在这方面并不重要。