我有一个简短的问题.
如果我有一个像int x = 30;
这样的变量
我知道,值30被更改为一个4字节的整数,然后它判断值30是否存储到整数变量中;如果是,则它起作用.
如果我有int x = 3.08;
(它应该弹出一个错误),但3.08被更改为一个8字节的浮点数,那么它会判断该值是否存储在float
中,但它希望存储在int
中,所以它会弹出一个错误.
我的主要问题是:在将值放入变量之前,是否先将其解释为字节(位格式)?
我有一个简短的问题.
如果我有一个像int x = 30;
这样的变量
我知道,值30被更改为一个4字节的整数,然后它判断值30是否存储到整数变量中;如果是,则它起作用.
如果我有int x = 3.08;
(它应该弹出一个错误),但3.08被更改为一个8字节的浮点数,那么它会判断该值是否存储在float
中,但它希望存储在int
中,所以它会弹出一个错误.
我的主要问题是:在将值放入变量之前,是否先将其解释为字节(位格式)?
我有一个简短的问题.如果我有像int x=30这样的变量;
我知道值30被转换为4字节的整数,然后它判断值30是否存储到整数变量中,如果是,则它工作.
通过"存储到整型变量",我想你的意思是编译器查看x
的类型(这是一个int
)和初始化器30
的类型(这是一个int
常量),并判断它们是否满足什么类型可以用来初始化什么类型的规则.
这是正确的;编译器确实分析了所涉及的类型.然而,假设初始化式是int
,它不仅仅是判断被初始化的对象是不是int
.C标准规定,任何算术类型都可以用于初始化任何算术类型.您甚至可以使用复数来初始化int
,如int i = 3.0 + 4.0 * I;
.
如果我的int x=3.08(应该会弹出一个错误),但3.08被改为8字节的浮点数,那么它会判断该值是否存储在浮点数中,但它想要存储在int中,所以它会弹出一个错误.
虽然C标准允许使用任何算术类型来初始化任何算术类型,但它也允许编译器对可能包含错误的代码发出警告,即使该代码是该标准允许的,并且其行为已由C标准完全定义.这里就是这种情况;int x = 3.08;
不违反C标准中的约束,C标准也不需要任何诊断消息或错误,但编译器编写人员 Select 警告您,因为用double
常量初始化int
的代码可能是错误的,而不是故意 Select 的.
通常,这样的诊断消息可以通过提供给编译器的某个switch 来打开或关闭.此外,当编译器发出这样的消息时,通常有一种方法可以解决这一问题.例如,通过编写int x = (int) 3.08;
,我们可以告诉编译器我们正在故意将double
转换为int
,然后它将不会生成该诊断消息.
我的主要问题是:在将值放入变量之前,是否先将其解释为字节(位格式)?
对于编译器如何执行其工作的这一方面,没有必要的顺序.它必须分析代码,如果C标准要求或由其设计者 Select ,它必须产生诊断消息,它必须将源代码中的常量转换为表示它们的字节(或以其他方式提供),并且它必须安排将这些字节存储在对象中以供其初始化.它可以按不同的顺序做这些事情.(请注意,这些操作可以通过优化进一步更改,这超出了本答案的范围.)
此外,编译器的设计比您目前所认为的更具概念性.有一个完整的类型分析系统,它既独立于编译器的其他方面,也与编译器的其他方面交织在一起,例如将常量转换为表示它们的字节.根据我对编译器设计的一般知识,我认为编译器的词法分析器最有可能读取3.08
,将其转换为适当值的某种表示形式,并为编译器创建一个内部"标记",指示在源代码中的这一点上存在double
常量.然后更高级别的代码分析在这一点上拥有double
的后果是什么.
然而,完全有可能将编译器设计为使词法分析器读取3.08
,创建指示其中存在double
常量的标记,并将源文本"3.08"与该标记一起存储,并且编译器仅在对源代码进行进一步分析(包括判断类型规则)之后才将该"3.08"转换为浮点表示形式.
因此,编译器可以按任一顺序进行字节转换和类型判断.