C/C++板块常见问题集:(写给新手),欢迎大家补充,帮顶也可以

猫已经找不回了 2009-03-02 06:56:17
加精
前言:多给你自己几分钟,耐心的分析一下,不要习惯性的一遇到问题就想找高手帮你解决,耐心点,多想,多看,多练,你就是高手.
主要目的是总结C/c++理一些常见的错误,随手引用或者写的(被我引用了的朋友应该不会介意吧..),自然不够详尽,对涉及的具体问题有兴趣的朋友可以google,这里不浪费时间和篇幅了.
暂时整理出一些,时间跟精力有限,请大家多补充或指正
希望相关方面有问题的朋友们可以先看看此贴,说不定对你有帮助,也可以省去一些重复问题.
/****所有代码都未加头文件,想运行请自行添加.*************************/

1:试图用cout输出全局类的析构.(可能是VC6的问题,如果你的编译器没出现问题,很好,别喷我)

引用自whillcoxdennis提问: http://topic.csdn.net/u/20090302/14/ca44881f-9664-4be8-9687-1dd098612d11.html
class CDemo
{
public:
CDemo(const char *str);
~CDemo();
private:
char name[20];
};
CDemo::CDemo(const char* str)
{
strcpy(name,str);
cout < <"cout:Construction called for " <<name <<endl;
}

CDemo::~CDemo()
{
cout <<"cout:Destruction called for " <<name <<endl;
printf(" printf:Destruction called for %s\n",name);
}

static CDemo GlobleObject("globeobject"); //这个是我们关注的,cout:Destruction called for globeobject并不会出现
void main()
{
CDemo LocalObjectInMain("localobjectinmain");
CDemo * pHeapObjectInMain=new CDemo("heapobjectinmain");
CDemo *pHeapObjectInFunc=new CDemo("heapobjectinfunc");
static CDemo StaticObject="staticobject";


}
这里globeobject的析构并没有被显示出来,为何呢?
加一句printf你就知道为何了.
因为cout析构在GlobleObject析构前.


2.关于VC6的问题:
有人说珍爱生命,远离VC6,确实有一定道理.
VC6对于friend,模板等几个bug,建议换VS测试.
如,重载操作符号,如果friend符号的定义在类体外会报错.
模板嵌套:
vector<vector<int>> bad; //error,VC6会把2维容器 >>认作输出符号.
vector<vector<int> > good;
此外VC6下编译模板,出现一堆警告的话,你在头文件前加
#pragma warning(disable:4786)


3.关于型参,实参不分,指针搞不清楚.具体不赘述了,看下面代码,把这3段都搞清楚,就可以了.不清楚可以参考林锐博士的<<彻底搞定C指针>>
void Exchg1(int x, int y)
{
int tmp;
tmp=x;
x=y;
y=tmp;
printf("Exchg1:x=%d,y=%d\n",x,y);
}
void Exchg2(int &x, int &y)
{
int tmp;
tmp=x;
x=y;
y=tmp;
printf("Exchg2:x=%d,y=%d\n",x,y);
}

void Exchg3(int *x, int *y)
{
int tmp;
tmp=*x;
*x=*y;
*y=tmp;
printf("Exchg3:x=%d,y=%d\n",*x,*y);
}



void main()
{
int a=4,b=6;
Exchg1 (a,b) ;
printf("a=%d,b=%d\n",a,b);
Exchg2 (a,b);
printf("a=%d,b=%d\n",a,b);
Exchg3(&a,&b) ;
printf("a=%d,b=%d\n",a,b);
}

4.C风格字符串与标准库类型string不分
int i;
char * ch = "cchars"; //这是C风格字符串,结尾有'\0'
char mch[] = "mchars";
string str(ch); //string类的构造函数接收ch,并作转化
i = strcmp(ch,str); //error,有人喜欢把string类作参数输入到strcmp等C字符串函数里,肯定会出问题啊.
ch[0] = 'd'; //error,char *ch获取的内存是const,相当于const char *ch= "cchars";无法修改.
mch[0] = 'f'; //ok



5.关于指针和内存申请及越界
int *ptr1,ptr2;
*ptr1=10; //error,ptr1未申请内存,未初始化,结果未定义,看似不容易出错,可很多人写链表就没有申请内存
ptr1 =(int *) malloc (sizeof(int));
*ptr1=10; //ok;
*ptr2 = 20; /error
ptr2=ptr1;
*ptr2 = 20; //ok,实际是修改ptr1和ptr2指向的同一块区域.
ptr2= new int[10];
ptr2[10]=5; //error,这样写你或与觉得很傻,但是实际上很多时候,你就不知不觉犯了这些错误.
free( ptr1 );
delete ptr2; //error,这样delete只会析构第一个元素
delete[] ptr2; //ok

