C语言复习手记

来源:互联网 发布:淘宝客服节假日放假吗 编辑:程序博客网 时间:2024/06/05 02:39

经过几天的整理,将C语言的大致重点整理了出来,还有一些像指针、文件操作、链表等一些算法的内容,后面以专题来整理。整理过程中如果有错误,欢迎指出,我们同学习,共进步!

实型常量有两种表现形式:
其一就是像我们平常的小数12.5
其二就是传说中的指数形式0.125e2,但是指数形式表达需要注意,e或E的前面必须要有数字,且e或E后面的数字必须为整数

字符常量有一类特殊形式的字符,它们就是转义字符,每个转义字符代表不同的含义,占一个字节的空间
\a 响铃(BEL) 007
\b 退格(BS) 008
\f 换页(FF) 012
\n 换行(LF) 010
\r 回车(CR) 013
\t 水平制表(HT) 009
\v 垂直制表(VT) 011
\ 反斜杠 092
\? 问号字符 063
\’ 单引号字符 039
\” 双引号字符 034
\0 空字符(NULL) 000
\ooo 任意字符 三位八进制
\xhh 任意字符 二位十六进制
注意不要将字符常量与字符串常量弄混,‘’之间只能包含一个字符,字符串常量末尾会自动加上一个“\0”表示字符串结束,所以“Hello”其实是六个字符

符号常量用#define定义,将一个常量用一个符号来表示,符号常量一般用大写表示,不占用存储空间
#define PI 3.1415926 //注意没有分号

常变量用count声明:count int a = 3.14;
常变量与符号常量的区别是:两者的值都是不能被改变的,符号常量是用#define定义的,是在预编译的时候就将程序中对应的符号常量全部替换成对应的值,所以说符号常量在预编译之后就不存在了,故不占用存储空间,而常变量还是存在于存储单元中的,可以被调用,常量是没有名字的不变量,而常变量是有名字的不变量
常变量与变量之间的区别是:两者都是变量,都有类型,占空间,只是常变量不允许更改其值,这个专门为不能改其值,而又要重复调用的值准备的
符号常量、常变量和变量三者各有各的用处

对于数据类型所占空间问题,不同的编译器对其是有不同的定义的,如Turbo C为每个INT 类型的变量分配了两个字节,而VC6.0则为INT类型的变量分配了4个字节,我们可以用sizeof(数据类型)来查看每个数据类型所占用的空间
小技巧:当我们用malloc分配空间时,可以直接用sizeof(数据类型)*数据个数的方式来分配空间

变量其实就是拿一个符号表示一个存储空间的地址

unsigned表示无符号的整型(包括字符型),我们可以直接用无符号整型,这样可以增加我们的存储范围
当我们输出整型数据的时候,要用“%u”的格式来进行输出

在C语言中,认为大写字母和小写字母是两个不同的字符,标识符一般由字母、数字和下划线组成,只能由字母或者下划线开头

多数的C编译器采取向零取整的方法

%运算符要求参与运算的对象都是整数,除了%运算符以外的运算符操作数可以是任何算术类型

在使用自增、自减运算符的时候,注意添加括号,避免i+++j的存在

不同的数据类型的数据之间可以进行混合运算,必要的时候可以用(类型名)(表达式)进行强制类型转换

空语句可以作为延时的循环语句体来使用,也可以作为流程的转向点来使用

活用复合运算符、三目运算符可以提高程序的效率和美观性,减少程序大小

在运算过程中,如果有int、float、double三种数据类型,那么最后结果是什么数据类型呢?
答案是:double,当不同数据类型的数据进行运算时,最后结果会朝着范围大的数据类型发展

C语言本身不提供输入输出语句,我们使用的printf、scanf、getchar是函数库中提供的一些函数供我们调用,我们在调用他们的时候,一定要先预编译他们的函数库头文件

