C程序设计读书笔记_第1页
C程序设计读书笔记_第2页
C程序设计读书笔记_第3页
C程序设计读书笔记_第4页
C程序设计读书笔记_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、I. 都不同的撰可以喜打每读妒奖湛设计读书C程序设计读书笔记 关键字:c语言原作者姓名:loose_went写在前面:第一章概述C程序设计可以说是一本再基础不过的编程书了,但每读一遍的感觉却都是不同的, 可以说,每读一遍,都会有很多新的收获。真所谓老书再读,回味无穷啊!此笔记是C程序设计谭浩强编著,清华大学岀版社岀版。除了将书中的重点知识点记下来外,也加入了我对 知识点的理解,我想这一点是读书笔记的重要性所在。第一章概述第二章数据类型、运算符与表达式第三章 最简单的C程序设计第四章逻辑运算和判断选取控制第五章循环控制第六章数组第七章函数第八章预编译处理第九章指针第十章结构体与共用体第十一章位运

2、算第十二章文件1. C语言的特点 语言简洁、紧凑,使用方便、灵活。共有3 2个关键字,9种控制语句。 运算符丰富,公有3 4种运算符。 数据结构丰富,数据类型有:整型、实型、字符型、数组、指针、结构体、共用体等。 具有结构化的控制语句(如ifelse while、dowhile、switch、for) 语法限制不太严格,程序设计自由度大。 允许直接访问物理地址,能进行位(bit)操作,可以直接对硬件操作。 生成目标代码质量高,程序执行效率高。 可移植性好。2. C语言的用途C虽不擅长科学计算和管理领域,但对操作系统和系统实用程序以及对硬件进行操作方面,C有明显的优势。现在很多大型应用软件也用C

3、编写。瓦 Top of Page第二章数据类型、运算符与表达式1 C 的数据类型C的数据类型包括:整型、字符型、实型或浮点型(单精度和双精度)、枚举类型、数组类型、 结构体类型、共用体类型、指针类型和空类型。2 常量与变量 常量其值不可改变,符号常量名通常用大写。变量其值可以改变,变量名只能由字母、数字和 下划线组成,且第一个字符必须为字母或下划线。否则为不合法的变量名。变量在编译时为其 分配相应存储单元。3 整型数据整型常量的表示方法:十进制不用说了,八进制以0开头,如 0123,十六进制以 0x 开头,如0x1e。整型变量分为:基本型( int )、短整型( short int )、长整型

4、( long int )和无符号型。不 同机器上各类数据所占内存字节数不同,一般int型为2个字节,long型为4个字节。4 实型数据 实型常量表示形式: 十进制形式由数字和小数点组成 (必须有小数点) ,如: 0.12 、 .123 、 123. 、 0.0等。指数形式如 123e3代表123X 10的三次方。实型变量分为单精度( float )和双精度( double )两类。在一般系统中 float 型占 4字节, 7 位有效数字, double 型占 8字节, 1516 位有效数字。5 字符型数据 字符变量用单引号括起来,如 a,b 等。还有一些是特殊的字符常量,如 n,t 等。分别

5、代表换行和横向跳格。字符变量以 char 来定义,一个变量只能存放一个字符常量。字符串常量是由双引号括起来的字符序列。这里一定要注意a和a的不同,前者为字符常量,后者为字符串常量, c 规定:每个字符串的结尾加一个结束标志 0 ,实际上 a 包含两个字 符: a 和0。6 数值型数据间的混合运算整型、字符型、实型数据间可以混合运算,运算时不同类型数据要转换成同一类型再运算,转换规则: char,short - int - unsigned - long - double =v=匸 )逻辑运算符(! & II )位运算符( | A &)赋值运算符(=)条件运算符(?:)逗号运算符(,)指针运算符