关于指针,我还想说多一点.但是这个问题牵涉到函数作用域,所以我放在第9条.

6.关于字节对齐
struct st1
{
char p1; [0]
char p3; [1]
short p2; [2][3]
int p4; [4][5][6][7]
};

struct st2
{
char p1; [0]
short p2; [2][3] //占2字节,起始地址要是2个整数倍
char p3; [4]
int p4; [8][9][10][11] //4字节,起始地址是4的整数倍
};

为何sizeof(st1)==8;sizeof(st2)==12,2者不一样呢?看注释.

7.小于32字节数据的输出显示问题

8.关于IO流
scanf("a=%d,b=%d",&a,&b); //很多人喜欢这样写,然后输入3 4 就问,为何程序跑起来不对,这里应该输入3,4
scanf("a=%db=%d",&a,&b); // 这样是3 4
输入缓冲区很容易出现一些你不需要,或者容易出问题的字符,
建议用空就刷新一下.
fflush(stdin);

9.关于变量作用域:其实也算指针应用的问题
引用的是rwjbjn1问的一个帖子 http://topic.csdn.net/u/20090302/17/900b3797-3642-4569-a623-dc0f8ebd8401.html?seed=1325371970
//代码1
int A()
{
int test=10;
return test;
}
int main()
{
int a=A();
printf("%d\n",a);
return 0;
}
//代码2
char* A()
{
char p[]="hello world";
return p;
}
int main()
{
char *str=NULL;
str=A();
printf("%s",str);
}
代码1没问题,可是代码2有问题(可以有结果,但是结果不一定对,这是未定义的操作).为何自己分析,可以去看那个贴里.



10.数据溢出

数据溢出,道理很简单,可是代码一长.有人不知不觉就犯错误了.
int main()
{
int b= 1294754725065626467; //32位机的int只支持32位(2^32-1)的有效计数
char a=199; //8bit的char数据只支持0到127的有效计数
cout << a <<endl;
cout << b <<endl;
printf("%c",a);
printf("%c\n",a);
}
不要试图解释结果,溢出了,就没什么好解释的了.什么诡异事都有.


...全文
16070 395 打赏 收藏 转发到动态 举报
写回复
用AI写文章
395 条回复
切换为时间正序
请发表友善的回复…
发表回复
zc01@ 2012-08-09
  • 打赏
  • 举报
回复
谢谢楼主、受教了
披荆又斩棘 2011-12-16
  • 打赏
  • 举报
回复
不错。。。
「已注销」 2011-11-24
  • 打赏
  • 举报
回复
没有及时看到,mark。
codesnail 2011-11-16
  • 打赏
  • 举报
回复
非常支持!!!
「已注销」 2011-10-27
  • 打赏
  • 举报
回复
lz辛苦。对于我等新手很有用
泼粪涂墙 2011-10-24
  • 打赏
  • 举报
回复
顶了以后好找~
一介丶草民 2011-10-19
  • 打赏
  • 举报
回复
很好的东西
lc19881029 2011-10-11
  • 打赏
  • 举报
回复
好东西,感谢!
anderuier 2011-09-29
  • 打赏
  • 举报
回复
先收藏,慢慢看
sanguo1985 2011-09-28
  • 打赏
  • 举报
回复
mark
Simle_Souce 2011-09-08
  • 打赏
  • 举报
回复
学习。
......顶
sunnyorange 2011-08-22
  • 打赏
  • 举报
回复
顶起哦~~
beihou__ 2011-05-12
  • 打赏
  • 举报
回复
成为CSDN第一帖子 一直更新下去、、、让我们受益
fyw1990 2011-05-04
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 awaltz 的回复:]
我觉得用C++的时候还要注意一下用delete时候,容易产生野指针。
应该让指针为空值,变为空指针。
[/Quote]

析构里面要
wjl15989 2011-04-15
  • 打赏
  • 举报
回复
虽然只是路过,但也见识到楼主的强大,顶!
VCACC 2011-04-13
  • 打赏
  • 举报
回复
好文章,mark
pcliuguangtao 2011-03-28
  • 打赏
  • 举报
回复
lz第一个确实因该说清楚,我在vs2010上面试过了,没有问题,可以输出“global object”;在gcc4.4.5里面也调试过了,都会输出。所以,lz应该都自己调试一边,否则会误导别人的。也请大家注意,发贴是要负责的
Dangerous_1 2011-03-16
  • 打赏
  • 举报
回复
明了了。。。。。。。。
  • 打赏
  • 举报
回复
再up.看来加分才是王道啊
  • 打赏
  • 举报
回复
加载更多回复(356)

64,660

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