首先,要知道一件事情:你在代码里写的事情,计算机未必会干。
比如:
char var = 'a';
var = (int) var;
没准人家编译器看你没有产生实际效用,就直接给砍了。
更严格来讲,你应当写:
char var1 = 'a';
int var2 = (int) var1;
这就有点实际意义了。
一直对基本类型的cast疑惑不解
C的基本类型,大都能对应到CPU能处理的标准数字类型。char基本都是一个8位有符号整数,最高位是符号位。int是不低于16位的有符号整数(所有的常见平台上都是32位),最高位是符号位。
那么进行这种转换,基本上就是编译器把这件事情翻译成一个或者几个CPU指令,大概是:从地址var1读内容到寄存器;
执行8位到32位的有符号整数转换;
将结果从寄存器写到地址var2,写32位。
对于ASCII,a的数值是97,用八位的二进制数表示,就是01100001。把它转换到int,实际上就是在求一个32位有符号的值,数值意义和01100001要相等。编译器会把你这个表达式翻译成对应的CPU操作。结果是00000000 00000000 00000000 01100001。
看起来好像除了填上一堆零,啥都没干?
实际上填零是重要操作,因为内存空间可以是脏的:在你给丫赋值之前,丫可能还带着上次计算完之后的垃圾。
而且,如果是负数,就会很不一样。比如:
char var1 = -1;
int var2 = (int) var1;
由于现代计算机几乎全都用补码来表示负数,于是负一的8位二进制表示,是11111111;而32位表示,则是11111111 11111111 11111111 11111111。不难看到,对于有符号数的长度转换,并不总是填零的。
所以CPU在这里面,还是需要做一些微小的工作。
======================
补充运行时类型的问题:
C这种语言,要的就是运行时不带类型记号的裸奔快感。比如对于类似这样的源代码:
int a = some_procedure();
int b = some_other_procedure();
int c = a + b;
最后的那个相加,在不优化的情况下,通常会产生类似这样的几个指令:从地址a取32位数据到寄存器1;
从地址b取32位数据到寄存器2;
执行32位整形加法;
将32位数据写到地址c;
可以看到,这里面没有类型。对数据的操作方式就是类型。