6、(*&)求字节数(sizeof )强制类型转换(类型)分量运算符(.- )下标运算符()其它运算符(如函数调用运算符()自增自减运算符(+ -)注意:+i和i+的不同之处,+i使用i之前先使i加加1, i+使用i之后,使i加H1o逗号表达式的求解过程:先求解表达式1, 再求解表达式2, 整个表达式的值是表达式2的值。云 Top of Page第三章 最简单的C程序设计1. c的9种控制语句:if()elsefor()while()dowhile()con ti nuebreakswitchgotoreturn程序的三种基本结构:顺序结构,选择结构,循环结构2 数据输出c语言不提供输入输岀语句,

7、输入输岀操作是由c的库函数完成。但要包含头文件stdio.hputchar()向终端输岀一个字符printf() 的格式字符: d格式符用来输岀十进制整数%d按整型数据的实际长度输出%md使输岀长度为 m如果数据长度小于m,则左补空格,如果大于m,则输岀实际长度%ld输出长整型数据 o格式符以八进制形式输岀整数 x格式符以十六进制形式输岀整数 u格式符用来输岀unsigned型数据,以十进制形式输岀 c格式符用来输岀一个字符 s格式符输岀一个字符串%s输岀实际长度字符串%ms输岀的串占m列,如果串长度小于 %-ms输岀的串占m列,如果串长度小于 %m.ns输岀占m列,但只取字符串中左端 %-m

8、.ns m、n含义同上,靠左对齐,如果 f格式符以小数形式输岀实数m左补空格,如果大于m实际输岀m右补空格,n个字符并靠右对齐nm,则m自动取n值%f整数部分全部输岀,小数部分输岀6位%m.nf输岀数据共占 m列,其中有n位小数。如果数值长度小于m,左补空格%-m.nf同上,右补空格e格式符以指数形式输岀实数%e系统指定6位小数,5位指数(e+002 ) g格式符 输岀实数,根据数值大小,自动选 f格式或e格式3 数据输入getchar()从终端输入一个字符scanf( 格式控制,地址列表)标准C scanf中不使用u对于unsigned型数据,以%d或0或x 输入。后的*,用来跳过它相应的数

9、据。输入数据时不能规定精度如scanf( %7.2f, &a );是不合法的。k Top of Page第四章 逻辑运算和判断选取控制1. 关系运算符:c提供6种关系运算符( =!=)前四种优先级高于后两种2. If 语句C提供了三种形式的if语句If(表达式)语句If(表达式)语句1 else 语句2If(表达式1)语句1Else if( 表达式2)语句2else 语句n3. 条件运算符(ab)?a:b条件为真,表达式取值a,否则取值b4. Switch 语句Switch(表达式)case 常量表达式1:语句1; break;case常量表达式2:语句 2; break;case 常量表达式

10、 n:语句n ; break;default :语句n+1第五章循环控制1. 几种循环语句goto语句(现已很少使用)while语句先判断表达式后执行语句do-while语句先执行语句后判断表达式for语句2. Break 语句和 continue 语句Break语句用于跳岀循环,continue用于结束本次循环。第六章数组1.一维数组K Top of PageK Top of Pagec规定只有静态存储( 不指定数组长度。static )和外部存储(extern )数组才能初始化。给数组初始化时可以2.二维数组3.字符数组部分字符串处理函数puts(字符数组)将一个字符串输岀到终端。gets

11、(字符数组)从终端输入一个字符串到字符数组,并且得到一个函数值,为该字符数组的 首地址strcat(字符数组1 ,字符数组2)连接两个字符数组中的字符串,数组1必须足够大。Strcpy(字符数组1 ,字符串2)将字符串2拷贝到字符数组1中。Strcmp(字符串1,字符串2)比较字符串,相等返回0,字符串1 字符串2,返回正数,小于返回负数。Strlen(字符数组)求字符串长度。Strlwr( 字符串) 将字符串中的大写字母转换成小写Strupr( 字符串)将字符串中的小写字母转换成大写 以上是一些比较常用的字符串处理函数。k Top of Page第七章函数1. 关于形参和实参的说明 在函数被

12、调用之前,形参不占内存 实参可以是常量、变量或表达式 必须指定形参的类型 实参与形参类型应一致 实参对形参的数据传递是 值传递,即单向传递2. 函数返回值如果想让函数返回一个值,在函数中就要用retur n 语句来获得,在定义函数时也要对函数值指定类型,如果不指定,默认返回整型。3. 函数调用1)注意在函数调用时实参和形参的个数、类型应一一对应。对实参表求值的顺序是不确定的, 有的系统按自左至右,有的系统则按自右至左的顺序。这一点要注意。2)函数调用的方式:函数语句,函数表达式,函数参数3)如果主调函数和被调函数在同一文件中,并且主调函数在前,那么一般要在主调函数中对被调函数进行说明。 除非:

