有人可以清楚地解释K& R的这些行实际上意味着什么:
“当char转换为int时,它是否会产生负数 整数?答案因机器而异。的定义 C保证机器的标准打印中的任何字符 字符集永远不会是负面,而是任意位模式 存储在字符变量中的某些字符可能看起来是负数 机器,但对其他人肯定“。
答案 0 :(得分:1)
标准中有两个或多或少的相关部分 - ISO / IEC 9899:2011。
6.2.5类型
¶3声明为类型
char
的对象足以存储基本的任何成员 执行字符集。如果基本执行字符集的成员存储在a中char
对象,其值保证为非负值。如果存储了任何其他字符 一个char
对象,结果值是实现定义的,但应在范围内 可以用该类型表示的值。¶15统称为
char
,signed char
和unsigned char
三种类型 字符类型。实现应将char
定义为具有相同的范围, 表示和行为为signed char
或unsigned char
。 45)CHAR_MIN
中定义的45)
<limits.h>
将具有值0
或SCHAR_MIN
中的一个,这可以是 用来区分这两个选项。无论做出何种选择,char
都是一个独立的类型 另外两个并且与两者都不兼容。
这定义了你对K&amp; R所说的引用。其他相关部分定义了基本执行字符集是什么。
5.2.1字符集
¶1应定义两组字符及其相关的整理顺序:设置 写入哪些源文件(源字符集),以及在中解释的集合 执行环境(执行字符集)。每组进一步分为a 基本字符集,其内容由本子条款给出,以及一组零或更多 调用特定于语言环境的成员(不是基本字符集的成员) 扩展字符。组合集也称为扩展字符集。该 执行字符集成员的值是实现定义的。
¶2在字符常量或字符串文字中,执行字符集的成员应为 由源字符集的相应成员或转义表示 序列由反斜杠
\
后跟一个或多个字符组成。一个字节 所有设置为0的位,称为空字符,应存在于基本执行字符集中;它 用于终止字符串。¶3基本源和基本执行字符集应具有以下内容 成员:拉丁字母的26个大写字母
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
拉丁字母的26个小写字母
a b c d e f g h i j k l m n o p q r s t u v w x y z
10个十进制数字
0 1 2 3 4 5 6 7 8 9
以下29个图形字符
! " # % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~
空格字符,控制字符表示水平制表符,垂直制表符和 形式饲料。源和执行的每个成员的表示基本 字符集应该适合一个字节。在源和执行基本字符集中, 上述小数位数列表中
0
之后的每个字符的值应大于1 以前的价值。在源文件中,应该有一些表示结束的方法 每行文字;本国际标准对待这样的终端指标就像它一样 是一个单行字符。在基本执行字符集中,应该有 控制表示警报,退格,回车和新行的字符。如果有的话 在源文件中遇到其他字符(标识符,字符除外) 常量,字符串文字,标题名称,注释或从不的预处理标记 转换为令牌),行为未定义。¶4字母是上面定义的大写字母或小写字母;在这个国际 标准术语不包括其他字母表中其他字母的其他字符。
¶5通用字符名称构造提供了一种命名其他字符的方法。
这些规则的一个结果是,如果一台机器使用8位字符和EBCDIC编码,则普通char
必须是无符号类型,因为数字在EBCDIC中具有代码240..249。
答案 1 :(得分:0)
你需要先了解好几件事。
如果我取一个8位值并将其扩展为16位值,通常你会想象只是在左边添加一堆0。例如,如果我有8位值23,二进制为00010111,那么作为16位数字,它是0000000000010111,也是23。
事实证明,负数在高位中始终为1。 (可能有奇怪的机器不适用于此,但对于您可能使用的任何机器都是如此。)例如,8位值-40以二进制表示为11011000。
因此,当您将带符号的8位值转换为16位值时,如果高位为1(即,如果该数字为负数),则不添加一堆0 -s在左边,你添加一堆1代替。例如,回到-40,我们将11011000转换为1111111111011000,这是-40的16位表示。
还有无符号数字,永远不会消极。例如,8位无符号数216表示为11011000.(您将注意到这是与带符号数-40相同的位模式。)当您将无符号8位数转换为16位时,添加无论如何,一堆0。例如,您可以将11011000转换为0000000011011000,这是216位的16位表示。
所以,把这一切放在一起,如果你要将8位数转换成16位(或更多位),你必须看两件事。首先,是签名还是未签名?如果它是无符号的,只需在左侧添加一堆0。但如果签名,你必须查看8-0位数的高位。如果它为0(如果数字为正),则在左侧添加一堆0。但如果它是1(如果数字是负数),在右边添加一堆1。 (整个过程称为符号扩展。)
普通的ASCII字符(如“A”,“1”和“$”)都具有小于128的值,这意味着它们的高位始终为0.但是“特殊”字符来自“Latin-1”或UTF-8字符集的值大于128.因此,它们有时也称为“高位”或“第八位”字符。例如,Latin-1字符Ø(带斜线的O)的值为216.
最后,虽然C中的类型char
通常是8位类型,但 C标准不指定它是有符号还是无符号。
总而言之,Kernighan和Ritchie所说的是当我们将char
转换为16位或32位整数时,我们不太清楚如何应用第5步。如果我' m在类型char
未签名的机器上,我取字符Ø并将其转换为int,我可能得到值216.但如果我在类型为{{1}的机器上}签名,我可能会得到数字-40。