cprimer学习笔记_第1页
cprimer学习笔记_第2页
cprimer学习笔记_第3页
cprimer学习笔记_第4页
cprimer学习笔记_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

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

文档简介

1、C Primer 始于2014-11-12文字颜色说明:1) 正文中的黑色粗字体表示首次看时,觉得比较重要的文字2) 正文中的红色表示,复习笔记后添加的知识点ANSI(American National Standards Institute) 美国国家标准协会第13章 文件输入输出13.1 和文件进行通信13.1.1 文件是什么l C将文件看成是连续的字节序列,其中每一个字节都可以单独的读取;13.1.2 文本视图和二进制视图l 二进制视图中,每一个字节都可以为程序所访问;l 文本视图中,不同的操作环境(操作系统),程序所看到的内容和文件有可能不同(例如行尾的标志)13.1.4 标准文件C语

2、言提供3种标准文件。标准输入、标准输出、标准错误输出; 标准输入:getchar()、gets()、scanf() 标准输出:putchar()、puts()、printf()13.2 标准I/O13.2.1 检查命令行参数l return 0 与exit(0)的区别: 最初调用的main函数中二者是一样的,main在一个递归程序中时,exit()会终止程序,而return只返回递归的前一级。 在main函数以外的函数中调用exit也会终止程序13.2.2 fopen()函数fopen(参数1,参数2) 参数1:是一个地址(指针或数组),数组中包含要打开的文件名 参数2:是一个字符串,指定打开

3、文件的模式。有以下7大类模式1) “r” 打开一个文本文件,可以读取文件2) “w” 打开一个文本文件,可以写入文件,先将文件长度截为0。若该文件不存在,先创建3) “a” 打开一个文本文件,向已有文件的尾部追加内容。若不存在,先创建4) “r+” 打开一个文本文件,可以进行更新,也可以读取和写入5) “w+” 打开一个文本文件,可以进行更新(读取和写入)。先将文件长度截为0,没有则先创建6) “a+” 打开一个文本文件,可以进行更新(读取和写入),读取整个文件,写入时只能向尾部追加内容 返回:fopen函数返回一个文件指针fp,这个指针指向FILE(stdio.h中定义的一种派生类型),fp

4、指向关于文件的信息的数据包。如果不能打开文件则返回一个空指针NULL。13.2.3 getc()函数和putc()函数l getc() ch = getc(fp) 表示从fp指定的文件中获得一个字符;l putc(参数1,参数2)putc(ch,fpout) 表示将字符ch写入到FILE指针fpout指定的文件中13.2.4 2文件结尾l 从文件中读取数据的程序需要在到大文件的结尾时停止。到达文件结尾时,getc()函数会返回一个特殊值EOF13.2.5 fclose()函数l Fclose(fp)关闭由指针fp指定的文件,同时根据需要刷新缓冲区。13.2.6 标准文件指针l 包含3个标准文件

5、指针:stdin(标准输入)、stdout(标准输出)、stderr(标准错误)13.3 一个简单的文件压缩程序13.4 文件I/O每个I/O函数都存在一个相似的文件I/O函数。文件I/O函数需要使用一个FILE指针来为这些函数指定要操作的文件。13.4.1 fprintf()和fscanf()函数l fprintf()和fscanf() fprintf/fscanf(参数1,参数2,参数3) 参数1为FILE指针;例如fprintf(fp,“%s”,words)其中fp是FILE指针,words是数组名称;l rewind(参数1) 使程序回到文件开始处,参数1必须是一个文件指针;13.4.

6、2 fgets()和fputs()函数l fgets(参数1,参数2,参数3) fgets(buf,max,fp) 参数1:一个地址,用于存储输入值的地址 参数2:一个整数,输入字符串的最大长度 参数3:一个文件指针,这个指针指向要读取的文件 返回值:返回传递给它的地址值,当遇到EOF时,返回NULL fgets()函数读取到它遇到的第1个换行字符的后面,或者读取比字符串的最大长度少一个的字符,或者读取到文件结尾。然后fgets()向末尾添加一个空字符以构成一个字符串。如果fgets在达到字符最大数目之前读完一整行,它将在字符串的空字符前添加一个换行符以表示一行结束。l Fputs(参数1,参

7、数2) 把字符串地址指针所指的字符串写入指定的文件。(与fgets相比,没有写入的长度,因为字符串包含结束符) 参数1:一个地址,是要写入到文件的字符串的地址 参数2:一个文件指针,指向要写入字符串的文件l fgets保留了换行符,fputs不会添加换行符;13.5 随机存取13.5.1 fseek()和ftell() 文件的定位函数l fseek(参数1,参数2,参数3) 参数1:一个文件指针,指向被搜索的文件 参数2:一个long类型的值。表示从起始点开始的偏移量(偏移的字节数),正表示前移,负表示后移,0表示保持不动 参数3:模式,决定偏移量的起始点,一般分为SEEK_SET、SEEK_