13、(1)被调函数的返回值类型为整型或字符型 (2)被调函数岀现在主调函 数之前。4)对函数的说明和定义是不同的,定义是指对函数功能的确立,包括指定函数名,函数值类型,形参及其类型、函数体等。说明则只是对已定义的函数返回值类型进行说明,只包括函数名、函数类型以及一个空的括弧,不包括形参和函数体。5)c语言允许函数的递归调用(在调用一个函数的过程中又岀现直接或间接的调用该函数本 身)。4 数组作为函数参数1) 数组元素作为函数参数 和一般变量相同2) 数组名作参数应该在主调和被调函数分别定义数组,形参数组的大小可以不定义。注意:数 组名作参数,不是单向传递。3) 多维数组作参数, 在被调函数中对形参

14、数组定义时可以省略第一维的大小说明, 但不能省略 第二维或更高维的说明。5 局部变量和全局变量从变量作用域角度分,变量可分为局部变量和全局变量。1) 内部变量(局部变量)在一个函数内定义,只在函数范围内有效的变量。2) 外部变量(全局变量)在函数外定义,可以为本文件其它函数所共用,有效范围从定义变量的位置开始到本文件结束。建议尽量少使用全局变量,因为它在程序全部执行过程中都占用 资源,而且使函数的通用性降低了。如果在定义外部变量之前的函数要想使用该 外部变量,则应在该函数中用 extern 作外部变量说明。6 动态存储变量与静态存储变量C语言中,变量的存储方法分为两大类: 静态的 (stati

15、c) ,寄存器的 (register)1) 局部变量的存储方式 函数中的局部变量如不作专门说明,都之从变量值存在的时间(生存期)角度来分,可分为静态存储变量和动态存储变量。静态存储指 在程序运行期间给变量分配固定的存储空间, 动态存储指程序运行期间根据需要动态的给变量 分配存储空间。静态存储类和动态存储类,具体包括:自动的(auto ),,外部的 (extern) 。auto 的,即动态存储的, auto 可以省略。局部变量 也可以定义为 static 的,这时它在函数内值是不变的。静态局部变量如不赋初值,编译时系统自动赋值为0,动态局部变量如不赋初值,则它的值是个不确定的值。C规定,只有在定

16、义全局变量和局部静态变量时才能对数组赋初值。为提高执行效率,c 允许将局部变量值放在寄存器中,这种变量叫 register 变量,要用 register 说明。但只有局部动态变量和形式参数可 以作为 register 变量,其它不行。2) 全局变量的存储方式全局变量在函数外部定义,编译时分配在静态存储区,可以在程序中各个函数所引用。多个文 件的情况如何引用全局变量呢?假如在一个文件定义全局变量,在别的文件引用, 就要在此文件中用 extern 对全局变量说明, 但如果全局变量定义时用 static 的话, 此全局变量就只能在 本文件中引用了,而不能被其它文件引用。3) 存储类别小结从作用域角度

17、分,有局部变量和全局变量 局部变量:自动变量,即动态局部变量(离开函数,值就消失)静态局部变量(离开函数,值仍保留)寄存器变量(离开函数,值就消失)(形参可定义为自动变量和寄存器变量) 全局变量:静态全局变量(只限本文件引用) 全局变量(允许其它文件引用) 从存在的时间分,有静态存储和动态存储 动态存储:自动变量(本函数内有效)寄存器变量(本函数内有效)形参静态存储:静态局部变量(函数内有效) 静态全局变量(本文件内有效) 全局变量(其它文件可引用)从变量值存放的位置分 静态存储区:静态局部变量静态全局变量全局变量动态存储区:自动变量和形参寄存器内:寄存器变量7.内部函数和外部函数内部函数:只

18、能被本文件中的其它函数调用,定义时前加static ,内部函数又称静态函数。外部函数:可以被其它文件调用,定义时前加extern,如果省略,则隐含为外部函数,在需要调用此函数的文件中,一般要用extern说明。Top of Page第八章预编译处理c提供的预处理功能主要有以下三c编译系统在对程序进行通常的编译之前,先进行预处理。 种:1)宏定义 2 )文件包含 3)条件编译 1.宏定义#define 标识符字符串不带参数的宏定义用一个指定的标识符来代表一个字符串,形式:几点说明:1)宏名一般用大写2)宏定义不作语法检查,只有在编译被宏展开后的源程序时才会报错3)宏定义不是c语句,不在行末加分号