当我们输出数值的时候,我们都要限定小数的位数,这时候可以在格式字符前面加m.n,m表示输出的列数是m位,其中有n位是小数。如果你想保留7位小数,你可以这么输出——printf(“%10.7f”,a);
如果指定列宽,显示列数小于指定列数,那么默认右对齐,不足位由空格填补。如果想要左对齐显示,在m.n前面加个-即可;

使用scanf输入时,应遵循原样输入的原则,如一次性输入多个值,最好用空格或其他符号隔开,避免歧义;

putchar():输出一个字符;
puts():输出字符串;
getchar():输入一个字符;
gets():输入字符串到数组,返回的函数值就是字符串的起始地址;
对于puts()和gets()两个函数而言,他们一次性只能输入或者输出一个字符串;

三目运算符即:表达式1?表达式2:表达式3;如果表达式1的结果为真,那么执行表达式2的语句,反之执行表达式3的语句;

对于选择语句和循环语句的嵌套问题,层次清楚,擅用{}会减少很多麻烦;

switch语句的实现表达式:
switch(表达式)
{
case 常量1:语句1;
case 常量2:语句2;
……
default:语句n;
}

while语句循环分为前测while循环和后测while循序,后测while循环至少执行一次程序体里面的语句;

对于for循环语句,主要针对已知循环次数的情况,当然for语句和while语句可以互相转换;
for循环的三个表达式原则上都可以省略,以实现不同的效果,如果三个表达式都省略,那个循环将会无终止的执行下去;

break语句用于提前终止循环;
continue语句用于提前结束本次循环;
return语句用于提前终止当前函数;

对于数组初始化的问题,如果不对变量进行初始化设置,那个里面的值就是垃圾值,很可能对程序造成未知的错误;

对于字符串来说,我们可以将他们看做是一个数组,且这个数组一定有一个”\0”作为字符串结束的标志,如果数组中有多个”\0”,以最前面的”\0”为准;
可用输出整数数值的方式,输出字符串,那么就可以显示字符串起始位置的地址,当然通过指针也可以得到;

strcat():字符串连接函数,将字符串2接在字符串1后面
strcpy()和strncpy():字符串复制函数,将字符串2复制到字符数组1中;strncpy()是将字符串2中的前N个字符复制到字符串数组1中;
注意:不能用赋值语句将一个字符常量或字符数组直接赋值给一个字符数组
strcmp():字符串比较函数,将字符串1和字符串2自左向右逐个字符进行比较,相等则返回0,字符串1>字符串2则返回一个正整数,反之返回一个负整数;
strlen():测试字符串的长度,注意不包括”\0”;
strlwr():转换为小写字母;
strupr():转换为大写字母;

对于一个庞大的项目工程来说,一般不把所有的内容都放在一个源文件中,而是每个源文件作为实现某个功能的一个模块,由若干模块实现整体的效果,这样便于我们的编写和调试;同理就是说,一个源文件可以别多个程序所调用;

所有的函数都是相互独立的一个关系,故不存在嵌套定义函数的方式,我们就可以相互调用,但是我们不能调用main函数,这是被操作系统调用的

从函数时候有传参来看,可以将函数分为有参函数和无参函数,对于main函数来说,他是个无参函数,但是他有返回值,它返回的是0,我们在有的程序中会看见,void main()这样的书写方式,这样问题不大,程序也可以正常运行,但是”return 0”的作用是当程序正常运行结束之后返回0,给系统一个信号,说明我已经正常运行结束了,如果没有的话,当程序出错时,可能表面并没有现象,但是出现的结果就是有问题的,你自己都不知道问题在哪里,所以,一般我们这样”int main(void)”来写,结尾时用”return 0”返回结束信号;

我们在定义函数时,括号中的参数我们称之为形式参数;在主调函数调用一个函数时,函数后面括号中的参数我们称之为实际参数;实参和形参的数据类型应该是相同的,当函数调用完毕后,形参的存储单元将会被释放;

return语句其一的作用就是返回函数的结果,即返回返回值。一般来说,返回值的类型应该和定义函数的类型是相同的;

