C/C++板块常见问题集

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有问题(可以有结果,但是结果不一定对,这是未定义的操作).为何自己分析,可以去看那个贴里. 
注意
int A()  
{  
  int test=10;  
  return test;  
}  
返回的是值, 的确调用完后test会释放, 但它的值被返回了


char* A()  
{  
  char p[]="hello world";  
  return p;  
}  
返回的是指针, 确切讲是指针的值, 但因为"hello world"会释放, 所以返回的这个指针值没用了  
(存放字符串的空间被释放掉了, 这个指针值还有什么用?)


  
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); 

    不要试图解释结果,溢出了,就没什么好解释的了.什么诡异事都有.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值