19、4)宏名有效范围为定义到本源文件结束5)可以用#undef命令终止宏定义的作用域6)在宏定义时,可以引用已定义的宏名 带参数的宏定义 定义形式:#defi ne 宏名(参数表) 字符串这和函数有些类似,但他们是不同的:1)函数调用时,先求实参表达式值,再代入形参,而宏只是简单替换,并不求值2)函数调用是在程序运行时分配内存的,而宏展开时并不分配内存,也没有返回值的概念3)对函数中的实参和形参都要定义类型,而且要求一致,宏名无类型,其参数也没有类型。4)函数只有一个返回值,而宏可以得到几个结果5)宏替换不占运行时间,只占编译时间,而函数调用占运行时间2. 文件包含处理#inelude 文件1就是

20、将文件1的全部内容复制插入到 #inelude 位置,作为一个源文件进行 编译。在#山elude 命令中,文件名可以用“ “也可以用 ,假如现在filel.c 中包含file2.h 文件,表示系统先在filel.c 所在目录中找file2.h ,如果找不到,再按系统指定的标准方式检 索目录,表示系统直接按指定的标准方式检索目录。所以用“保险一点。3. 条件编译条件编译指不对整个程序都编译,而是编译满足条件的那部分。条件编译有以下几种形式:1)#ifdef 标识符程序段1#else程序段2#en dif它的作用:当标识符在前面已经被定义过(一般用#define ),则对程序段1编译,否则对程序段

21、2编译。2)#ifndef 标识符程序段1#else程序段2#en dif它的作用和#ifdef相反,当标识符没被定义过,对程序段1编译,否则对程序段2编译。3)#if 表达式程序段1#else程序段2#en dif它的作用:当表达式值为真(非0)时,对程序段1编译,否则对程序段2编译。k Top of Page第九章指针指针说白了就是地址。指针变量就是用来存放指针(地址)的变量1 变量的指针和指向变量的指针变量 读起来很拗口, 说白了就是变量的地址和用来存放变量地址的地址变量。 因为一个变量在编译 的时候系统要为它分配一个地址, 假如再用一个变量来存放这个地址, 那么这个变量就叫做指 向变量

22、的指针变量, 也就是用来存放变量地址的这么一个变量。 所谓“指向“就是指存放XX的 地址, 如指向变量的指针变量, 指向 就是指用来存放变量的地址, 再如指向数组的指针变量, 指向 就是指存放数组的地址。只要理解了这个,指针也就不难了。另外,还有指向字符串的 指针变量,指向函数的指针变量,指向指针的指针变量等。1) 指针变量的定义形式:类型标识符* 标识符 如: int *pointer;要注意两点: *表示 pointer 是个指针变量, 在用这个变量的时候不能写成 *pointer , *pointer是 pointer 指向的变量。一个指针变量只能指向同一个类型的变量。如上面 point

23、er 只能指向 int 型变量。2) 指针变量的引用两个有关的运算符:& 取地址运算符 &a 就代表变量 a 的地址* 指针运算符 *a 就代表变量 a 的值2 数组的指针和指向数组的指针变量数组的指针指数组的起始地址,数组元素的指针指数组元素的地址。1) 指向数组元素的指针变量的定义与赋值定义和指向变量的指针变量定义相同, c 规定数组名代表数组的首地址,即第一个数组元素地 址。2) 通过指针引用数组元素我们通常引用数组元素的形式是 ai ,如果用指针可以这样引用, *(a+i) ,或定义一个指针 变量p,将数组a的首地址赋给 p, p=a;然后用*(p+i)弓I用。注意:指针变量P指向数组

24、a首地址,则p+指向数组a的下一元素地址,即a1的地址。3) 数组名作函数参数形参数组和实参数组之间并不是值传递, 而是共用同一段地址, 所以在函数调用过程中如果形 参的值发生变化,则实参的值也跟着变化。4) 指向多维数组的指针和指针变量以二维数组为居多。假设定义了一个二维数组 a34 ,那么a代表整个二维数组的首地址,也代表第0行的首地址,同时也是第0行第0列的元素的首地址。 a +0 和 a0 代表第 0 行首地址, a+1 和 a1 代表第一行的首地址。假设a是一个数组的首地址,那么如果a是一维的,a+I代表第I个元素的地址,如果a是二维的,则 a+I 代表第 I 行的首地址。那么第一行

