从应用程序员的角度来看,类型转换只是起作用。使用某种语法,整数的无符号表示可以充当小于INT_MAX的有符号整数值。执行这些转换的算法是什么?它们的时间复杂度是多少?是否存在执行转换的现代指令集体系结构的专用项,或者编译器是否知道一系列指令?如果类型转换在内部工作中存在平台依赖性,那么这些差异是否会泄漏到类型转换的影响中?
答案 0 :(得分:6)
C语言在“类型转换”的相同语法下混淆了两个不同的进程。第一种是简单地以两种不同的方式解释同一组位。这就是发生的情况,例如,当您将signed int转换为unsigned int时。实际上没有任何变化,您只需告诉编译器以不同的方式解释这些位。例如,表达式a < b
可能会导致生成与a < (unsigned)b
不同的代码,即使转换本身实际上对b
本身的位没有任何作用。
同样地,指向事物的指针可以转换为指向不同事物的指针,但它们仍然只是内存地址,并且除了编译器执行指针数学和解除引用等操作之外,强制转换实际上不会改变任何其他内容。 / p>
C错误地称为类型转换的另一个不相关的东西是类型转换。如果你有一个int a
,表达式(double)a
实际上会调用一个函数来将整数转换为等效的双精度浮点值。这需要相当多的数学。在整数类型之间转换通常只留下比特但增加了额外的比特:例如,如果short a = 0x1234
,那么(long)a
将是0x00001234
(填充比特是0还是1取决于有符号性)。
答案 1 :(得分:4)
实际的类型转换中没有涉及任何代码。它只是以不同的方式重新解释底层字节。您所有的类型转换都会关闭编译器中的类型检查。即如果你写:
unsigned int uInt = UINT_MAX;
int sInt = (int)uInt;
printf( "sInt = %d\n", sInt );
你得到-1。这是因为底层字节都被设置为0xff,即所有位都是1.如果你看4个字节,期望一个unsigned int,那就是4294967295,如果你看4个字节需要一个有符号的int,相同的位被解释为-1。
RAM中的实际数据没有变化。但是,编译器会生成不同的机器代码指令,具体取决于它是否认为您给出的这4个字节是有符号或无符号的。
类似地,如果您为printf()指定了signed或unsigned int,但使用了错误的格式(即使用%d打印unsigned int,或使用%u打印已签名的int), printf 是错误地解释字节的地方。
C优于汇编程序和原始机器代码的优点是C实际上跟踪变量是否应该被认为是否已签名,并且不会强迫您记住它,甚至在您获得它时会发出警告错误。类型转换只是编译器的一个信号,表明这样做是错误的&#34; case实际上是正确的,编译器应该相信你知道你在做什么。
请注意,在C ++中,事情是不同的。在C ++类之间进行类型转换或将子类分配给基类类型的变量实际上可能会生成调整指针的代码。
更新:正如Alastair所说,这并不完全正确:如果您对一个或多个相同大小的指针进行类型转换,我所写的内容只有100%为真。对于不同大小的数字类型,C 将实际生成一小段代码,例如将4.5之类的浮点数截断为4,或者确保如果将char -1类型转换为int,它将移动指示符号的位&#34; up&#34;。这样,你仍然得到-1,而不是255(这将是在被视为int时将-1组成为char的位的解释。)