8、CUR、SEEK_END 返回值:正常则返回0,不正常则返回-1l ftell(参数1) ftell函数为long型函数,返回文件的当前位置(1个long型数据)。通过返回距离文件起始处的字节数目来确定文件的位置。13.5.4 fgetpos()和fsetpos()处理较大文件的定位函数。13.6 标准I/O内幕l 执行一次fopen函数: 打开一个文件 建立一个(读写模式下两个)缓冲区 创建一个数据结构(包含文件和缓冲区相关数据),包括以下内容 错误指示器 文件结尾指示器 指向缓冲区起始处的指针 文件标示符 计数器:记录实际复制到缓冲区中的字节数 返回一个指向该结构的指针13.7 其他标准I

9、/O函数13.7.4 二进制I/O:fread()和fwrite()数据用二进制形式存入文件,没有数字形式到字符形式的转换。存入的数据更精确。13.8 知识总结比较常用的共12 个1) fopen(参数1,参数2) 文件地址,模式2) fclose(参数1) 文件指针3) getc(参数1) 文件指针4) putc(参数1,参数2) 写入文件的字符,文件指针5) fgets(参数1,参数2,参数3) 存入字符串的地址,字符长度,文件指针6) fputs(参数1) 文件指针7) fprintf(参数1,参数2,参数3) 文件指针,输出格式,字符串地址8) fscanf(参数1,参数2,参数3)

10、文件指针,输入格式,字符串地址9) fseek(参数1,参数2,参数3) 文件指针,偏移量,起始点模式10) ftell(参数1) 文件指针11) fread(参数1,参数2,参数3)12) fwrite(参数1,参数2,参数3)第14章 结构和其他数据格式14.1 实例问题:创建图书目录P37914.2 建立结构声明Struct bookchar title41;char author31;float value;struct book library; 把library定义为一个book结构设计的结构变量;l 其中struct是关键字,表示接下来是一个结构;l Book:是一个可选的标记l

11、 花括号内是结构成员列表;14.3 定义结构变量l 结构有两个意思:一是结构设计,一是结构变量 结构设计:告诉编译器如何表示数据,但并没让计算机为数据分配空间 结构变量:编译器使用book模板为该变量分配空间;l 声明结构和定义结构变量的过程可以合并,如下:Structchar title41;char author31;float value;library;但是如果要多次使用一个结构模板,就必须使用标记;14.3.1 初始化结构l 使用一个用花括号括起来、逗号分隔的初始化项目列表进行初始化。如下Struct book library“C Primer”,“Stephen Prata”,60

12、.00;14.3.2 访问结构成员l 访问结构的成员:用结构成员运算符点(.)例gets(library.title)14.3.3 结构的指定初始化项目l 指定初始化:用点运算符和成员名来表示具体的元素;例:struct book gift = .value = 25.99, .author = “James Broadfool”, .title = “Rue for the Toad”;1) 可以按任何顺序指定初始化2) 只初始化某个成员3) 对特定的成员,最后一次赋值是它实际的值14.4 结构数组14.4.1 声明结构数组Struct book library10;Library本身不是结

13、构名,它是元素类型为struct book结构的数组名。14.4.2 表示结构数组的成员library1.valuelibrary2.title5 第2个结构的title成员的第6个字符14.5 嵌套结构结构的某一个或多个成员也是结构。访问嵌套结构的成员的方法:应用两次点运算符。#include #define LEN 20const char *msg5 = /定义字符常量数组 Thank you for the wonderful evening,You certainly prove that a ,is a specail kind of guy.We must get togethe