25、第二列的元素地址如何表示呢?a1+2或&a12或*(a+1)+2。我们只要记住:在二维数组中 a 代表整个数组的首地址, aI 代表第 I 行的首地址, aI 与 *(a+I) 等价就行了。只要运用熟练了就没什么复杂的了。5) 指向由m个整数组成的一维数组的指针变量如: int (*p)4, p 是一个指向包含 4 个元素的一维数组,如果 p 先指向 a0 ,则 p+1 指向a1 ,即 p 的增值是以一维数组的长度为单位的,这里是 4,举个例子:假设 a34=1,3,5,7,9,11,13,15,17,19,21,23, p 先指向 a0也就是数组 a 的首地址,那么 p+1 就是 a1 的首

26、地址即元素 9 的地址,因为在定义 p 时 int (*p)4 ,定义一维数组长 度为 4,所以 p+1 就等于加了一个一维数组的长度4。3 字符串的指针和指向字符串的指针变量1) 字符串的表示形式c 中字符串有两种表示形式:一种是数组,一种是字符指针char string=I love c!;char *str=I love c!; 其实指针形式也是在内存中开辟了一个数组,只不过数组的首地址存放在字符指针变量str中,千万不要认为 str 是一个字符串变量。2) 字符串指针作函数参数实际上字符串指针就是数组的首地址。3) 字符指针变量与字符数组的区别 字符数组由若干元素组成,每个元素存放一个

27、字符,而字符指针变量只存放字符串的首地 址,不是整个字符串 对数组初始化要用 static ,对指针变量不用。 对字符数组赋值,只能对各个元素赋值,不能象下面这样:char str14; str=I love c!;对指针变量可以,char *str;str=I love c!;注意:此时赋给 str 的不是字符,而是字符串首地址。 数组在定义和编译时分配内存单元,而指针变量定义后最好将其初始化,否则指针变量的 值会指向一个不确定的内存段,将会破坏程序。如:char *a;scanf( %s, a ); 这种方法是很危险的,应该这样:char *a, str10;a = str;scanf(

28、%s, a ); 这样字符指针就指向了一个确定的内存段。 指针变量的值是可以改变的,而字符数组名所代表的字符串首地址却是不能改变的。4 函数的指针和指向函数的指针变量一个函数在编译时被分配一个入口地址, 这个入口地址就称为函数的指针。 函数名代表函数的 入口地址,这一点和数组一样。我们可以用一个指针变量来存放这个入口地址,然后通过该指 针变量调用函数。如:假设有一个求两者较大的函数如下:int max( int x, int y );当我们调用这个函数时可以这样:int c;c=max( a, b ); 这是通常调用方法,其实我们可以定义一个函数指针,通过指针来调用,如: int (*p)()

29、; / 注意指向函数指针变量的定义形式 p=max; / 此句就是将函数的入口地址赋给函数指针变量 p c=(*p)( a, b );有些朋友可能对 (*p)() 不大理解,其实它的意思就是定义一个指向函数的指针变量p, p 不是固定指向哪个函数的, 而是专门用来存放函数入口地址的变量。 在程序中把哪个函数的入口地 址赋给它,它就指向哪个函数。但要注意, p 不能象指向变量的指针变量一样进行 p+,p- 等无 意义的操作。既然 p 是一个指针变量, 那么就可以作为函数的参数进行传递。 其实函数的指针变量最常用的 用途之一就是作为函数参数传递到其它函数。这也是 c 语言中应用的比较深入的部分了。

30、5 返回指针值的函数 我们知道,一个函数可以带回一个整型值、字符值、实型值等,函数还可以带回一个指针型的 数据,即地址。这种函数的定义形式如下:类型标识符 * 函数名 (参数表 ) 如: int *a(x,y) 返回一个指向整型的指针 使用这种函数的时候要注意: 在调用时要先定义一个适当的指针来接收函数的返回值。 这个适 当的指针其类型应为函数返回指针所指向的类型。这样的函数比较难于理解, 其实只要把它当做一般的函数来处理就容易了。 当我们觉得指针难 于理解的时候,就把它暂时当做整型来看,就好理解多了。6 指针数组指针数组无疑就是数组元素为指针,定义形式为: 类型标识 *数组名 数组长度 如:

