|
初学VC或C++者常犯的几个错误
chris 发表于 2003-06-25 11:19:00
评论数:1 点击数:2,973 投票总得分:12 投票总人次:5
关键字:初学VC或C++ 常见错误
作者:Christopher
根据我自己的实践和版上一些网友常提的问题,我想写一些系列文章,列举常见的错误,从概念上澄清一些东西,希望对大家有帮助。
1.编译问题
1) Unresolved externals
这是典型的链接错误,最常见的原因是用了一个外部变量或在别的模块里定义的函数却没有声明。举例来说:
///////////////////
//a.h
int f();
///////////////////
//a.c
#include “a.h”
external int a;
int b;
b = a;
b = f();
这时如果编译a.c就会出连接错,一是a没有定义,只是作为外部变量声明了一下,编译时不会出错,连接时就找不到它的定义了;二是函数f没有实现,只是在头文件里声明了一
下,编译时不会出错,连接时就找不到实现出错。
解决的办法是找个合适的地方实现函数f,定义a。
如何定义a呢,比方说还有一个b.c,在里面定义a为全局变量就可以了。
还有一种比较典型的情况就是使用了一些库,但没把库文件加进工程,最常见的是编译socket或DirectX程序时。解决办法就是在Project-》Setting对话框下选Link页,选择
Category下拉式列表框中的input,然后在object/library modules编辑框里加上要包括的库文件(注意:如果该库文件不在标准库文件目录下时要么将其拷贝到库文件目录里,要么把目录写上,可以用绝对目录也可以用相对目录(相对于工程文件dsp所在的目录))
2) Undeclared identifier
现在当然不会有人随手引用一个既没定义又没声明的变量或函数了,那是低级错误。
但是看下面的代码:
///////////////////
//a.h
int f();
///////////////////
//a.c
#include “a.h”
int f()
{
return 0;
}
b.c
int a = f();
这就会引起上述错误,因为对于b.c来说它不知道函数f从何而来,程序员可能以为自己已经在a.h里声明并在a.c里实现了,但是b.c并不知道,解决的办法就是在b.c力包含头文件a.h
3) Unexpected end while looking for precompiled header
这是因为该模块没有包括预编译头文件“stdafx.h”的缘故。
VC用一个stdafx.cpp包含头文件stdafx.h,然后在stdafx.h里包含大部分系统头文件,这样编译时VC就通过编译stdafx.cpp把大部分系统头文件预编译进来了,在Debug目录下有一个很大的文件*.pch,这里就存储了预编译信息。
根据这个原理,如果这个pch损坏了或被删除了,系统重新编译时就会抱怨“cannot open precompiled header file debug/*.pch”。这时怎么解决这个问题呢,打开Project->Setting对话框选C++页,将Category下拉式列表框选中Precompiled Headers,最简单的办法就是选中第一个选项“Not using....",这样,就根本不用预编译头也不去寻找pch文件,就不会出错了,但是这样做的后果是每次编译、连接都花更多的时间。
也可以选第二个选项”Automatic . ...",然后在“Through header”力填上stdafx.h,这样如果没有pch文件系统会自动生成一个pch,如果有的话就使用这个pch,这个选项是比较“智能”的。第三个选项是强行创建一个pch文件,第四个选项是直接使用pch文件。当然“Through headers”里都填stdafx.h了。
附赠一个小花招:
如果编译、连接时总出稀奇古怪的错误,或者调试时,单步执行的代码都不符合自己的想法因为你连接时一般都选用的incremental linking,每次增加一点,有可能把以前的错误的东西留在连接出来的可执行文件里了。不如彻底重新编译、连接一遍。
4)每次编译都把几乎所有的文件编译一遍,速度太慢
一般都是因为改动了系统时间引起的。编译是VC根据文件的修改时间确定哪个文件需要编译,哪个不需要。最简单的办法当然是把系统时间改回去然后重新编译一次就行了。如果因为某种原因不想更改系统时间,那就把所有的源文件略作修改然后保存,再编译就可以保证所有的源文件都比可执行文件要老了。
2.语法问题
1) 宏定义
看下面的代码
#define BBB 200
#define AAA 100+BBB
int a;
a = AAA*2;
请问a等于多少,很多人会以为是600其实应该是500,因为宏的使用只是在编译时简单替换,宏本身并没有什么优先级,直接替换的结果是 a = 100 + 200*2而不是理想中的
a =(100 + 200)*2。
2) 指针的问题
char* b,c;
char k;
k = 'a';
b = &k;
c = b;
请问c为多少,可能有相当一部分人以为c等于k的地址,其实c应该等于k的地址的最后一个字节,c的类型是字符而不是字符指针。 |
|