许多文本都警告说,将char
值作为整数处理是不可移植的,例如假设'A'的值是65(如ASCII)。
但是什么决定了这个字符集是ASCII(或扩展形式)还是其他一些字符集?它是由操作系统还是编译器决定的?我假设这不依赖于硬件。
例如,英特尔PC是否可以使用EBCDIC等字符集(理论上)?并且可以在Linux / Unix中更改LANG
环境变量来更改C程序的基本字符集的值(如果再重新编译)?
(编辑:我现在看到Linux中的各种非拉丁字符集都有相同的基本ASCII码,例如KOI8-U - 我假设有些变体的字符集与ASCII不兼容)< / p>
答案 0 :(得分:3)
C标准说:
§5.2.1/ 1在C99中
应定义两组字符及其关联的整理顺序:设置 写入哪些源文件(源字符集),以及在中解释的集合 执行环境(执行字符集)。每组进一步分为a 基本字符集,其内容由本子条款给出,以及一组零或更多 调用特定于语言环境的成员(不是基本字符集的成员) 扩展字符。组合集也称为扩展字符集。该 执行字符集的成员值是实现定义的。
在启动时,编译器必须使用C语言环境,它只会在调用setlocale(LC_ALL, "");
时获取操作系统的语言环境。
答案 1 :(得分:3)
标准并不关心任何这些细节,只要它关注的是只有“实施”。
实际上,硬件和操作系统都可以指定该平台上的C实现应该使用的实现细节,或者如果他们想要与系统功能互操作则需要 使用 (也就是说,随OS或硬件提供的代码)。所以我们经常说“在Win32上,sizeof(void*) == 4
”。这是一个简写,但是,因为有人可以,如果他们选择,编写一个在32位Windows上运行并具有不同指针大小的C实现。我们真正的意思是,“在Win32 ABI中,sizeof(void*) == 4
和在Win32上运行的不遵循Win32 ABI的C实现被排除在考虑之外”。
因此,实现可以做任何他们喜欢的事情,只要他们不介意他们是否可以(例如)使用遵循系统约定的dll。可以定义字符集,但编译器和标准库的编写者喜欢,只受标准内容的限制。
也就是说,字符文字的值是编译时常量。这告诉您基本执行字符集在运行时不能更改。
此外,如果它依赖于环境变量,那么确保程序以与编译时相同的值运行是有责任的。这对用户来说非常不友好,但标准实际上并没有禁止某人编写C实现,并对程序的运行方式有特殊的限制。
答案 2 :(得分:1)
编译器清楚地确定使用了哪个源和执行字符集,因为可以进行交叉编译(例如,编译在使用ASCII的Linux机器上使用EBCDIC的IBM大型机的代码)。