31、int *p4,千万不要写成in t (*p)4,这是指向一维数组的指针变量。指针数组多用于存放若干个字符串的首地址,注意一点,在定义指针数组时初始化,如下: static char *name=Li jing,Wang mi,Xu shang; 不要以为数组中存放的是字符串,它存放的是字符串首地址,这一点一定要注意。7 指向指针的指针说的明白一点, 将一个指针再用一个变量来存放, 那么这个变量就是指向指针的指针。 定义如: char * *p;8 指针数组作 main() 函数的参数函数形式为 main( int argc, char *argv ) main 函数的参数是从命令行得到的,

32、argc 指命令行参数个数,注意命令名也算一个参数,命 令行参数都是字符串, 他们的首地址构成一个指针数组 argv 。 Main 函数的形参用 argc 和 argv 只是一个习惯,也可以定义成别的名字。9 指针小结1) 有关指针的数据类型定义含义Int I;定义一个整型变量 1Int *p;P为指向整型数据的指针变量Int an;定义整型数组a,它有n个元素Int *p n;定义指针数组p,它有n个指向整型的指针元素In t (*p) n;P为指向含有n个元素的一维数组的指针变量Int f();F为返回整型值的函数Int *p();P为返回值为指针的函数,该指针指向整型数据In t (*p

33、)();P为指向函数的指针,该函数返回一个整型值Int *p;定义一个指向指针的指针变量2) ANSI新增了一种void *指针类型,即定义一个指针变量,但不指向任何数据类型,等用到的时候再强制转换类型。如:char *p1;void *p2;pl = (char *)p2;也可以将一个函数定义成void *型,如:void *fun( chi, ch2 )表示函数fun返回一个地址,它指向空类型,如果需要用到此地址,也要对其强制转换。 如(假设p1为char型):p1=(char *)fun( c1,c2 );指针应该说是c语言中比较重要的概念,也是c语言的精华,它有很多优点,但用不好也会带

34、来严重性的错误,这就需要我们多用,多练,慢慢的积累经验。k Top of Page第十章结构体与共用体结构体定义的一般形式:struct结构体名成员列表struct结构体名结构体变量名;定义一个结构体变量可以这样定义:2.结构体变量的引用 在引用结构体变量时应注意以下规则:1) 不能将结构体变量作为一个整体输入输出,只能对变量当中的各个成员输入输出。新标准 允许将一个结构体变量直接赋值给另一个具有相同结构的结构体变量。3 结构体变量的初始化如:struct studentlong int num;char name20;char sex;char addr20;a=89031,Li Lin,M

35、,123 Beijing Road ;4 结构体数组struct student stu4;定义了一个数组 stu,其元素为struct student类型,数组有 4个元素。注意数组各元素在内存 中是连续存放的。在定义结构体数组时,数组元素个数可以不指定。编译时,系统会根据给出初值的结构体常量 的个数来确定数组元素的个数。5 指向结构体变量的指针因为结构体变量在内存中是连续存放各成员的, 因此我们可以将结构体变量在内存中的起始地 址存放到一个变量中,那么这个变量就是指向结构体变量的指针。注意将结构体变量的首地址赋给指针变量的形式:struct student stu_1;struct stu

36、dent *p;p=&stu_1; / 要加取地址符 而指向函数和指向字符串的指针不用 在对引用结构体变量中的成员时,有三种方式:以上面的结构体为例:设 p 为指向此结构体变量的指针,即 p=&a;1) a.num2) (*p).num3) p-num6 指向结构体数组的指针struct student *p;struct student stu4;p=stu;则p为指向结构体数组的指针变量。这里应注意p+ , p指向stuO,p+则指向stu1。P指向的是数组中一个元素的首地址,而不能让 p 指向元素中的某一成员,如 p=&stuI.name 是不对7 用指向结构体的指针作函数参数虽然 AN

37、SI C 允许用整个结构体作为函数参数,但要将全部成员值一个一个传递,开销大。所 以用指针作参数,能提高运行效率。Struct student stu;用整个结构体作为参数调用形式:fun( stu );而且被调函数 fun 中也要定义成结构体变量 ,struct student stu; 用指针作参数调用形式:fun( &stu );被调函数 fun 中定义成指针变量, struct student *p;8 用指针处理链表链表是一种重要的数据结构,原因就在于它可以动态的进行存储分配。链表都有一个头指针, 用来存放整个链表的首地址。链表的定义形式如下:struct nodeint num;s

