1. c语言编程米ing明明代码检查了是对的,为什么编译器说是错的
看看你用的一些符号是不是中文状态下输入的,比如分号,双引号什么的
2. gcc编译器在编译过程会进行哪些检查
一个编译器,执行的时候
先会做词法分析,其中会判断是否符合词法规范,一般用有限自动机写
然后是语法分析,自顶向下的LL和自底向上的LR,会判断是否符合文法规范
然后就是四元式,语义动作、汇编指令,后面的检查应该就不多了
3. C++编译器每个具体的地方如何使用,希望帮助下
找相关书籍资料看吧,这么问太空洞了,不知如何说起。
4. 编译器本身是如何进行测试的
编译器最重要的性质就是保证语义的正确。比如,从高级语言翻译到机器指令之后,指令必须正确的表达原来程序的意思。所以一般编译器测试都包含一些源程序,用来覆盖可能出现的各种情况。基本的原则是:原来程序的结果 = 编译后机器指令运行的结果。机器指令运行的结果很容易知道,运行一下就知道了。可是原来程序的结果你怎么知道呢?
为了解决这个“原来程序语义”的问题,最好是写一个解释器,准确无误的表达原来的代码的语义。所以我们的要求就是:
高级语言解释器(源程序) = 机器执行(机器代码)
由于处理器其实就是一个用来执行机器代码的解释器,这里有一个很美好的对称关系:
interp1(L1) = interp2(L2)
另外还有一个问题,就是编译器一般需要经过多个转化步骤(叫做 pass)才能最后编译为机器指令。比如,
L2 = pass1(source)
L3 = pass2(L2)
L4 = pass3(L3)
Ln = passN(Ln-1)
machine_code = codegen(Ln)
由于源程序经过了很多步骤猜得到最后的机器指令,如果你使用上面的公式,就会出现以下一些情况:
1. 知道结果错了,但是却不知道到底是哪一个 pass 错了。
2. 结果没有错,但是中间却有 pass 实际上是错的。但是由于之前的 pass 把输入程序的一些结构给“优化”掉了,所以错的那个 pass 其实没能得到触发错误的那个数据结构。所以测试没能发现错误。如果以后前面的那个 pass 被修改,错误就会暴露出来。这是非常难以发现的潜伏的危险。
为了防止这些情况出现,一些编译器(比如 Chez Scheme 和 Kent Dybvig 的课程编译器)使用了对每一个 pass 进行测试的做法。具体的方法就是为每一个中间语言都写一个解释器,把这语言的语义完全的表示出来。这样我们就需要检查一组等式:
L2 = pass1(source)
高级语言编译器(源程序) = interp2(L2) // 测试 pass1 的正确性
L3 = pass2(L2)
interp2(L2) = interp3(L3) // 测试 pass2 的正确性
这样一来我们就能独立的判断每一个 pass 的正确性了。
这些是基本的语义测试原理。另外除了语义,可能还有一些“表面”一些的测试,它们看代码本身,而不只看它的语义。比如尾递归优化的测试应该确保输出程序的尾递归得到正确的处理,等等。这些是语义测试检查不到的,因为尾递归没有正确处理的程序大部分也能输出正确的结果。
普通的单元测试方法也可以用来测试一些编译器里的辅助函数,但那些不是编译器特有的,所以就不讲了。
另外,就像所有测试的局限性一样,你没法枚举所有可能出现的输入,所以以上的测试方法其实也不能保证编译器的完全正确。
5. 在Java编译器中用什么样的机制来实现数组边界检查
int[] i = {1,2,3,4,5,6,7,8,9};
for(j=0;i.length>j;j++){....}
length就是了
6. 为什么guess number程序编译器检查时,总在srand行报错求大神看
srand( (unsgined) time( NULL ) ); 拼写错,应是 unsigned
也可略去 unsigned
7. 简单c++问题,帮帮小弟。
C++编译器是不对数组边界进行检查的,但是有个问题:比如
int i,a[10];
for(i=0;i<=10;i++)
{
a[i]=0;
}
上面的语句就可能是一个无限循环。因为当i=10的时候a[10]的值被赋值为0,而a[10]又不在定义的数组内,根据递减内存分配方式,a[10]被分配给i了,故这个是个无限循环。一般是不会报错的,但是也有编译报错的可能。
8. C#的数组边界检查的底层原理是什么
c#的数组是一个对象,而不是一段单纯的栈内存空间。数组对象里包含了length属性喽!
类似于C语言的结构体:
struct Array{
datatype data[SIZE];
int length;
}
9. C 语言中编译器为何不检测数组下标越界问题
以前还真没想过,记得老师讲的时候也没说,就是强调这是C语言的历史问题,从一开始就没有,后来这个功能也没有加上。至于具体的原因已知模棱两可,今天总算查清楚了。 综合网上的各种资料,可以得到如下的结果: 1. 在一个固定的机器之下,指针所占的位数都是一样的,换言之,保存的地址是有最大值的,这样如果每次都检查数组的越界问题,会对指针的功能做出很大的限制,因为指针只是包含地址信息并没有包含长度的信息,比如一个 char ch[100]; char * test=ch; 之后test也可以只想超过100的长度的字符串类型,并不是局限与100。如果检测长度,那么就相当与限制的指针的长度,这是不合理的。 2. 没有效率,需要付出代价。具体:最早的C编译器并不检查下标,而最新的编译器依然不对它进行检查。这项任务之所以很困难,是因为下标引用可以作为任意的指针,而不仅仅是数组名。作用于指针的下标引用的有效性既依赖于该指针当时恰好指向什么内容,也依赖于下标的值。结果,C的下标检查所涉及的开销比你开始想象的要多。编译器必须在程序中插入指令,证实下标的结果所引用的元素和指针表达式所指向的元素属于同一个数组。这个比较操作需要程序中所有数组的位置和长度方面的信息,这将占用一些空间。当程序运行时,这些信息必须进行更新,以反映自动和动态分配的数组,这又将占用一定的时间。因此,即使是那些提供了下标检查的编译器通常也会提供一些开关,允许你去掉下标检查。
10. 最近在做一个利用VC6.0+opencv1.0环境,做canny边缘检测,但是编译器老是报错,不能编译cxcore.hpp,求指点
参考http://www.opencv.org.cn/index.php/VC6%E4%B8%8B%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AEOpenCV1.0