14、r,over a delicious,and have a few laughs;struct nameschar firstLEN;char lastLEN;struct guystruct names handle;char favfoodLEN;char jobLEN;float income;int main(void)struct guy fellow = /初始化结构Even, Villard ,grilled salmon,personality coach,58112.00;printf(Dear %s,nn,fellow.handle.first);printf(%s%sn,

15、msg0,fellow.handle.first);/访问嵌套结构的成员printf(%s%sn,msg1,fellow.job);printf(%sn,msg2);printf(%s %s %sn,msg3,fellow.favfood,msg4);printf(n%40s%sn,See you soon,);printf(%40s%sn,Shalala);return 0;14.6 指向结构的指针14.6.1 声明和初始化结构指针l 声明:struct guy *him; 意味着指针him现在可以指向任何现有的guy类型的结构。l 初始化:him = & fellow0;14.6.2 使用

16、指针访问成员l 初始化后的him,有两种方式访问指针成员 him - income; (*him).income 二者完全相同14.7 向函数传递结构信息函数与结构的传递包括3种方式:传递结构成员、传递结构地址、传递结构;14.7.1 向函数传递结构成员14.7.2 向函数传递结构地址#include #define FUNLEN 50struct fundschar bankFUNLEN;double bankfund;char saveFUNLEN;double savefund;double sum (const struct funds *);/声明函数,其中参数为指向结构的指针int

17、 main (void)struct funds stan =Garlic-Melon Bank,3024.72,Luckys Savings and Loan,9237.11;printf(Stan has a total of $%.2f.n,sum (&stan);/结构的地址必须用&return 0;double sum (const struct funds *money)return (money-bankfund + money-savefund); /通过指针直接访问原结构stan14.7.3 向函数传递结构#include #define FUNLEN 50struct fu

18、ndschar bankFUNLEN;double bankfund;char saveFUNLEN;double savefund;double sum (struct funds moolah);/声明函数,参数为结构 int main (void)struct funds stan =Garlic-Melon Bank,3024.72,Luckys Savings and Loan,9237.11;printf(Stan has a total of $%.2f.n,sum (stan);/将结构传递给函数 return 0;double sum ( struct funds moola

19、h)return (moolah.bankfund + moolah.savefund); /会创建一个和stan一样的结构14.7.4 结构的一些特性1) 结构的成员、结构的地址、结构可作为函数的参数向函数传递信息2) 赋值:两个结构类型相同,可将一个结构赋值给另外一个结构3) 把一个结构(已经初始化的)初始化另外一个结构4) 结构可以作为函数的返回值l 结构指针作为参数的例子:/要求输入名和姓,然后得到姓名中的字母总数#include #include struct namectchar fname20;char lname20;int letters;void getinfo (stru

20、ct namect *);void makeinfo(struct namect *);void showinfo(const struct namect *);int main(void)struct namect person;getinfo(&person);/传递的是结构的地址makeinfo(&person);showinfo(&person);return 0;void getinfo (struct namect *pst)printf(Please enter your first name.n);gets(pst-fname);/实际操作的还是那一个结构printf(Plea

21、se enter your last name.n);gets (pst - lname);void makeinfo (struct namect *pst)pst-letters = strlen(pst - fname) +strlen(pst - lname);void showinfo (const struct namect *pst)printf(%s %s,your name contains %d letters.n,pst-fname, pst-lname, pst-letters);l 结构作为参数的例子:/要求输入名和姓,然后得到姓名中的字母总数#include #in

22、clude struct namectchar fname20;char lname20;int letters;struct namect getinfo (void);/函数返回类型为structstruct namect makeinfo(struct namect);void showinfo(struct namect);int main(void)struct namect person;person = getinfo();person = makeinfo(person);/传递的参数为结构showinfo(person);return 0;struct namect geti

23、nfo (void)struct namect temp;/创建一个新的结构printf(Please enter your first name.n);gets(temp.fname);printf(Please enter your last name.n);gets (temp. lname);return temp;struct namect makeinfo (struct namect info)/创建一个新的结构info.letters = strlen(info. fname) +strlen(info.lname);return info;void showinfo (str

24、uct namect info)/创建一个新的结构printf(%s %s,your name contains %d letters.n,info.fname,info.lname, info.letters);14.7.5 结构,还是指向结构的指针1) 为提高效率,使用结构指针作为函数参数,当要保护数据、防止意外改变数据时对指针使用const限定词2) 处理小型结构时常用传递结构值的方法;14.8 把结构内容保存到文件中14.9 结构:下一步是什么14.10 联合介绍l 定义:一个能在同一个存储空间里(但不同时)存储不同类型的数据类型。l 联合的定义:联合模板、联合变量、联合标记Union

