C语言程序设计第三版笔记谭浩强.docx
- 文档编号:6047028
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:13
- 大小:24.43KB
C语言程序设计第三版笔记谭浩强.docx
《C语言程序设计第三版笔记谭浩强.docx》由会员分享,可在线阅读,更多相关《C语言程序设计第三版笔记谭浩强.docx(13页珍藏版)》请在冰豆网上搜索。
C语言程序设计第三版笔记谭浩强
第一章 概述
●学习C语言的用途
①C对操作系统和系统实用程序以及对硬件进行操作方面,C有明显的优势。
现在很多大型应用软件也用C编写。
绝大多数操作系统都是由C或C++语言编制。
特别是嵌入式操作系统。
②是学习其他课程的基础(比如数据结构、操作系统原理、编译原理等)
③是学习C++或C#和JAVA语言的基础
1.1.C语言的诞生:
C语言是在B语言的基础上发展起来的,B(BCPL)语言是1970年由美国贝尔实验室设计的,并用于编写了第一个UNIX操作系统,在PDP7上实现。
优点:
精练,接近硬件,缺点:
过于简单,数据无类型。
1973年贝尔实验室的D.M.Ritchie在B语言的基础上设计出了C语言,对B取长补短,并用之改写了原来用汇编编写的UNIX,(即UNIX第5版),但仅在贝尔实验室使用。
1975年UNIX第6版发布,C优点突出引起关注。
1977年出现了《可移植C语言编译程序》,推动了UNIX在各种机器上实现,C语言也得到推广,其发展相辅相成。
1978年影响深远的名著《TheCProgrammingLanguage》由BrianW.Kernighan和DennisM.Ritchie合著,被称为标准C。
之后,C语言先后移植到大、中、小、微型计算机上,已独立于UNIX和PDP,风靡世界,成为最广泛的几种计算机语言之一。
1.2.C语言的特点
①语言简洁、紧凑,使用方便、灵活。
共有32个关键字,9种控制语句。
②运算符丰富,共有34种运算符。
③数据结构丰富,数据类型有:
整型、实型、字符型、数组、指针、结构体、共用体等。
④具有结构化的控制语句(如if…else、while、do…while、switch、for)
⑤语法限制不太严格,程序设计自由度大。
⑥允许直接访问物理地址,能进行位(bit)操作,可以直接对硬件操作。
⑦生成目标代码质量高,程序执行效率高。
⑧可移植性好。
C程序:
(1)C程序是由函数构成的。
这使得程序容易实现模块化。
(2)一个函数由两部分组成:
函数的首部:
例1.3中的max函数首部
intmax(intx,inty)
函数体:
花括号内的部分。
若一个函数有多个花括号,则最外层的一对花括号为函数体的范围。
函数体包括两部分:
声明部分:
inta,b,c;可缺省
执行部分:
由若干个语句组成。
可缺省
(3)C程序总是从main函数开始执行的,与main函数的位置无关。
(4)C程序书写格式自由,一行内可以写几个语句,一个语句可以分写在多行上,C程序没有行号。
(5)每个语句和数据声明的最后必须有一个分号。
(6)C语言本身没有输入输出语句。
输入和输出的操作是由库函数scanf和printf等函数来完成的。
C对输入输出实行“函数化”。
第二章 数据类型、运算符与表达式
1.C的数据类型
C的数据类型包括:
整型、字符型、实型或浮点型(单精度和双精度)、枚举类型、数组类型、结构体类型、共用体类型、指针类型和空类型。
2.常量与变量
常量其值不可改变,符号常量名通常用大写。
变量其值可以改变,变量名只能由字母、数字和下划线组成,且第一个字符必须为字母或下划线。
否则为不合法的变量名。
变量在编译时为其分配相应存储单元。
3.整型数据
整型常量的表示方法:
十进制不用说了,八进制以0开头,如0123,十六进制以0x开头,如0x1e。
整型变量分为:
基本型(int)、短整型(shortint)、长整型(longint)和无符号型。
不同机器上各类数据所占内存字节数不同,一般int型为2个字节,long型为4个字节。
4.实型数据
实型常量表示形式:
十进制形式由数字和小数点组成(必须有小数点),如:
0.12、.123、1230.0等。
指数形式如123e3代表123×10的三次方。
实型变量分为单精度(float)和双精度(double)两类。
在一般系统中float型占4字节,7位有效数字,double型占8字节,15~16位有效数字。
5.字符型数据
字符变量用单引号括起来,如'a','b'等。
还有一些是特殊的字符常量,如'\n','\t'等。
分别代表换行和横向跳格。
字符变量以char来定义,一个变量只能存放一个字符常量。
字符串常量是由双引号括起来的字符序列。
这里一定要注意'a'和"a"的不同,前者为字符常量,后者为字符串常量,c规定:
每个字符串的结尾加一个结束标志'',实际上"a"包含两个字符:
'a'和''。
6.数值型数据间的混合运算
整型、字符型、实型数据间可以混合运算,运算时不同类型数据要转换成同一类型再运算,转换规则:
char,short->int->unsigned->long->double<-float
7.运算符和表达式
c运算符包括:
算数运算符( + - * / % )
关系运算符(><==>=<=!
=)
逻辑运算符(!
&&||)
位运算符(<<>>~|^&)
赋值运算符( =)
条件运算符( ?
:
)
逗号运算符(,)
指针运算符(*&)
求字节数(sizeof)
强制类型转换(类型)
分量运算符( .->)
下标运算符( [])
其它运算符( 如函数调用运算符())
自增自减运算符( ++--)注意:
++i和i++的不同之处,++i使用i之前先使i加1,i++使用i之后,使i加1。
逗号表达式的求解过程:
先求解表达式1,再求解表达式2,整个表达式的值是表达式2的值。
第三章最简单的c程序设计
1.c的9种控制语句:
if()~else~
for()~
while()~
do~while()
continue
break
switch
goto
return
程序的三种基本结构:
顺序结构,选择结构,循环结构
2.数据输出
c语言不提供输入输出语句,输入输出操作是由c的库函数完成。
但要包含头文件stdio.h。
putchar()向终端输出一个字符
printf()的格式字符:
①d格式符 用来输出十进制整数
%d按整型数据的实际长度输出
%md使输出长度为m,如果数据长度小于m,则左补空格,如果大于m,则输出实际长度
%ld输出长整型数据
②o格式符 以八进制形式输出整数
③x格式符 以十六进制形式输出整数
④u格式符 用来输出unsigned型数据,以十进制形式输出
⑤c格式符 用来输出一个字符
⑥s格式符 输出一个字符串
%s 输出实际长度字符串
%ms输出的串占m列,如果串长度小于m,左补空格,如果大于m,实际输出
%-ms输出的串占m列,如果串长度小于m,右补空格,
%m.ns输出占m列,但只取字符串中左端n个字符并靠右对齐
%-m.nsm、n含义同上,靠左对齐,如果n>m,则m自动取n值
⑦f格式符 以小数形式输出实数
%f整数部分全部输出,小数部分输出6位
%m.nf输出数据共占m列,其中有n位小数。
如果数值长度小于m,左补空格
%-m.nf同上,右补空格
⑧e格式符 以指数形式输出实数
%e系统指定6位小数,5位指数(e+002)
⑨g格式符 输出实数,根据数值大小,自动选f格式或e格式
3.数据输入
getchar()从终端输入一个字符
scanf(格式控制,地址列表)标准Cscanf中不使用%u,对于unsigned型数据,以%d或%o或%x输入。
%后的*,用来跳过它相应的数据。
输入数据时不能规定精度如scanf("%7.2f",&a);是不合法的。
第四章逻辑运算和判断选取控制
1.关系运算符:
c提供6种关系运算符(><<=>===!
=)前四种优先级高于后两种。
2.If语句
C提供了三种形式的if语句
If(表达式)语句
If(表达式)语句1else语句2
If(表达式1)语句1
Elseif(表达式2)语句2
…
else语句n
3.条件运算符
(a>b)?
a:
b条件为真,表达式取值a,否则取值b
4.Switch语句
Switch(表达式)
{
case常量表达式1:
语句1;break;
case常量表达式2:
语句2;break;
…
case常量表达式n:
语句n;break;
default:
语句n+1;
}
第五章循环控制
1.几种循环语句
goto语句(现已很少使用)
while语句 先判断表达式后执行语句
do-while语句 先执行语句后判断表达式
for语句
2.Break语句和continue语句
Break语句用于跳出循环,continue用于结束本次循环。
第六章数组
1.一维数组
c规定只有静态存储(static)和外部存储(extern)数组才能初始化。
给数组初始化时可以不指定数组长度。
2.二维数组
3.字符数组
部分字符串处理函数
puts(字符数组) 将一个字符串输出到终端。
gets(字符数组)从终端输入一个字符串到字符数组,并且得到一个函数值,为该字符数组的首地址
strcat(字符数组1,字符数组2) 连接两个字符数组中的字符串,数组1必须足够大。
Strcpy(字符数组1,字符串2) 将字符串2拷贝到字符数组1中。
Strcmp(字符串1,字符串2)比较字符串,相等返回0,字符串1>字符串2,返回正数,小于返回负数。
Strlen(字符数组)求字符串长度。
Strlwr(字符串) 将字符串中的大写字母转换成小写
Strupr(字符串) 将字符串中的小写字母转换成大写
以上是一些比较常用的字符串处理函数。
第七章函数
1.关于形参和实参的说明
①在函数被调用之前,形参不占内存
②实参可以是常量、变量或表达式
③必须指定形参的类型
④实参与形参类型应一致
⑤实参对形参的数据传递是"值传递",即单向传递
2.函数返回值
如果想让函数返回一个值,在函数中就要用return语句来获得,在定义函数时也要对函数值指定类型,如果不指定,默认返回整型。
3.函数调用
1)注意在函数调用时实参和形参的个数、类型应一一对应。
对实参表求值的顺序是不确定的,有的系统按自左至右,有的系统则按自右至左的顺序。
这一点要注意。
2)函数调用的方式:
函数语句,函数表达式,函数参数
3)如果主调函数和被调函数在同一文件中,并且主调函数在前,那么一般要在主调函数中对被调函数进行说明。
除非:
(1)被调函数的返回值类型为整型或字符型
(2)被调函数出现在主调函数之前。
4)对函数的说明和定义是不同的,定义是指对函数功能的确立,包括指定函数名,函数值类型,形参及其类型、函数体等。
说明则只是对已定义的函数返回值类型进行说明,只包括函数名、函数类型以及一个空的括弧,不包括形参和函数体。
5)c语言允许函数的递归调用(在调用一个函数的过程中又出现直接或间接的调用该函数本身)。
4.数组作为函数参数
1)数组元素作为函数参数 和一般变量相同
2)数组名作参数应该在主调和被调函数分别定义数组,形参数组的大小可以不定义。
注意:
数组名作参数,不是单向传递。
3)多维数组作参数,在被调函数中对形参数组定义时可以省略第一维的大小说明,但不能省略第二维或更高维的说明。
5.局部变量和全局变量
从变量作用域角度分,变量可分为局部变量和全局变量。
1)内部变量(局部变量)
在一个函数内定义,只在函数范围内有效的变量。
2)外部变量(全局变量)
在函数外定义,可以为本文件其它函数所共用,有效范围从定义变量的位置开始
到本文件结束。
建议尽量少使用全局变量,因为它在程序全部执行过程中都占用
资源,而且使函数的通用性降低了。
如果在定义外部变量之前的函数要想使用该
外部变量,则应在该函数中用extern作外部变量说明。
6.动态存储变量与静态存储变量
从变量值存在的时间(生存期)角度来分,可分为静态存储变量和动态存储变量。
静态存储指在程序运行期间给变量分配固定的存储空间,动态存储指程序运行期间根据需要动态的给变量分配存储空间。
C语言中,变量的存储方法分为两大类:
静态存储类和动态存储类,具体包括:
自动的(auto),静态的(static),寄存器的(register),外部的(extern)。
1)局部变量的存储方式
函数中的局部变量如不作专门说明,都之auto的,即动态存储的,auto可以省略。
局部变量也可以定义为static的,这时它在函数内值是不变的。
静态局部变量如不赋初值,编译时系统自动赋值为0,动态局部变量如不赋初值,则它的值是个不确定的值。
C规定,只有在定义全局变量和局部静态变量时才能对数组赋初值。
为提高执行效率,c允许将局部变量值放在寄存器中,这种变量叫register变量,要用register说明。
但只有局部动态变量和形式参数可以作为register变量,其它不行。
2)全局变量的存储方式
全局变量在函数外部定义,编译时分配在静态存储区,可以在程序中各个函数所引用。
多个文件的情况如何引用全局变量呢?
假如在一个文件定义全局变量,在别的文件引用,就要在此文件中用extern对全局变量说明,但如果全局变量定义时用static的话,此全局变量就只能在本文件中引用了,而不能被其它文件引用。
3)存储类别小结
从作用域角度分,有局部变量和全局变量
局部变量:
自动变量,即动态局部变量(离开函数,值就消失)
静态局部变量(离开函数,值仍保留)
寄存器变量(离开函数,值就消失)
(形参可定义为自动变量和寄存器变量)
全局变量:
静态全局变量(只限本文件引用)
全局变量(允许其它文件引用)
从存在的时间分,有静态存储和动态存储
动态存储:
自动变量(本函数内有效)
寄存器变量(本函数内有效)
形参
静态存储:
静态局部变量(函数内有效)
静态全局变量(本文件内有效)
全局变量(其它文件可引用)
从变量值存放的位置分
静态存储区:
静态局部变量
静态全局变量
全局变量
动态存储区:
自动变量和形参
寄存器内:
寄存器变量
7.内部函数和外部函数
内部函数:
只能被本文件中的其它函数调用,定义时前加static,内部函数又称静态函数。
外部函数:
可以被其它文件调用,定义时前加extern,如果省略,则隐含为外部函数,在需要调用此函数的文件中,一般要用extern说明。
第八章预编译处理
c编译系统在对程序进行通常的编译之前,先进行预处理。
c提供的预处理功能主要有以下三种:
1)宏定义 2)文件包含 3)条件编译
1.宏定义
不带参数的宏定义
用一个指定的标识符来代表一个字符串,形式:
#define标识符字符串
几点说明:
1)宏名一般用大写
2)宏定义不作语法检查,只有在编译被宏展开后的源程序时才会报错
3)宏定义不是c语句,不在行末加分号
4)宏名有效范围为定义到本源文件结束
5)可以用#undef命令终止宏定义的作用域
6)在宏定义时,可以引用已定义的宏名
带参数的宏定义
定义形式:
#define宏名(参数表) 字符串
这和函数有些类似,但他们是不同的:
1)函数调用时,先求实参表达式值,再代入形参,而宏只是简单替换,并不求值
2)函数调用是在程序运行时分配内存的,而宏展开时并不分配内存,也没有返回值的概念
3)对函数中的实参和形参都要定义类型,而且要求一致,宏名无类型,其参数也没有类型。
4)函数只有一个返回值,而宏可以得到几个结果
5)宏替换不占运行时间,只占编译时间,而函数调用占运行时间
2.文件包含处理
#include"文件1"就是将文件1的全部内容复制插入到#include位置,作为一个源文件进行编译。
在#include命令中,文件名可以用""也可以用<>,假如现在file1.c中包含file2.h文件,""表示系统先在file1.c所在目录中找file2.h,如果找不到,再按系统指定的标准方式检索目录,<>表示系统直接按指定的标准方式检索目录。
所以用""保险一点。
3.条件编译
条件编译指不对整个程序都编译,而是编译满足条件的那部分。
条件编译有以下几种形式:
1)#ifdef标识符
程序段1
#else
程序段2
#endif
它的作用:
当标识符在前面已经被定义过(一般用#define),则对程序段1编译,否则对程序段2编译。
2)#ifndef标识符
程序段1
#else
程序段2
#endif
它的作用和#ifdef相反,当标识符没被定义过,对程序段1编译,否则对程序段2编译。
3)#if表达式
程序段1
#else
程序段2
#endif
它的作用:
当表达式值为真(非0)时,对程序段1编译,否则对程序段2编译。
第九章指针
指针说白了就是地址。
指针变量就是用来存放指针(地址)的变量。
1.变量的指针和指向变量的指针变量
读起来很拗口,说白了就是变量的地址和用来存放变量地址的地址变量。
因为一个变量在编译的时候系统要为它分配一个地址,假如再用一个变量来存放这个地址,那么这个变量就叫做指向变量的指针变量,也就是用来存放变量地址的这么一个变量。
所谓"指向"就是指存放××的地址,如指向变量的指针变量,"指向"就是指用来存放变量的地址,再如指向数组的指针变量,"指向"就是指存放数组的地址。
只要理解了这个,指针也就不难了。
另外,还有指向字符串的指针变量,指向函数的指针变量,指向指针的指针变量等。
1)指针变量的定义
形式:
类型标识符 *标识符 如:
int*pointer;
要注意两点:
*表示pointer是个指针变量,在用这个变量的时候不能写成*pointer,*pointer是pointer指向的变量。
一个指针变量只能指向同一个类型的变量。
如上面
pointer只能指向int型变量。
2)指针变量的引用
两个有关的运算符:
&取地址运算符&a就代表变量a的地址
*指针运算符 *a 就代表变量a的值
2.数组的指针和指向数组的指针变量
数组的指针指数组的起始地址,数组元素的指针指数组元素的地址。
1)指向数组元素的指针变量的定义与赋值
定义和指向变量的指针变量定义相同,c规定数组名代表数组的首地址,即第一个数组元素地址。
2)通过指针引用数组元素
我们通常引用数组元素的形式是a[i],如果用指针可以这样引用,*(a+i),或定义一个指针变量p,将数组a的首地址赋给p,p=a;然后用*(p+i)引用。
注意:
指针变量p指向数组a首地址,则p++指向数组a的下一元素地址,即a[1]的地址。
3)数组名作函数参数
形参数组和实参数组之间并不是值传递,而是共用同一段地址,所以在函数调用过程中如果形参的值发生变化,则实参的值也跟着变化。
4)指向多维数组的指针和指针变量
以二维数组为居多。
假设定义了一个二维数组a[3][4],那么
a代表整个二维数组的首地址,也代表第0行的首地址,同时也是第0行第0列的元素的首地址。
a+0和a[0]代表第0行首地址,a+1和a[1]代表第一行的首地址。
假设a是一个数组的首地址,那么如果a是一维的,a+I代表第I个元素的地址,如果a是二维的,则a+I代表第I行的首地址。
那么第一行第二列的元素地址如何表示呢?
a[1]+2或&a[1][2]或*(a+1)+2。
我们只要记住:
在二维数组中a代表整个数组的首地址,a[I]代表第I行的首地址,a[I]与*(a+I)等价就行了。
只要运用熟练了就没什么复杂的了。
5)指向由m个整数组成的一维数组的指针变量
如:
int(*p)[4],p是一个指向包含4个元素的一维数组,如果p先指向a[0],则p+1指向a[1],即p的增值是以一维数组的长度为单位的,这里是4,举个例子:
假设a[3][4]=,p先指向a[0]也就是数组a的首地址,那么p+1就是a[1]的首地址即元素9的地址,因为在定义p时int(*p)[4],定义一维数组长度为4,所以p+1就等于加了一个一维数组的长度4。
3.字符串的指针和指向字符串的指针变量
1)字符串的表示形式
c中字符串有两种表示形式:
一种是数组,一种是字符指针
charstring[]="Ilovec!
";
char*str="Ilovec!
";
其实指针形式也是在内存中开辟了一个数组,只不过数组的首地址存放在字符指针变量str中,千万不要认为str是一个字符串变量。
2)字符串指针作函数参数
实际上字符串指针就是数组的首地址。
3)字符指针变量与字符数组的区别
①字符数组由若干元素组成,每个元素存放一个字符,而字符指针变量只存放字符串的首地址,不是整个字符串
②对数组初始化要用static,对指针变量不用。
③对字符数组赋值,只能对各个元素赋值,不能象下面这样:
charstr[14];
str="Ilovec!
";
对指针变量可以,
char*str;
str="Ilovec!
";
注意:
此时赋给str的不是字符,而是字符串首地址。
④数组在定义和编译时分配内存单元,而指针变量定义后最好将其初始化,否则指针变量的值会指向一个不确定
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言程序设计 第三 笔记 谭浩强