38、truct node *next;next 用来存放下一节点的地址。如何进行动态的开辟和释放存储单元呢? c 提供了以下有关函数:1) malloc(size) 在内存的动态存储区开辟一个长度为 size 的连续空间。成功返回空间首地址, 失败返回 0;2) calloc(n,size) 在内存的动态存储区开辟 n 个长度为 size 的连续空间。成功返回空间首地址, 失败返回 0;3) free(ptr) 释放由 ptr 指向的内存区。 Ptr 是最近调用一次调用 malloc 和 calloc 时返回的值。 上面函数中, n 和 size 为整型, ptr 为字符指针。9 共用体定义形式:

39、union 共用体名成员列表 变量列表 ; 共用体和结构体类似,只是有一点不同,结构体中个成员的起始地址不同,结构体变量在内存 中的长度为各成员长度之和; 而共用体中个成员的起始地址相同, 共用体变量所占的内存长度 为最长的成员的长度。共用体类型数据的特点:1)同一个内存段可以存放几种不同类型的成员2)共用体变量中起作用的成员是最后一次存放的成员3)不能对共用体变量名赋值,不能在定义时初始化。4)不能把共用体变量作为函数参数5)共用体类型可以岀现在结构体定义中,反之也可,也可以定义共用体数组。另外,结构体名可以作为参数,而共用体名不可以。这两中数据结构在不同场合中各有所用。10.枚举类型定义形

40、式如下:举个例子enum weekdaysu n,mon ,tue,wed,thu,fri,sat;enum weekday workday,week_e nd; /定义枚举变量workday和week_end被定义成枚举类型,他们的值只能为sun到sat之一。也可以直接定义枚举变量,这一点与结构体相同enum weekdaysun,mon,tue,wed,thu,fri,satwordday,week_end;注意:枚举元素是作为常量存在的,他们是有值的,c在编译时使他们的值按顺序为0,1,2如:上面的定义中,sun的值为0,mon的值为1另外:虽然枚举元素有值,但不能将一个整数直接赋给一个

41、枚举变量。应进行强制类型转换,如:workday=(enum weekday)2;它相当于把 tue 赋给了 workday。11.用typedef定义类型typedef的作用就是能够让你定义一个自己喜欢的数据类型名来代替已有的数据类型名。如: typedef int INT;那么我就可以用INT来定义整型变量了。作用和 int 样。Typedef用于结构体定义,如:Typedef structInt day;In t mon th;Int year;DATE;DATE birthday;DATE *p;等等用typedef有利于程序的通用与移植。K Top of Page第十一章位运算1)概

42、述所谓位运算是指进行二进制位的运算。在系统软件中,常要处理二进制位的问题。c提供的位运算符有:& 按位与 | 按位或A按位异或 取反 右移 &对于将一个单元清零、取一个数中的某些指定位以及保留指定位有很大用途。 |常被用来将一个数的某些位置1。A判断两个位值,不同为1,相同为0。常用来使特定位翻转等。常用来配合其它位运算符使用的,常用来设置屏蔽字。 右移时,要注意符号问题。对无符号数,右移时左边高位移入0,对于有符号数,如果原来符号位为0 (正数),则左边移入 0;如果符号位为 1 (负数),则左边移入0还是1要取决于 系统。移入0的称为“逻辑右移“,移入1的称为“算数右移“。2)位段将一个字

43、节分为几段来存放几个信息。所谓位段是以位为单位定义长度的结构体类型中的成 员。如:struct packed-data unsigned a:2; unsigned b:6;unsigned c:4;unsigned d:4;int I;data;其中a,b,c,d分别占2位,6位,4位,4位。I为整型,占4个字节。 对于位段成员的引用如下:data.a = 2;等,但要注意赋值时,不要超岀位段定义的范围。如位段成员a定义为2位,最大值为3,即(11)2,所以data.a=5;就会取5的两个低位进行赋值,就得不到想要的值了。 关于位段的定义和引用,有几点重要说明: 若某一个段要从另一个字开始存