25、 hold int digit; double bigfl; char letter;union hold fit;/其中hold为联合标记,fit为联合变量,方括弧为联合模板;l 联合的初始化:1) 初始化为同样的另外一个联合2) 初始化联合的第1个元素3) 指定初始化项目14.11 枚举类型l 定义:枚举是一种代表整数常量的符号名称;注:enum常量是int类型的,因此在使用int类型的任何地方都可以使用它。枚举类型的目的是提高程序的可读性。l 默认情况下,枚举列表中的常量被指定为整数值0、1、2等等。l 可以指定常量具有的值。例如:enum levels low = 100,medium

26、 = 500,high = 2000;l 如果只对某一个常量赋值,而没有对后面的常量赋值,那么这些后面的常量会被赋予后续的值。例如:enum feline cat,lynx =10,puma,tiger; 则对应值的一次为 0,10,11,12。14.12 typedef简介l 定义:typedef工具是一种高级数据特性,能为某一类型创建自己定义的名字。l Typrdef与#define的区别:1) typedef给出的符号名称仅限于对类型,而不是对值;2) typedef的解释由编译器,而不是预处理器执行3) typedef比#define更灵活l 使用方法:typedef unsigned

27、 char BYTE;随后就可以用BYTE来定义变量了。即 typedef b A其中b为类型,A为字符名称l 用typedef来命名一个结构类型时,可以省去结构的标记。注意:typedef并不是创建新的类型,只是创建了便于使用的标签。14.13 奇特的声明C语言中,当进行一个声明时,可以添加修饰符来修饰名称或标示符。一共包含3个修饰符:*、()、l 这3个修饰符的使用规则:1) 优先级:()、优先级一样,高于*2) ()、顺序从左向右组合14.14 函数和指针l 指向函数的指针:保存着指向函数代码起始处的地址l 声明一个函数指针时,必须声明它指向的函数类型(包括函数返回类型、函数的参量类型)

28、。viod (*pf)(char *)/pf是一个指向函数的指针,(*pf)为一个函数,(char*)为该函数的参量列表,void作为其返回类型。l 函数名可以用来表示函数的地址。第16章 C预处理器和C库C预处理器:因为在编译程序之前,先由预处理器检查程序16.1 翻译程序的第一步1) 首先将源代码中出现的字符映射到源字符集;2) 第二,将两个物理行转换成一个逻辑行;3) 其次,编译器将文本划分成预处理的语言符号序列、空白字符及注释序列。16.2 明显常量:#define每个#define行由3部分组成:#define PX printf(“x is %d.n”,x); 第1部分 第2部分

29、第3部分第1部分:#define本身第2部分:缩略语,称为宏第3部分:类对象宏(主体)l 宏展开:预处理器在程序中发现了宏的实例后,总会用实体代替该宏,从宏变成最终的替换文本的过程称为宏展开;l 预处理器不进行计算,只是按照指令进行文字替换操作。但是在双引号中的宏却不会进行替换,例#define TWO 2#define OW “ABC”Printf(“TWO:OW”); 则打印的结果是TWO:OW16.2.1 语言符号16.2.2 重定义常量假设将LIMIT定义为20,后来在该文件中又把LIMIT定义为25,这个过程被称为重定义常量。16.3 在#define中使用参数l 类函数宏:通过使用

30、参数,可以创建外形和作用都与函数相似的类函数宏。l 注意事项:1) 使用足够多的圆括号来保证以正确的顺序进行运算和结合;2) 在宏中不要使用减量和加量运算16.3.1 利用宏参数创建字符串:#运算符l 字符串化:#符号可将语言符号转换为字符串。假如x为一个宏参量,则#x可以把参数名转化为相应的字符串。16.3.2 #运算符l #运算符:将两个语言符号组成单个语言符号16.4 宏,还是函数l 宏与函数间的选择实际上是时间与空间的权衡。1) 宏产生内联代码,也就是说在程序中产生语句。如果使用20次宏,则会把20行代码插入语句中。占用的空间更大。2) 函数的调用涉及控制权的转移,花费的时间更长。l

