c语言基础总结_c语言知识基础总结

2020-02-29 其他工作总结 下载本文

c语言基础总结由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“c语言知识基础总结”。

常见错误

1.使用未初始化和未赋值的变量

描述:非全局变量和静态变量在定义时不自动进行初始化,初值为一个与该程序运行环境有关的随机数。不赋值或没有显示初值就直接使用这样的变量是错误的。

解决:所有变量都显示地进行初始化,建议数值变量初始化为0,指针变量初始化为NULL

2.不考虑数值溢出的可能

描述:当赋值超过此范围数值,就会产生数值溢出,得到不正确的值。

解决:预先估算运行结果的可能范围,采用可能范围更大的,不处理负数,就用无符号类型。运算还没开始前,判断运算数是否在合理取值的范围内,超出则停止运算。采用第三方无取值范围的运算库。

3.不用sizeof()获得类型或变量的字长

描述:相同类型在不同平台上占得字节数不同。Int在16位,32位,64位系统分别占2,4,8个字节。结构体所占字节也不是所有成员字长的简单相加,而是和平台与编译器,编译项都有关系。

解决:用且只用sizeof获得字长

Intwriteint(intfh ,inti)

{

Returnwrite(fh ,&i,sizeof(i));

}

4.假定类型的取值范围

描述:类型的取值范围与程序编译息息相关。