我们一般将自己定义的函数写在main函数的后面,这是我们需要在main函数的前面或者main函数体中先声明函数,然后再调用函数,不然可能会出现问题;

我们在调用函数的过程中,可能会直接或间接的调用函数本身,这种函数的调用,我们称之为递归调用(详见专题);

我们可以将数组作为函数的参数传参给函数进行处理,在定义函数时,数组形参可以不指定大小;

每一个变量和函数都有两个属性,一个是数据类型,另外一个就是数据的存储类型,我们将存储类型分为4种:自动(auto)、静态(static)、寄存器(regi)、外部(extern);内存中供我们使用的空间大致可以分为三种:程序区、静态存储区、动态存储区
我们默认的就是自动存储类型,它们自动分配存储空间(故相同名字的变量,每次的存储地址都不相同),当我们调用完或者说函数结束后,存储空间就会被释放;
静态局部变量是存在于静态存储区的数据,在程序的整体执行过程中,都不回被释放,但他只是不被释放而已,还是可以对他的值进行修改的;如果在定义的过程中,我们没有对他们进行赋值的话,编译时会自动赋初值0或者空字符”\0”;虽然说变量没有被释放,但是它终究是局部变量,别的函数还是无法调用他的;
寄存器变量(可以不关注,因为现在编译系统可以自动识别使用频繁的变量,不需要我们特意指定了)

我们有时为了反映相互独立的变量他们之间的内在联系,我们将多个数据类型复合起来,组成一个数据类型,这就是我们的结构体类型;定义:struct 结构体名{成员列表(类型名 成员名)}结构体变量名;
我们将结构体定义好后可以直接定义结构体变量,就是上面这种方法,我们还可以像一般定义变量那样:struct 结构体名 结构体变量名;
结构体其实和我们一般的变量的定义等操作,都是类似的,唯一不同的是我们对其的赋值和调用,因为结构体中由多个变量组成,所以我们在调用的时候,要指明是哪个结构体变量的哪个值,调用的方法:结构体变量名.成员变量名,在所有运算符中,’.’运算符的优先级别是最高的,当我们面临结构体成员变量本身有属于一个结构体类型,我们在进行操作时,只能对最低级别的成员变量进行操作;
同类型的结构体之间可以相互赋值,但是,我们在输出的时候,不能直接”printf(“a.a = %d\na.b = %d\n”,a);”,正确的是:printf(“a.a = %d\na.b = %d\n”,a.a,a.b);
同样的,结构体也有指针,我们在定义的时候跟一般变量的方法相同,我们在调用的时候,是这样的:(*a).a,或者我们可以写成a->;
数据的存储方式有很多种,像我们的数组就是按顺序存储的存储方式,但是一旦数组所需要的空间很大,或者说,我们内存连续的存储空间很小,达不到要求的时候,数组就显得不够用了,我们可以用结构体用链表的方式实现随机存储,可以更好结束大数据量的问题,两种方式各有好处,数组寻找数据的速度就比链表要快很多;后续会讲链表的创建方法;

刚才讲了结构体,还有一种数据结构跟结构体很像——共用体,相比而言他们的区别是:结构体是:把不同类型的数据组合成一个整体,他们各自都有一块存储空间;而共用体是使几个不同类型的变量共占一段内存,只能有一个变量存在(相互覆盖);定义:union 共用体名{成员列表(类型名 成员名)}共用体变量名;结构体和共用体的定义、声明基本相同;

如果你想限定某个变量的值,你可以用枚举将所有的可能性都列举出来,定义:enum 枚举名{枚举元素列表}枚举变量名;其实我们在给枚举定义的时候,编译器默认将枚举的成员列表进行编号,第一个成员是0,第二个是1,以此类推,所以枚举元素可以拿来做判断比较;

有些类型形式复杂,理解困难,容易写错,这是我们可以用typedef声明新的类型名;声明方法:typedef 原类型名 新类型名;

1 0
原创粉丝点击