31、使用宏注意事项:1) 宏的名字中不能有空格2) 用圆括号括住每个参数,并括主宏的整体定义3) 用大写字母表示宏函数名4) 使用宏代替函数来加快速度时,应先确定宏是否会引起重大差异。16.5 文件包含:#includel 预处理器发现#include指令后,就会寻找后跟的文件名并把这个文件的内容包含到当前文件中。1) #include 文件名放在尖括号中,告诉预处理器在标准系统目录文件中寻找文件2) #include”names_st.h” 文件名放在双引号中,告诉预处理器在当前目录中寻找文件。16.5.1 头文件:一个实例1. 头文件:#define SLEN 32struct names_s

32、tchar firstSLEN;char lastSLEN;typedef struct names_st names;/typedef定义void get_names(names *);/函数参数为指向结构的指针void show_names(const names *);2. names_st.c#include#includenames_st.hvoid get_names(names *pn)int i;printf(Please enter your first name:);fgets(pn-first,SLEN,stdin);/用fgets函数是避免目标数组溢出/*i=0;whi

33、le(pn-firsti != n & pn - firsti != 0)i+;if(pn - firsti = n)pn - firsti = 0;/输入的字符串中有换行符n(ASII码值为0x0a)时,用空字符0(ASII码值为0x00)代替elsewhile(getchar()!= n)continue;/*如果不加入这段程序,则姓的字符个数不到32时,会把换行符当成一个字符,输出时便会换行。当姓超过32字符时,取前31个字符printf(Please enter your last name:);fgets(pn - last,SLEN,stdin);i=0;while(pn - la

34、sti != n & pn - lasti !=0)i+;if(pn - lasti = n)pn - lasti = 0;elsewhile(getchar()!= n)continue;void show_names(const names *pn)printf(%s %s ,pn - first,pn - last);3. useheader.c/主程序#include#includenames_st.hint main(void)names candidate;get_names(&candidate);printf(Lets welcome );show_names(&candida

35、te);printf(to this program!n);return 0;16.5.2 使用头文件l 头文件内容的最常见的形式包括:1) 明显常量2) 宏函数3) 函数声明4) 结构板定义5) 类型定义6) 可以用头文件来声明多个文件共享的外部变量7) 使用具有文件作用域、内部链接和const限定词的变量或数组。16.6 其他命令有时需要不同的工作环境准备不同的C程序。预处理器提供一些指令来帮助程序员编写这样的代码:改变一些#define宏的值后,这些代码就可以从一个系统移植到别的系统。可分为四大类:#undef、条件编译、#line和#error、#progma16.6.1 #undef

36、指令l 取消前面的#define定义l 如果想使用一个特定的名字,但又不确定前面是否已经使用了该名字,为安全起见,就可以取消该名字的定义。16.6.2 已定义:C预处理器的观点l 已定义:如果C预处理器遇到一个标示符,要么是已定义,要么是未定义。其中已定义是指C预处理定义的,如果标示符不是一个宏,则预处理器把标示符 当做未定义。l 已定义宏:分为类对象宏(包括空宏)、类函数宏。l #define宏的作用域:从文件的定义点开始,直到用#undef取消宏为止,或直到文件尾为止。16.6.3 条件编译l 条件编译指令可以告诉编译器:根据编译时的条件,接受或忽略信息(代码)块。包括#ifdef、#el

37、se、#endif或#ifndef 或#if、#elif1) #ifdef、#else、#endif#ifdef #else格式非常类似于C中的if else。主要差异为预处理器不能识别代码块的花括号,所以需要#endif来结束指令块。2) #ifndef #endif指令 #ifndef用来定义此前未定义的常量。 #ifndef #endif指令通常用于防止多次包含同一文件。3) #if #elif指令 #if后跟常量整数表达式(更像if),在该表达式中可以使用C的关系运算符合逻辑运算符。 #ifdef 与#if的关系#ifdef VAX #if defined(VAX) 其中defined是预处理器运算符。如果defined的参数已用#define定义过,则defined返回1,否则返回016.6.4 预定义

温馨提示

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

最新文档

评论

0/150

提交评论