解决:使用limits.h和float.h定义的宏(INT--MAX,INT----MINULONG--MAXFLT---MAX

5.期望两个整数的运算自动获得浮点数的结果

描述:两个数运算的结果还是整数,不是浮点数

方案:强制转换为浮点数,再运算

例:voidfunc(void)voidfunc(void)

{{

Floatf=0.0;floatf=0.0;

Inta =3,b=2;int a=3,b=2;

f=a/b;f=a/(float)b;

printf(“%f,f);printf

}

6.不预先判除除数是否为0

编译器反应:直接写入inti=100/0,编译器会报错,编译器对此问题沉默

解决方案:先判断除数是否为0,若是0则不运算。

7.混淆“&,|”与“&&,||”

说明:他们是两种不同的运算符,有人总是弄错

8使用依赖编译器求值顺序的语句

描述:printf(“%d,%d,%d,i++,i++,i++);i=0可能输出 0.1.20.0.0.2.1.0方案:按期望的顺序分别求职,再综合运算

Voidfunc(void)

{

Int a,b,c ,i=0;

a=i++;

b=i++

C=i++

Printf(“%d,%d,%d”,a,b,c)

9.使用依靠算符优先级的表达式

描述;没有记住优先级,容易出错。

解决:用括号明确优先计算的部分

10.表达式过于复杂

描述:(a>b||b>c)&&(o>P||q>p)?(a-b)*c+(o-p)*q:(a*b*c)-(o*p*q)

11.用“==”时误用“=”

12.用“==”比较两个浮点数

描述;两个数值表面相等或者非常接近的浮点时用“==”比较,结果可能不同

解决;不用float用double在精度运算中两个浮点数的差的绝对值只要小于一个

精度范围,就可以相等

13.使用幻数

描述:直接使用的常数

解决;把幻数定义为宏或枚举,建议使用枚举。编译提示会更清晰,准确

#definearray-srze10

Enum(array-size=10)printf()和scanf()中格式控制字符串与参数类型不匹配

15.循环或判断语句以“;”结尾

描述:分别表示循环和判断语句的终结,后面的代码不算循环体或分支,而是循环和判断

平行的代码

解决:禁止在循环判断语句末尾出现分号,循环体为空的情况下,While(.........)

{

}

16.在循环体内改变循环结束条件

例如:voidfunc(void)

{

Int a,end:

-------

While(a

{

在这里修改end的值

}

}

17.case分支不用break结束

规定每个case分支必须用break结束,两个分支用同样的代码,就把代码定义为函数

基本概念

函数是c的基本单位,必须有且仅有一个main函数。一个c可以包含一个到多个函数,在函数中可以调用系统提供的库函数

函数首部:函数返回值类型,函数名,形参类型,形参名的说明

函数

函数体:大括号中的内容,包括变量声明(对象)语句和执行(动作)语句c程序书写规则;以分号结束,并且书写注释;“/**/,注释之间不能留有空格常见关键字:asmautobreakcasecdeclchar

Constcontinuedefaultdodoubleelse

Enumexternfarfloatforgoto

Hugeifinterruptintlongnear

Pascalregisterreturnshortsigned

Sizeofstaticstructswitchtypedef

Unionunsignedvoidvolatilewhile

标识符:系统自定义标识符,用户自定义标识符

运算符:算数运算符:+—*/%关系运算符: >>==

逻辑运算符:!&&||

赋值运算符:=

复合的赋值运算符:+=-=*=/=%=&=!=^==

增一减一的运算符:++--

条件运算符:?:

强制类型转换运算符:

指针和地址运算符:*&

计算字节数运算符:sizeof

下标运算符:[]

结构体成员运算符:->

位运算符:>|^&~

逗号运算符:,分隔符:相邻保留字,标识符之间由空格或回车换行做分隔符:相邻同类项之间用逗号分隔

声明相同类型的变量之间可用逗号分离,向屏幕输出的变量中各变量表达式之间用

逗号分离。

常见的转义字符:n 换行r回车(不换行) 字符串结束t 水平制表

v 垂直制表b退格f走纸换页a响铃报警

” 双引号’单引号 一个反斜线?问号

常见错误

数组;数组的下标都是从0开始的,访问时发生下标多1或者少1都会越界访问内存错误

用变量来定义数组长度会导致语法错误,应该用整型常量或整型常量表达式定义

用a[x,y]而不是a[x][y]的形式来访问二维数组中的元素,将导致语法错误

(数组的第1个元素的下标是0,数组元素1是指数组元素的下标为1,是数组的第二个元素)

忘记对需要进行初始化的元素初始化,导致运行结果错误

对数组初始化的过程中,提供的初值个数多于数组所能容纳的元素个数定义字符数组长度时,必须要多留一个字节的存储单元,存放结束标志打印一个不包括字符串结束标志的,导致运行结果错误

直接使用赋值运算符对字符串赋值是错误的,必须用strcpy()赋值

直接使用关系运算符比较字符串大小是错误的,必须使用strcpy()比较

字符串必须使用双引号括起来,单引号括起来是错误的。

一对双引号将一个字符常量括起来,产生一个指向包含两个字符的字符串指针(把字符当做实参去调用形参是字符串的函数;把字符串当做实参去调用形参是字符的函数,都会导致语法的错误!)

误以为在函数中定义的静态局部数组元素中的元素,在每次函数调用时都初始化0(函数原型,函数定义的头部和函数调用语句三者,在形参和实参的数量,类型和顺序,以及返回值的类型上没有严格保持一致,将导致语法错误。)

指针:误以为用来声明指针变量的星号(*)会对同一个声明语句中的所有指针变量都起作用,而省略了其他指针变量名前的星号。实质是每一个每一个变量名前的星号都不能省略。

没有对指针变量进行初始化,或没有将指针变量指向内存中某一个确定存储单元的情况下,就利用这个指针变量去访问它所指向的存储单元,将导致严重的运行错误。没有意识到某些函数形参是属于“传地址掉调用”而数值不是指针当做实参赋值给这形参。

对没有指向数组中的某个元素的指针变量进行算数运算,是无意义的。

对并非指向同一数组中元素的两个指针进行相减或比较运算。是无意义的。每个数组都有上,下边界,指针超出了边界就会造成越界访问内存错误。

除非两个指针类型都是void,否则将一种类型的指针赋值给其他类型的指针,造成语法错误。

试图用一个void的指针变量去访问内存,是一个语法错误。

试图以指针运算的方式来改写一个数组名所代表的地址,是一个语法错误

内存分配不成功的话会导致非法内存访问错误,只要运行前检查指针是否为空指针,可以避免错误发生。

如果内存分配成功,但是没有初始化,将会导致非法内存访问错误。

向系统申请了一块内存,结束后忘了释放内存,造成内存泄露。

释放了内存,但却仍然使用,会产生“野指针”

结构体,共用体:定义一个结构体时,忘记最后加上一个分号,导致语法错误

将一种类型的结构体赋值给另一种类型的结构体,导致语法错误

对两个结构体或者共用体进行比较,导致语法错误

在结构体指向运算符的两个组成符号“-” 和“>”之间插了空格,或者写成“→”导致语法错误

只使用成员变量名访问结构体的一个成员,导致语法错误

直接使用结构体的每个成员类型所占内存字节数的“和”作为一个结构体实际所占的字节数。是错误的。

没有标明结构体数组下标 就访问其中一个结构体数组元素,导致语法错误。

函数

递归函数是需要返回值的,在递归函数中忘记返回数值,是错误的忘记了编写递归终止条件的分支语句,写错了递归步骤,都会导致递归函数不能收敛到递归的终止条件,引起无穷递归

定义函数指针时,忘记将函数指针变量名及前面的星号用圆括号括起来,使得本应声明函数指针变量的变量声明变成了一个函数声明语句。

将函数指针作为函数参数时,不在函数指针变量名后的一对圆括号中列出各函数参数的类型,导致编译错误。

实施细则

1.函数

1.函数指针:通式:数据类型(*指针名)()int(*p)()

错误:忘记前一个()意义是声明一个函数,函数名为P,返回值是一个指向整型变量的指针

忘记了后一个(),意义是定义了一个指向整型变量指针。使用:1.定义过程 2.函数指针赋值过程3.调用过程

2.递归:一个对象部分地由它和自己组成或它自己定义,称它是递归的。

3.返回指针值的函数:通式:数据类型*函数名(参数名){}

区别;不带*的函数值,函数值只能是一个数据,不能是一组带*的函数值,不仅是一个数据,还能是一组数据。

2.结构体,共用体

位段:指定了存储位数的结构体或共用体的成员叫位段

优点:用最少的位数存储数据注意:必须声明为int或unsigned型使用:用struct作为关键字,定义了unsigned 的三个位段

“:”代表位段宽度的整数常量,访问位段成员的方法与访问结构体成员的方法基本一致,用“圆点运算符”或“箭头运算符”

共用体:将不同的数据类型组合在一起,共占有同一段内存的用户自定义数据类型注意:必须有足够大的内存空间将占据最大内存空间的成员存储在内,内存空间的大小由占据内存空间成员所占的空间数决定。

动态数据结构:在结构体类型中,如果包含了本结构体类型的成员,由于本结构所占的内存字节数无法确定,系统无法正常分配内存。

声明结构体类型是不能包含自我,但可以包含指向本结构体类型的指针域。操作:

Structtemp

{

Intdata;

Structtemp*temp;

};

利用函数malloc()申请一个结构体的内存

Structtemp

{

Intdata;

Charname[10];

};

Structtemp *p;

P=(struct temp*)malloc(10*sizeof(structtemp));利用函数calloc()申请一个结构体内存

Structtemp *p

P=(struttemp*)calloc(10*sizeof(struct 利用函数free()释放申请的内存空间,链表的定义

temp));

《c语言基础总结.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
c语言基础总结
点击下载文档
相关专题 c语言知识基础总结 语言 基础 c语言知识基础总结 语言 基础
[其他工作总结]相关推荐
    [其他工作总结]热门文章
      下载全文