它们具有相同的语义。
常数999
属于类型int
.
int i=999;
char c=i;
i
创建为类型的对象int
并初始化为int
value 999
,具有明显的语义。
c
被创建为类型的对象char
,并用值初始化i
,这恰好是999
。该值是从隐式转换而来的int
to char
.
平原的符号性char
是实现定义的。
如果平淡的话char
是无符号类型,转换的结果是明确定义的。该值按模减少CHAR_MAX+1
。对于 8 位字节的典型实现(CHAR_BIT==8
), CHAR_MAX+1
将是 256,存储的值将是999 % 256
, or 231
.
如果平淡的话char
是有符号类型,并且999
超过CHAR_MAX
,转换产生一个实现定义的结果(或者,从 C99 开始,引发一个实现定义的信号,但我知道没有实现这样做)。通常,对于 2 的补码系统CHAR_BIT==8
,结果将是-25
.
char c=999;
c
被创建为类型的对象char
。其初始值为int
value 999
转换成char
——按照我上面描述的完全相同的规则。
If CHAR_MAX >= 999
(只有当CHAR_BIT
,一个字节中的位数至少为 10),那么转换就很简单了。 DSP(数字信号处理器)有 C 实现,其中CHAR_BIT
例如,设置为 32。这不是您在大多数系统上可能遇到的情况。
在第二种情况下,您可能更有可能收到警告,因为它正在转换常量表达式;在第一种情况下,编译器可能不会跟踪预期值i
。但是,一个足够聪明的编译器可以对两者发出警告,而一个足够天真的(但仍然完全符合)编译器可以对两者都发出警告。
正如我上面所说,当源值不适合目标类型时,将值转换为有符号类型的结果是实现定义的。我认为实现可以为常量和非常量表达式定义不同的规则。不过,这将是一个不正当的选择。我不确定 DS9K 是否能做到这一点。
至于引用的注释“第一个是赋值,第二个是初始化”,这是不正确的。两者都是初始化;两个代码片段中都没有分配。区别在于,一种是用常量值初始化,另一种不是。顺便说一句,这意味着第二个片段可以出现在文件范围内的任何函数之外,而第一个片段则不能。