CSDN博客

img kernelhao

编译系统所带来的语言特性的不同

发表于2004/7/31 0:06:00  737人阅读

                                

不同的编译环境(vcbcturbo pascal等等)在处理一些语句的时候存在着很大的不同,这样就引起了一些相同的语句在不同的编译环境下有着不同的结果。下面举例给予说明:

1、为变量分配的空间不同:对于int  i ,double j.这两个语句在vc6.0环境下编译运行的时候,系统为 i,j 分配的空间分别是48个字节。但是在tc环境下编译运行的时候,系统为 i,j 分配的空间分别是24个字节。如果不熟悉这些编译系统的不同特性的时候,有时候会出现一些错误。例如:在不同的编译平台编写的程序之间交换数据的时候,就会因为分配空间的不统一而出现取错数据的情况。在vc6.0有解决这种不匹配的方案。

2、大家有没有想过为什么在c/c++语言中,int a[][20]能够正确的定义一个二维数组,而int a[20][]却不是正确的定义呢?这就关系到编译系统在处理数组的时候的不同。在c/c++语言中,数组的编址方式是行优先的,在上面的第一种定义方式中,如果你要访问a[10][0]这个元素的时候,你可以根据数组a的第一个元素的地址来得到a[10][0]的地址,地址(a[10][0]=地址(a[0][0]+10*20*2。但是对第二种定义方式,你并不能通过a的第一个元素的地址获得a[10][0]的地址。因为有这样的问题发生,所以c/c++语言就做出了相应的定义规定。但是对一些数组的编址方式是列优先的语言来说,第二种方式就是正确性,第一种定义方式却是错误的了。

3、大家知道,在c++中,形参的初始化是按从左到右的顺序,这主要跟c++函数的参数压栈方式有关。C++的这种特性导致了在使用默认参数的函数的时候必须注意一个规则:在有默认值的形参右边,不能出现无默认值的形参。下面举个例子说明一下:例如void try(int j, int k=2, int m),由于形参的初始化是按左到右的顺序,所以如果用try(1,2)的方式调用函数的时候,程序员本意是调用try(1,2,2),但是在vc6.0环境下进行编译的时候编译器却认为程序员是为j赋值为1k赋值为2,没有为m赋值,所以vc6.0认为出错了。为了避免出现这种不必要的错误,就定了那么一个规则。有些语言中规定了形参的初始化是按从右到左的顺序,规则就反过来了。

4、最后举一个例子,请看下面的问题。

int w,z,x,y;

w=5;x=4;

y=w++*w++*w++;

z=--x*--x*--x;

请问一下最后W,Z,X,Y的值为多少呢?

这个问题采用不同的编译器实现有不同的结果。在vc6.0环境下,对于y=w++*w++*w++,计算机是这样做的:先取w值进行连乘,然后w进行3次自加,就是y=5*5*5=125; w=8。对z=--x*--x*--x,计算机是这样做的:首先x自减两次,取x相乘,x再自减一次,再和上次相乘的结果相乘。因此,z=2*2*1=4;x=1。但是在vc.net环境和Bc3.1环境下,结果并不是这样的:对于y=w++*w++*w++,计算机是这样做的:先取w值进行连乘,然后w进行3次自加,就是y=5*5*5=125; w=8;z=--x*--x*--x,计算机是这样做的:首先x自减三次,取x相乘。因此,z=1*1*1=1;x=1。为什么会出现这样的不同呢?因为对于语言标准没有定义的语法特性,各种编译器都出于自己的考虑做了自己的处理(虽然有些处理在我们看来不可理喻的)。

 

因为编译器的不同引起相同语句有不同处理的情况还有很多,本文就不打算一一列举了。本文的目的是为了引起大家对不同编译器的处理多做些思考和比较,这些对深入的学习计算机语言有着很大的帮助。

阅读全文
0 0

相关文章推荐

img
取 消
img