C语言总结笔记.docx
《C语言总结笔记.docx》由会员分享,可在线阅读,更多相关《C语言总结笔记.docx(23页珍藏版)》请在冰点文库上搜索。
C语言总结笔记
一、什么是C语言
C语言是面向结构的计算机高级语言,其兼具一般高级语言和低级语言的优点,c语言功能强大、应用广泛,既可以用来编写系统软件,也可以用来编写应用软件。
它具有以下几个特点:
(1)语言简洁、紧凑,使用方便、灵活。
C语言程序比其他许多高级语言简练,源程序短,因此输入程序时工作量少。
(2)运算符丰富。
C语言的运算符包含的范围很广泛,共有34种运算符,
(3)数据类型丰富。
C语言提供的数据类型有:
整型、浮点型、字符型、数组类型、指针类型、结构体类型、共用体类型等,能用来实现各种复杂的数据结构(链表、树、栈等)的运算。
(4)具有结构化的控制语句(如if…else语句、while语句、do…while语句、switch语句、for语句)。
用函数作为程序的模块单位,便于实现程序的模块化。
C语言是完全模块化和结构化的语言。
(5)语法限制不太严格,程序设计自由度大。
(6)C语言允许直接访问物理地址,能进行位操作,能实现汇编语言的大部分功能,可以直接对硬件进行操作。
(7)生成目标代码质量高,程序执行效率高。
(8)用c语言编写的程序可移植性好(与汇编语言比)。
二、c程序设计中的“共性”
(1)C程序是由函数构成的。
一个C源程序有且仅有一个main函数,也可以包含一个main函数和若干个其他函数。
因此,函数是C程序的基本单位。
(2)一个函数由两部分组成:
Ø函数的首部,即函数的第一行,包括函数名、函数类型、函数参数(形式参数)名、参数类型。
Ø函数体,即函数首部下面花括号内的部分。
函数体一般包括以下两部分。
●声明部分。
在这部分中定义所用到的变量和对所调用函数的声明。
●执行部分。
由若干语句组成。
(3)一个C程序总是从main函数开始执行的,而不论main函数在整个程序中的位置如何。
(4)C程序书写格式自由,目前使用的许多C编译系统,允许一行内写几个语句,一个语句可以写在多行上。
(5)每个语句和数据声明的最后必须有一个分号。
分号是C语句的必要组成部分。
(6)C语言本身没有输入输出函数语句。
输入输出由输入输出函数来完成。
(7)可以用/*……*/对c程序中的某行或某几行做注释。
三、运行C程序的步骤
上机输入与编辑源程序(.c)->对源程序进行编译,得到目标程序(.obj)->将目标程序与库函数连接,得到可执行程序(.exe)->运行可执行程序,得到运行结果。
四、程序的灵魂-算法
Ø程序=数据结构+算法
Ø为解决一个问题而采取的方法和步骤,就称为算法。
计算机算法分为两大类:
数值运算算法和非数值运算算法。
Ø算法描述:
自然语言、流程图、N-S流程图、伪代码、计算机语言。
五、数据类型、运算符与表达式
(1)数据类型
Ø在C语言中,数据类型可分为:
基本数据类型,构造数据类型,指针类型,空类型四大类。
Ø基本数据类型包括:
整型(短整型(shortint)、基本整型(int)、长整型(longint))、字符型(char)、实型(单精度型(float)、双精度型(double)、长双精度型(longdouble))、枚举类型(enum)
Ø构造类型包括:
数组类型、结构体类型(struct)、共用体类型(union)
(2)标识符:
在C语言中用来对变量、符号常量、函数、数组、类型等数据对象命名的有效字符序列统称为标识符。
标识符由字母、数字和下划线3种字符组成,且第一个字符必须为字母或下划线。
(3)基本数据类型
1)整型常量的表示方法:
Ø十进制整常量没有前缀。
Ø八进制整常数必须以0开头,数码取0~7,八进制通常是无符号数。
Ø十六进制整常数前缀0X或0x,数码取值0~9、A~F或a~f。
整型常数可以有后缀L或l、U或u,表示的整数范围要广,一般C编译系统给普通数分配两字节空间,长整型分配4字节空间。
2)整型变量
Ø在内存中,数值以补码表示。
Ø正数补码与原码相同,负数补码为绝对值按位取反再加1。
Ø整型变量分类:
基本整型(int)、短整型(shortint)在内存中都占两个字节,长整型(longint)占4字节。
(具体由编译系统决定)无符号型(unsigned)与上面三种类型匹配使用。
几个范围:
-32768~32767,0~65535
定义:
类型说明符变量名标识符,变量名标识符,...;
3)实型常量(也称为浮点型)
Ø表示方法:
十进制小数形式,如5.789;指数形式,aen(a为十进制数,n为十进制整数)
实型常数都按双精度double型处理。
标准c允许浮点数使用后缀,f或F,表示该数为浮点数。
4)实型变量
Ø实型数据一般占4字节内存空间,由数符(+、-)、小数部分、指数三部分构成,在TurboC中,单精度占4字节空间,只能提供7位有效数字。
双精度占8字节空间,可提供16位有效数字。
长双精度占16字节空间,可提供19位有效数字。
注意:
提供7位有效数字并不是说显示结果只有7位,只有前7位可以正确显示,之后的为无效数字。
双精度有效位16位,但是TurboC规定小数后最多保留六位,其余部分四舍五入。
5)字符常量
用单引号括起来的一个字符。
把数字括起来就不能当做数字进行数值运算。
6)转义字符
了解常用转义字符的含义。
如\n,\t,\b,\r,\\,\',\",\f,\ddd,\xhh。
理论上来说,c语言字符集中的任何一个字符均可以由转义字符表示,最后两个转义字符正是为此而提出的。
7)字符变量
每一个字符变量分配一个字节空间,因此只能存贮一个字符。
实际上字符是以ASCII码(美国标准信息交换码)的形式存储在空间单元里。
c语言允许把字符变量按整型量输出,也准许把整型量按字符量输出。
大小写字母的ASCII码相差32。
大写字母ASCII码数值较小。
8)字符串常量
Ø字符串常量由双引号括起来。
"CHINA","Cprogram"
Ø字符常量可以赋值给字符变量,但是C语言中没有相应的字符串变量。
Ø字符串常量可以用一个字符数组来存放。
字符串常量占的内存字节数等于字符串中字节数加1,增加的一个为"\0",结束符号。
如"a"的存放占2字节,'a'的存放占1字节。
(4)变量赋值
允许在变量定义时候赋值,但是不能连续赋值,如a=b=c=5是不合法的。
(5)各类数值型数据之间的混合运算
1)若参与运算量的类型不同,则先转换为同一类型,然后进行运算。
2)转换按数据长度增加的方向进行,以保证精度不降低。
3)所有的浮点运算都是以双精度进行的。
4)char型和short型参与运算时,必须先转换为int型。
5)赋值运算中,赋值号两边的数据类型不同时,赋值号右边量的类型将转换为左边的类型。
这可能导致精度丢失,丢失的部分按四舍五入。
6)强制类型转换:
(类型说明符)(表达式)。
该转换只是临时的转换,而不改变数据说明时对该变量定义的类型。
(6)算术运算符和算术表达式
C语言中的运算符和表达式数量非常多,使得C语言功能完善的同时增加了C语言的复杂度。
运算符具有优先级和结合性两个特点让运算十分灵活。
1)算术运算符和算术表达式
+-*/%、++i、--i、i++、i—
注1:
除法参与运算量均为整数时,结果也为整型,舍去小数。
如果运算量中有一个是实型,则结果为双精度实型。
如20/7结果为2,20.0/7=2.857143
注2:
C语言中左结合性指自左至右运算,如x+y+z,=号具有右结合性。
单目运算符、三目运算符、赋值运算符具有右结合性。
c语言中,有15个优先级,1级最高,15级最低。
注3:
求余运算符要求参与运算的均为整型。
注4:
单目,双目运算符的概念。
注5:
注意理解++i与i++的区别。
++i表示在执行++i所在语句时先有一条i=i+1指令,i++
表示在执行i++所在语句之后有一条i=i+1指令。
(7)赋值运算符和赋值表达式
=
它具有右结合性,如a=b=c=5可理解为a=(b=(c=5)),=定义为运算符的含义是凡是表达式可以出现的地方均可以出现赋值表达式。
赋值表达式会把右边的类型转换为左边的类型。
+=,-=,/=,%=,<<=,>>=,&=,^=,|=
复合赋值符的写法十分有利于编译处理,能提高编译效率并产生质量较高的目标代码。
(8)逗号运算符和逗号表达式
C语言中逗号也是一种运算符。
其功能是把两个表达式连接起来组成一个表达式
表达式1,表达式2
其求值过程是分别求两个表达式的值,并以表达式2的值作为整个逗号表达式值
如y=((x=2+2),3+3),则y的值为6
六、最简单的c程序设计-顺序程序设计
(1)c程序结构:
一个程序可以由多个源程序文件组成;每一个源程序文件由预处理命令、全局变量声明、函数1、函数2、„„函数n组成;每一个函数由函数首部和函数体构成;每一个函数体由局部变量声明、执行语句构成。
(2)程序功能由执行语句实现,c语句可分为5类:
1)表达式语句;2)函数调用语句;3)控制语句;4)复合语句;5)空语句
表达式;
函数名(实际参数表);
控制语句有9种;
复合语句由{}括起来;
只有“;”的语句称为空语句。
(3)赋值语句
注意在变量说明中,不允许连续给多个变量赋初值,如inta=b=c=5;是错误的。
而赋值语句允许连续赋值。
注意赋值语句和赋值表达式的区别。
语句有;号,而表达式没有。
表达式可以出现在允
许表达式出现的地方,而赋值语句则不能。
(4)数据输入输出的概念及在c语言中的实现
在C语言中,所有的输入/输出都是由库函数完成的。
在使用C语言库函数时,要用预编译命令#include将有关“头文件”包括到源文件中。
使用标准输入输出库函数要用到“stdio.h”文件,因此源文件开头应有以下预编译命令:
#include或#include"stdio.h"。
stdio是standardinput&output。
考虑到printf和scanf函数使用频繁,系统允许在使用这两个函数时可以不加。
(5)字符数据的输入输出
putchar(字符变量);字符输出函数,在显示器上输出单个字符。
对于控制字符则执行控制功能,不在屏幕上显示。
使用本函数前必须要用头文件包含命令:
#include或„„
eg:
putchar('A')输出A;putchar(x)输出x的值;putchar('\n')换行。
getchar();从键盘上输入一个字符。
通常把输入的字符赋予一个字符变量,构成赋值语句。
eg:
charc;c=getchar();
注意:
getchar函数只能接受单个字符,多余一个只接受第一个。
putchar(getchar());printf("%c",getchar());
(6)格式输入输出
printf("格式控制字符串",输出表列)格式输出函数。
f为格式(format)之意。
格式控制字符串以%开头后接格式字符。
格式字符:
[标志][输出最小宽度][.精度][长度]类型;[]为可选项。
标志:
-+空格#:
-表示左对齐,右边填空格;#对o类和x类输出时加前缀。
输出最小宽度:
若实际位数多余定义的宽度,则按实际位数输出,否则补空格精度:
若输出数字,表小数的位数,直接去掉多余位;若输出字符表字符个数长度:
h,l两种,分别表示按短/长整型输出。
scanf("格式控制字符串",地址表列)格式输入函数。
格式控制字符串:
%[*][输入数据宽度][长度]类型*符:
用以表示该输入项,读入后部赋予相应的变量。
宽度:
超过宽度的部分将被截去。
地址由地址运算符"&"后跟变量名组成eg:
&a,&b,&a是一个表达式,其功能是求变量的地址。
在输入多个字符数据时,C编译在碰到空格、tab、回车或非法数据时即认为该数据结束。
如12A,A为非法数据。
如果格式控制串中有非格式字符则输入时也要输入该非格式字符。
eg:
scanf("a=%d,b=%d,c=%d",&a,&b,&c);
a=5,b=6,c=7
eg:
scanf("%d%d%d",&a,&b,&c);
七、选择结构
(1)关系运算符:
C语言有6种,<,<=,>,>=,==,!
=
==和!
=的优先级在关系运算符中相对较低,关系运算符高于赋值运算符,低于算术运算符。
(2)逻辑运算符:
&&,||,!
,前两个具有左结合性,双目运算符。
优先级:
!
>算术运算符>关系运算符>&&和||>赋值运算符;!
>&&>||
(3)if-else语句和if-elseif-else语句。
if语句可以嵌套使用。
(4)条件运算符和条件表达式表达式1?
表达式2:
表达式3
如果表达式1的值为真,则以表达式2的值为条件表达式的值,否则以表达式3
eg:
max=(a>b)?
a:
b;
注意:
条件表达式是右结合,结合方向自右向左。
eg:
a>b?
a:
c>d?
c:
d应理解为a>b?
a:
(c>d?
c:
d)
(5)多分支选择语句switch
switch(表达式){
case常量表达式1:
语句1;
case常量表达式2:
语句2;
……
case常量表达式n:
语句n;
default:
语句n+1;
}
八、循环控制方法四种
(1)goto语句和if语句构成循环;
goto语句标号;
goto是无条件转移指令。
标号是一个有效的标识符加上一个":
"一起出现在函数的某处。
goto语句一般不用,因为它使得程序层次不清,且不易读懂,但在多层嵌套退出时,用goto语句则比较合理。
(2)while(表达式)语句;
(3)do
语句
while(表达式)
(4)for(表达式1;表达式2;表达式3)语句
其最简单应用形式:
for(循环变量赋初值;循环条件;循环变量增量)语句
注意:
三个表达式均可以省略,要注意省略所带来的问题。
(5)break语句
跳出switch、do-while、while、for。
break对if-else不起作用,break用于多层循环嵌套,一次只跳出一个循环。
(6)continue:
跳出本次循环。
九、数组
(1)一维数组
定义方式:
类型说明符数组名[常量表达式(元素个数)];
eg:
inta[10];charch[20];
数组名不能与其它变量重名。
比如inta;floata[10];是不对的。
方括号中不能用变量来表示元素的个数,但可以是符号常数或常量表达式。
调用:
数组名[下标];
在c语言中只能逐个使用下标变量,而不能一次引用整个数组。
a[5.2]=a[5.8]=a[5]当下标不为整数时,自动取整。
赋值:
inta[10]={0,1,2,3,4,5};intb[]={1,2,3}
可以只给部分元素赋初值。
只能给元素逐个赋值。
若给全部元素赋值,可以不指定元素个数。
(2)二维数组
定义方式:
类型说明符数组名[常量表达式1][常量表达式2]
引用:
数组名[下标][下标]
注意区分下标和数组说明时下标的不同,数组说明时只能是常量,它是说明数组在某一维上的最大长度,而引用时候的下标可以是常量、变量或表达式。
赋值:
inta[3][2]={{1,2}{5,6}{7,3}};
对于二维数组的初始化说明:
1)可以只对部分元素初始化,未赋值的元素自动取0值。
2)如果全部元素赋初值,则第一维长度可以不给出。
3)二维数组可以分解为一维数组的组合
(3)字符数组
charc[]={"Cprogram"};
charc[]={'C','','p','r','o','g','r','a','m'};
上面两种方法可以得到一样的输出结果,但是字符串赋值比用字符逐个赋值多占一个字节,用于存放字符结束标志'\0'。
'\0'是由C编译系统自动加上的,由于采用'\0'标志,所以在用字符串赋初值时一般无需指定数组长度,而由系统自定。
若没有给字符串数组赋初值,则必须对其指定长度。
采用字符串方式对于字符数组的输入输出也有帮助,在输出时可以直接用字符串变量名
表示字符串。
printf("%s\n",c),c为字符串名。
当用scanf函数输入字符串时若输入空格字符,将被当做结束标志。
eg:
scanf("%s%s%S%s",st1,st2,st3,st4);st1,st2,st3,st4分别为字符串
(4)字符串处理函数
puts(字符数组名):
把字符数组的字符串输出到显示器。
gets(字符数组名):
从标准输入设备键盘输入一个字符串。
若使用gets函数,当输入字符串中含有空格时,输出仍未所有字符,说明gets函数并不以空格作为结束标志,而只以回车作为结束标志。
这是与scanf函数不同的地方。
strcat(字符数组名1,字符数组名2):
把字符数组2中的字符串连接到字符串1的后面,并删去字符串1后的标志“\0”。
本函数返回值是字符数组1的首地址。
strcpy(字符数组名1,字符数组名2);将s2拷贝到s1,s1要够长。
返回s1首地址。
strcmp(字符数组名1,字符数组名2);按照ASCII码进行比较,返回比较结果。
从第一个字母开始往后比。
若s1=s2,返回0;若s1>s2,返回>0;若s1strlen(字符数组名):
测字符串实际长度(不含字符串结束标志'\0')并作为返回值。
十、函数
(1)main函数是主函数,允许它调用其它的函数,不允许其它函数调用它。
C程序的执行总是从main开始,完成对其它函数的调用后再返回到main函数,最后由main结束。
一个C程序,必须有且只能有一个main函数。
函数的使用要在主函数中像变量一样先声明后使用。
(2)函数的定义:
[]内容为可选
类型标识符函数名([形式参数列表])
{声明部分
语句
}
(3)实参和形参
形参只有在被调用时才分配内存单元,其作用域是函数内部,函数调用结束返回主函数
则不能使用该形参。
函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,而
不能反向操作。
实参和形参是函数实现主调函数向被调函数传送数据的方式,在传递时,实
参的值必须是确定的,而且应该与形参在数量上、类型上、顺序上严格一致。
(4)函数返回值
函数值只能通过return(表达式);或return表达式;返回。
函数中允许有多个return,但是每次调用只能有一个return语句被执行,因此只能返回一个函数值。
不返回函数值的函数应该定义为void类型。
(5)函数的调用:
不用多说,函数名(实际参数表)。
注意的是主调函数中调用某函数之前应该对被调函数进行说明(声明)。
C语言中主调函数可以省去对被调函数说明的情况:
1)被调函数的返回值是整形或字符
型,系统自动对被调函数返回值按整型处理。
2)被调函数定义出现在主调函数之前。
3)如
果在所有函数定义之前,在函数外预先说明各个函数的类型。
(6)函数的嵌套和递归调用
(7)使用数组名作为函数参数:
数组名也就相当于数组的首地址,当把首地址赋给形参时,形参的数组与实参的数组占用的是相同的内存单元。
这点与变量或常量作为形参是不同的,变量和常量作为形参,计算机为实参和形参分配了不同的内存单元,数据是单向传递,但是用数组名作为形参时数据是双向传递的。
使用时注意:
1)形参数组和实参数组类型必须一致。
2)形参数组和实参数组长度可以不一样,因为调用时只传送首地址而不检查长度。
3)在函数参数表中,允许不给出形参数组的长度,或用一个变量来表示数组元素的个数。
eg:
voidnzp(inta[],intn)其中形参a没有给出长度,由n值动态指定,n值由主调函数的实参进行传送。
十一、指针
(1)指针编程是C语言最主要的风格之一,是C语言中广泛使用的一种数据类型。
利用指针可以表示各种数据结构;能方便地使用数组和字符串;能处理内存地址,从而编出精练的高效程序。
(2)指针就是某个内存单元的地址,对于某个单元来说,单元的地址即为指针,其中存放的数据才是单元内容。
C语言中,允许用一个变量来存放指针,这种变量称为指针变量。
因此,一个指针变量的值就是某个内存单元的地址或称为某个内存单元的指针。
严格地说,一个“指针”是一个地址,是一个常量,“指针变量”是指取值为地址的变量。
定义指针的目的就是为了通过指针去访问内存单元。
(3)变量的指针和指向变量的指针变量
这句话很拗口,但是要搞清楚它。
变量的指针就是变量的地址,指向变量的指针变量就
是指针变量的值是变量所在地址。
eg:
i_pointer为011A,地址011A中的内容为3,i=3;*i_pointer=3;第二个语句的含义是将3赋给指针变量所指向的变量i,i在011A单元。
(4)指针变量的定义:
类型说明符*变量名;
指针变量的定义包括三个内容:
指针类型,指针变量名,指针所指向的变量的类型。
*
表示这是一个指针变量。
一个指针变量只能指向同类型的变量。
如char*p3;p3指向浮点变量,具体指向的变量值由对p3所赋的值来决定。
(5)指针变量的引用:
指针变量使用之前不仅要定义,而且必须赋予具体的值。
未经赋值的指针不能使用,否则会造成系统混乱。
指针变量只能赋予地址,在C语言中,变量的地址是由编译系统分配的,对用户不透明,有两个有关的运算符:
1)&:
取地址运算符,用来表示变量的地址。
2)*:
指针运算符(或称为间接访问运算符)。
不能把一个数赋予指针变量。
eg:
inta;int*p;p=&a;
p++表示p指向下一个数据地址地址,如对int型,p++则p的值增加2,对float型,p++则p的值增加4。
可以利用指针完成返回多个数的功能,如交换两个数,需要函数返回两个值,用指针可
以不用返回值做到。
(6)指针变量的运算:
inta,*pa;pa=&a;
inta,*pa=&a,*pb;pb=pa;
inta[5],*pa;pa=a;(或pa=&a[0];)
char*pc="CLanguage";把存放字符串的字符数组的首地址装入指针变量。
int(*pf)();pf=f;f为函数名,把函数的入口地址赋予指向函数的指针变量。
指针与数字的加法运算:
数组指针变量的加1指的是指针变量指向后一个数据元素的首地址,而不是原地址基础上加1。
两个指针变量之间的运算:
1)指针变量的加减法运算只能对数组指针变量进行,对指向其它类型变量的指针变量作加减运算是毫无意义的。
2)只有指向同一数组的两个指针变量之间才能进行运算,否则运算毫无意义。
两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。
如pf1和pf2是指向同一浮点数组的两个指针变量,设pf1为2010H,pf2为2000H,而浮点数每个元素占4字节,所以p