44、放,可以定义:unsigned a:1;unsigned b:2;unsigned :0;unsigned c:3; ( 另一单元 ) 使用长度为 0 的位段,作用就是使下一个位段从下一个存储单元开始存放。 一个位段必须存放在用一个存储单元中,不能跨两个单元。 可以定义无名位段。如:unsigned a:1;unsigned :2; ( 这两位空间不用 )unsigned b:3; 位段的长度不能大于存储单元的长度,也不能定义位段数组k Top of Page第十二章文件1)概述c语言将文件看成一个字符的序列,分为ASCII文件(文本文件)和二进制文件。即一个c文件就是一个字节流或二进制流。A

45、SCII文件每一个字节放一个ASCII码,代表一个字符,输岀与字符一一对应,便于逐个处理字符,但占用空间较多。二进制文件按内存中的存储形式原样输出到磁盘上,节省空间,由于输岀与字符不对应,不能直接输岀字符形式,一般用于保存中间结果。目前c对文件的处理只有缓冲文件系统一种方法,即无论是从程序到磁盘文件还是从磁盘文件到程序,数据都要先经过缓冲区,待缓冲区充满后,才集中发送。2)文件夹类型指针在缓冲文件系统中,关键的概念是文件指针。因为每个被使用的文件都在内存中开辟一个缓冲 区,来存放文件有关信息。这些信息保存在一个结构体变量中,该结构体类型是由系统定义的,取名为FILE,在stdio.h中定义。F

46、ILE *fp;定义了一个文件指针变量fp,以后对文件的操作都是通过fp进行的。3)文件的打开与关闭在对文件读写之前,要先打开文件。打开文件的函数为:fopen(),调用方式为:FILE *fp;fp=fope n( file name,使用文件方式);fopen()失败返回一个空指针NULL,成功则返回一个指向filename的文件指针,赋给fp,这样fp就和打开的文件联系在一起了。或者说,fp指向了 filename。文件使用方式:r,w,a,rb,wb,ab,r+,w+,a+,rb+,wb+,ab+,具体含义要记住。4)文件的关闭为了防止数据丢失,程序结束前,务必将打开的文件关闭,即将文

47、件指针与文件脱钩。用fclose(文件指针)函数关闭文件,执行函数后,先将缓冲区中的数据送到磁盘文件,然后释放文 件指针。成功返回 0,失败返回非0。5)文件的读写文件打开后,就可以对其读写了,常用的文件读写函数有: fputc 和 fgetcfputc 将一个字符写到文件, 形式为 fputc( ch, fp ); 将字符 ch 写入 fp 所指向的文件。 成功返回该 字符,失败返回 EOF ,EOF 在 stdio.h 中定义为符号常量 -1。fgetc 从指定文件读入一个字符, 该文件必须是以读或读写方式打开的。 调用形式为 ch=fgetc(fp); 从fp指向的文件读入一个字符赋给c

48、h,当文件结束时,fgetc返回一个EOF,我们可以用函数feof(fp) 来判断是否已到文件尾,返回 1 表示已到文件尾,否则返回0。这个函数适用于文本文件和二进制文件。 fread和fwrite函数可以读写一组数据。调用形式如下:fread( buffer, size, count, fp );fwrite( buffer, size, count, fp );buffer 为一个指针,对 fread 来讲,是指从文件读出数据的存放地址,对 fwrite 来讲,是要写入 文件的数据的地址。size 要读写的字节数count 要进行读写多少个 size 字节的数据项(书上这么说)其实就是读写

49、的次数fp 文件指针这两个函数返回值成功为 1,失败为非 1,一般用于二进制文件的读写。 注意:有些 c 编译系统不具备这两个函数。 fprintf()和 fscanf()函数格式化输岀和输入函数,与printf()和scanf()作用相似,只有一点不同,fprintf()和fscanf()的读写对象不是终端而是磁盘文件。调用方式: fprintf( 文件指针 ,格式字符串 ,输岀列表 );fscanf(文件指针,格式字符串,输岀列表); fgets()和 fputs()函数作用是读写一个字符串,如:fgets(str,n,fp);意为从 fp 指向的文件读岀 n-1 个字符,存放到 str 中,成功返回 str 的首地址。fputs( China, fp );把字符串 China 写入 fp 指向的文件。成功返回 0,失败为非 0。6) 文件的定位文件中有一个位置指针,指向当前读写的位置,如果要强制改变位置指针的位置,可以用有关 函数: rewind使位置指针重新返回文件的开头 fseek()fs

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论