初学者学编程,比如C语言,往往是从一些简单的代码开始,以熟悉语法,比如:
int i = 300;
int temp = 0;
temp = i;
printf("%d\n", temp);
这段代码是把变量i中存储的300赋给变量temp,这样,temp中也存储300了,我们将在输出打印环境中看到300。
不过,如果只是单纯地背诵C语言语法,依葫芦画瓢,则有人可能写出这样一段代码:
int i = 300;
char temp = 0;
temp = i;
printf("%d\n", temp);
这看起来是依葫芦画瓢,没什么问题,编译也可以通过,也可以运行,但结果不会如愿。
你会发现,机器会打印44,而不是300。
为什么?
原因不难,这是因为在大多数平台,char型变量只占一个字节,而int要么至少是2字节,要么4字节。我们就以4字节为例,那么,变量i实际存储的形式应该是:
00000000 00000000 00000001 00101100
而由于char类型的temp只占一个字节,所以,它无法存储变量i的所有位,而只存储低8位:
00101100
而这低8位二进制数所对应的十进制值,就是44。因此,变量temp的值将是44。
这个很基础的例子,说明了我们为什么要理解编程,而不可仅停留在对语法的简单复制,尤其对于在电子领域使用C编程的朋友。
因为在这种直接面对硬件的领域,代码中任何一个预料之外的行为,都可能造成严重后果。
1996年6月4日,法国航空航天公司Arianespace SA的Ariane 5火箭在发射37秒后偏离飞行路线,开始解体,并自毁,导致超过3.7亿美元损失。
这次事故的原因和刚才我们举的例子相当类似,火箭沿用了上一代火箭中的某些代码,将一个64位浮点数(代表火箭的水平速度)转换为16位有符号整数,用C语言描述大概是这样:
int16_t convert_v(double velocity)
{
return (int16_t)velocity;
}
而这个浮点数velocity运行时传入的值,在上一代火箭中没问题,但在这一代,由于火箭速度更快,velocity更大,就出问题了。
由于没有进行范围检查,表达式得出了错误的结果,引发异常,导致一系列连锁反应,并最终触发自毁。
当然,并不是我们每个人都会从事这种对安全有严苛要求的工作,但总体而言,只掌握编程语言的编写是不够的。
重新理解编程,能让你在编程时,潜移默化地深入底层掌控代码,而不是简单的模仿。这可以让你在工作、面试中更具竞争力,学习更有效率,如虎添翼。