|
总结了一些C/C++里会遇到的一些问题,会不继更新。
1、在C++里,要使用IO流,须包含头文件iostream,要注意,没有.h后缀的(在VC++.NET里),如果还有错误,试下用上这句:using namespace::std;。
2、getch()与getchar()的区别
两者都是从键盘接收输入字符,getch()是得到键盘输入,不需要回车确定。而getchar()则要回车确认。
3、当程序中要输入数据时,如果程序逻辑没有问题但结果老是错,那就要看看是不是输入数据时没有接收回车,把回车当成了下一个数据的输入了,可以用getchar()来接收回车。
4、说说声明和定义
我们的教科书上好像对这个问题说得不够清楚。不过这个问题也是一个不易说得清的问题。谭浩强老师是这样说的:“在声明部分出现的变量有两种情况:一种是需要建立存储空间的(如:int a;),另一种是不需要建立存储空间的(如:extern int a;)。前者称为定义性声明或称定义,后者称为引用性声明。”。
一般情况下,我们没有严格区分两者,但当做比较大的系统时,个中带来的问题也不是很易处理。比如:在文件head.h中定义一个变量int a;然后文件a.c和b.c都include这个头文件,编译链接后会提示重定义,那是因为编译成目标文件时,编译器在a.c和b.c都把head.h展开了,当连接的时候,两个目标文件都有int a 的定义,编译器就报重定义错误了。
解决方法:在头文件里声明,在.c文件里定义。在head.h里声明extern int a;在a.c里定义int a;这样在b.c都可以使用变量a了。
当编译器编译时,对于head.h里的int a,只是声明了一个变量int a,并没有分配空间,当在a.c里才真正定义,在b.c里展开head.h时也是只是声明,这样就解决了重定义问题。
5、关于重编译
当头文件之间出现相互include的时候,就可能出现重编译,防止重编译,只要正规地写就行了。可用以下方式:
#ifndef __XXX_H
#define __XXX_H
……
#endif
/-----------7.2添加----------------
6、使用链表时要注意的问题
比如有个结构体
struct A{
int i;
struct A *next;
};
(1).已创建了一个链表比如a->b->c->NULL,如果想把b删除的话,把a->next=b->next后不要忘记free(b);否则会内存泄露。
(2).要在b后插入d,须d->next=c;b->next=d;不能乱了顺序,否则会断链。
(3).在链尾插入一个结点时要注意,如在c后插入一结点e,e=(A*)malloc(sizeof(A));不要忘记e->next=NULL,否则对于以下例子的查找,可能会一直死循环,
例子,要想从链头查找某个符合一定条件的结点,如统计i=3的结点个数,
while(p){//p初始指向链首
if(p->i==3)count++;
p=p->next;
}
因为没有e->next=NULL的话,e->next并不会等于空的,而是一个野指针,循环条件永远为真,这个问题在vc++.net平台下的确是这样的,其它平台没有试过。
/------------------7.5添加-------------./
7、sizeof的一些问题
sizeof的作用就是返回一个对象或者类型所占的内存字节数。
char、signed char和unsigned char的sizeof值为1;
int的sizeof值是4;
指针变量的sizeof是4;
sizeof可以对一个表达式求值,编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算,如sizeof(3-1.5),等价于sizeof(double)。
sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用。
结构体的sizeof值,在32位机器中结构体大小会被调整到4bytes的整数倍。
/------------------7.9添加-------------./
8、在C++里,使用cin得到输入信息时,空格会被认为是输入结束符,空格以后的字符不会读进当前变量里,而会读进下一变量里,而使用gets()函数则可以接收带有空格的字符串,直到回车确认输入为止,当然,用来接收的变量一定要足够放下输入字符串的大小。
[ Last edited by hjack on 2005-7-9 at 12:03 ] |
|