2007年7月27日星期五

C语言常见错误

1.mallocfarmalloc动态分配内存时,如

char *buffer;

buffer=(char *)malloc(300);

因为并不是在所有的情况下,都会分配成功

所以应加
if(buffer==NULL) {......}

2.char far *buffer;

buffer=(char far *)farmalloc(size);

size的值大于64K时,很可能不会分配成功,

但是不会返回
NULL,很容易出错。

因此最好
size的值最好不要大于64K

3.char 的取值范围为 0-127

unsigned char 的取值范围为0-255

新手常常在使用
char时,出错,比如说,

256色的屏幕模式下,颜色索引值为0-255

而很多新手用
char color,这样会出错。

4.编程时常会对键盘进行处理

key=bioskey(1);

bioskey(1)时,程序从缓冲区取一个键,但是不

会把这个键从缓冲区移走,因此
key的值将永远保持不变

5.if(bioskey(1)!=0) key=bioskey(0);

这样按键时,会从缓冲区移走一个键。

但是当不按键时,
key的值将保持不变,直到按下一键为止

因此应加
else key=0;

6.使用textcolor(int newcolor);

textbackground(int newcolor);

这两个函数来改变字符颜色和背景色时,

stdio.h中的printf,puts等向屏幕输出的函数是,并不能

textcolor(int),textbackground(int)这两个函数所要求的颜色来显示。

用该用
conio.h中的cprintf,cputs等函数

7.printf("\n");光标会在屏幕上换行并移动到第一列。

cprintf("\n");不会,printf是标准输出函数,与DOS相关

DOS会自动把'\n'处理成'\n''\r',cprintf是控制台级函数,不会这样

因此应该用
cprintf("\n\r");

8.float a=1.9;

if(a==1.9) printf("OK");

运行时却不会显示
OK;

不要用
float型数字进行关系运算中的等于运算

改为
double双精度型即可解决问题.

9.TC2.0

main()

{

......

.....

}

这样编译时不会出错

但是在有些
C语言版本中,系统会自动当作

int main()

{

}

而显示
"..should return a value "

10.float a;

a=1/2;

printf("%f",a);

运行的结果是
0.000000,而不是0.500000.

因为
/号两边的数字是12,系统会当作整型处理,因此出

现这种情况
,解决办法是改为 a=1.0/2a=1/2.01.0/2.0

11.一个函数

char *buf()

{

char *data;

char str[]="HELLO";

data=str;

return data;

}

因为系统在调用完函数时
,会自动释放为str 开辟的空间,

因此
return data无意义

12.对于findfirst(char *name,struct ffblk,int attrib);

findnext(struct ffblk);

当寻找目录时,用
findfirst("*.*",&ffblk,FA_DIREC);

虽然所找文件的属性为目录,但是会将当前目录下的所有文件找出来

findfirst("*.",&ffbli,FA_DIREC)时,找出来的是目录以及没有扩

展名的文件。

13.看下面一个函数

/*640x480x256*/

void plot(int x,int y,unsigned char color)

{

char far *video=(char far *)(0xa0000000L);

long int offest;



offest=(y-1)*640+x-1;

*(video+offest)=color;

}

看似没有错误,但是对于
offest=(y-1)*640+x-1这句,

虽然
offest是长整型,但是y是短整型,在计算(y-1)*640时,系统

会按短整型处理,当
y的值取110以上时,(y-1)*640的值显然会超出

短整型数字的取值范围,从而产生错误,因此应改为

offest=(long int)(y-1)*640+x-1;

14.对于一个数组 int data[5][4];

data表示data[0][0]的地址

data[2]表示data[2][0]的地址

因此有人认为
data[4][2]的地址可表示为

(1).data+4*4+2;

(2).data[4]+2;

其中
(2)是正确的,而(1)却是错误的.

因为
data的基类型是8个字节的,

data+4表示的就是data[4][0]的地址

data+1表示的就是data[1][0]的地址

15.许多人认为转义字符'\64'中的64是十进制数,

但实际上这个
64是八进制数,这个八进制数前面可以加0也可不

0,当然转义字符\后面也可以用十六进制数,但要

'\x..''\X..'的形式,如'\x14'

16.看下面这个程序

#include

void display(int data[]int num)

{

int i;

for(i=0;i<num;i++)

printf("%d\n",data[i]);

}

void main()

{

int da[10]={0,1,2,3,4,5,6,7,8,9};

display(da,10);

}

一般认为当程序里调用这个函数时,系统会为形参
data[]开辟一个

10个整型数字的存储空间,实际上,这个函数只为data[]开辟一个整型指针类型的空间,

使用指针指向
data[]的首地址,因此在display(int data[],int num)这个函数中,

若使用赋值语句对数组
data[]的某项赋值,如data[0]=2,会使主程序中的数组da[]的值改变.

17.

void main()

{

unsigned char index;

for(index=0;index<256;index++)

{

printf("%d\n",index);

}

}

在编译时,会出现警告。

TC2.0中,若改为index<=255,编译会通过,但是运行程序时

却会陷入死循环,大家不禁会产生疑问,
unsigned char类型数据的

取值范围为
0-255,为什么上述程序会出现错误呢。

让我们先看下面一个程序:

void main()

{

int i;

for(i=0;i<10;i++)

{;}

printf("%d",i);

}

运行结果为
10,当i=9的循环完成后,i自加1,使得i=10,这时不符合

i<10,才跳出循环,因此运行结果为10;

同理,若改为
i<=10;则运行结果为11

通过这个程序,应该能明白为什么前一个程序会出错了。

没有评论: