文件、预处理、位运算

news2024/12/23 1:54:21

10.2 数据文件概述

10.2.1 ASCII文件与二进制文件

ASCII文件就是“将需要保存到文件的信息使用ASCII字符表示,然后按照顺序将每个字符的ASCII码存储到文件中”。ASCII文件的优点是编码方式公开,可以被其它的文本编辑器打开;其缺点是效率比较低,信息冗余度高。

二进制文件将数据在内存中的二进制形式原样存储到文件中。

10.2.2 缓冲文件系统

所谓缓冲区,是指对于每个正在使用的文件,系统在内存中为其开辟的一段存储区,用于存储从文件输入的内容或者需要输出到文件的内容。像这种通过缓冲区处理文件的系统称为缓冲文件系统。使用缓冲文件系统可以大大提高文件操作的速度。

缓冲区有两种类型,输入缓冲区和输出缓冲区,程序、缓冲区和文件的关系如图13.4。


10.2.3 文件结构与文件类型指针

1.文件结构

为了有效地使用文件缓冲区,系统将缓冲区的细节封装到了一个结构体中,称为文件结构。该结构体的成员包含了文件缓冲区的详细信息,并使用typedef关键字将该结构类型重命名为FILE,该结构定义包含在stdio.h头文件中,因此,使用文件的程序都要包含“#include<stdio.h>”。

2.文件类型指针

有了文件缓冲区的结构定义以后,C语言引进指针来指向该文件结构,通过移动指针实现对文件的操作,该指针就是FILE文件类型指针。定义文件结构指针的格式为:

       FILE 文件指针;

10.2.4 标准输入/输出设备文件

在操作系统中,把外部设备也当作一个文件进行管理的。例如,键盘通常作为标准输入设备,显示器及打印机称为标准输出设备。在C语言中,键盘被指定为标准的输入文件,文件指针是stdin,从键盘上输入就意味着从标准输入文件上输入数据,scanf()函数、getchar()函数使用的就是标准输入文件;显示器被指定为标准的输出文件,文件指针是stdout,向屏幕显示信息就是向标准输出文件输出数据,printf()函数、putchar()函数使用的就是标准输出文件。文件指针stdin和stdout不需要用户定义,它们都包含在stdio.h头文件中,由C编译系统自动完成。

10.3 文件的打开与关闭

10.3.1 文件的打开

C语言中,打开文件使用fopen()函数,打开文件的真正含义是请求系统为指定的文件名分配相应的文件缓冲区。打开文件的函数调用格式如下:

fopen("文件名","文件打开方式")

说明:

(1)括号中的“文件名”指出要打开的文件。文件名中一般要包含路径,如果未包含路径,默认与应用程序的当前路径相同;如果包含文件路径,由于“\”为转义字符,所有路径中的“\”都需要使用“\\”表示。

(2)fopen()函数的返回值是一个FILE类型的指针,常称为文件指针。所以,在使用文件之前,先要定义文件类型指针:

FILE *fp;

函数如果执行成功,返回包含文件缓冲区信息的文件结构体的地址,赋给文件指针fp。否则,返回一个NULL(空值)的FILE指针。

(3)为保证文件能正常打开,在调用fopen()函数时一般都要进行判断,例如,例13.1中的打开形式如下:

if((fp=fopen("D:\\file.txt","r"))==NULL)                /* 打开文件 */

{       printf("File open error!\n");

exit(1);

}

(4)一旦文件经fopen()函数正常打开,该文件的操作方式即固定下来,直至文件被关闭都不能改变。例如,例13.1中的文件打开以后,只能读出其中的数据,不能进行写操作。

(5)允许同时打开多个文件,每打开一个文件就需要一个FILE指针,若需要同时打开多个文件,需要定义多个FILE指针。不允许同一个文件在关闭前被再次打开。

(6)C语言中,ASCII文件与二进制文件的打开方式可以通用。

10.3.2 文件的关闭

文件操作结束后,要使用fclose()函数关闭文件。关闭文件操作的真正含义是:将文件缓冲区中还未写入文件的数据写入文件,确保数据的完整性,同时释放文件占用的缓冲区单元。fclose()函数的格式为:

fclose(文件指针)

10.4 文件的操作

10.4.1 字符方式文件读写函数fgetc()和fputc()

1.fputc()函数

C语言中,使用fputc()函数向文件写入一个字符,函数调用形式为:

fputc(ch,fp)

2.fgetc()函数

C语言中,从文件中读取一个字符使用fgetc()函数,函数调用形式为:

ch=fgetc(fp);

10.4.2 字符串方式文件读写函数fgets()和fputs()

1.fputs()函数

C语言中,向文件中写入字符串通常使用fputs()函数,一般调用形式为:

fputs(str,fp)

2.fgets()函数

C语言中,从文件中读出字符串可以使用fgets()函数,一般调用形式为:

fgets(str, n, fp);

10.4.3 格式化文件读写函数fscanf()和fprintf()

1.fprintf()函数

fprintf ()函数的一般调用形式为:

fprintf(fp, 格式控制字符串, 输出项列表)

2.fscanf ()函数

fscanf()的一般调用形式为:

fscanf (fp, 格式控制字符串, 输出项列表)

10.4.4 数据块读写函数fread()和fwrite()

1.fwrite ()函数

fwrite()函数的一般调用形式为:

fwrite(buffer, size, count , fp)

2.fread ()函数

fread()函数的一般调用形式为:

fread(buffer, size, count , fp)

10.5 其他文件操作函数

1.feof()函数

feof ()函数的作用是检测文件是否结束,函数格式如下:

feof(fp)

2.rewind()函数

rewind()函数的作用是定位文件指针,使文件指针指向读写文件的首地址,即打开文件时文件指针所指向的位置。函数调用形式为:

rewind(fp);

3.fseek()函数

fseek(fp, offset, fromwhere);

4.ftell()函数

ftell ()函数的作用是获取当前文件指针读写的位置,函数格式如下:

ftell(fp);

11.1 宏定义

11.1.1 无参宏定义

无参数宏是指在宏名的后面没有参数。只是用一个指定的宏名来代表一个字符串,它的一般形式为:

#define 标识符 字符串

在C语言中,以“#”开头的均为预处理命令,“define”则表示是宏定义命令,“标识符”是定义的宏名,“字符串”可以是常数、表达式、类型名、格式串等。

说明:

(l)宏名一般习惯用大写字母表示,以便与变量名相区别,但也允许用小写字母。

(2)使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量。当需要改变某一个常量时,可以只改变#define命令行,改一处则全改。

(3)宏定义是用宏名代替一个字符串,只做简单的替换,编译程序不做语法检查。

(4)宏定义并不是C语句,一般不在行末加分号。如果加上分号,则会连分号一起进行替换。

(5)#define命令必须放在函数定义的外面,习惯上,#define总是写在文件开头处。宏名的作用域为从宏定义命令起到源文件结束,可以用#undef命令终止宏名的作用域,这样可以灵活控制宏名的作用范围。

(6)宏定义中可以引用已定义的宏名,进行层层替换。

(7)在源程序中出现的宏名若带引号时,预处理程序不对其进行宏替换。例如,例11.14的printf()函数格式字符串中的L和S都没有被替换。

(8)宏定义还可以定义运算符、表达式及其他符号。

11.1.2 带参数的宏定义

带参宏是指在宏名的后面带有参数。宏定义中的参数称为形参,宏调用中的参数称为实参。在调用带参数的宏时,不仅要进行宏展开,而且要进行参数替换,其定义的一般形式为:

#define 宏名(形参表) 字符串

其中,“字符串”中包含形参表中的参数。带参宏调用的一般形式为:

              宏名(实参表)

说明:

(1)带参宏定义时,宏名与括号之间不应有空格,否则将空格以后的字符都作为字符串的一部分。

(2)宏定义中,字符串中的形参通常要用括号扩起来。

带参的宏调用与函数调用非常相似,但两者的实现过程完全不同。区别主要有:

(l)函数调用时,如果实参是表达式,要先求出表达式的值,再把结果值传递给形参。而使用带参的宏不作计算,直接替换进去。例如,上面的S(a-b),在宏展开时并不计算a-b的值,而只将实参字符“a-b”代替。

(2)函数调用是在程序运行时处理的,而宏调用是在编译时进行的。

(3)函数中的实参和形参都要定义类型,实参和形参是不同的变量,各自有自己的作用域,系统为实参和形参分配内存单元,调用时要把实参值传递给形参,进行“值传递”。而宏不存在类型的问题,宏名无类型,它的形参也无类型,只是一个符号,系统不为形参分配内存单元,不进行值的传递。但宏调用中的实参有具体的值,要用它们去替换形参,若是变量时必须作类型声明。

(4)程序中使用宏定义多时,宏展开以后的源程序长,因为每展开一次都使程序增长,而函数调用不会使源程序变长。

(5)宏替换不占用运行时间,只占用编译时间,而函数调用则占用运行时间(分配单元、保留现场、值传递和返回等)。

11.2 文件包含

文件包含是指一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。C语言提供了#include命令,用来实现文件包含操作,其一般形式为:

#include<文件名>

#include "文件名"

以上两种#include的区别是:采用尖括号(如<stdio.h>)时,编译系统从启动C编译系统的文件夹中去寻找所要包含的文件,这称为标准方式。如果用双引号(如"stdio.h")时,编译系统首先从用户保存源文件的文件夹中去寻找所要包含的文件,若找不到,再按标准方式查找。一般来说,如果调用系统的是库函数,用标准方式(尖括号)可节省查找时间,而如果要包含自己编写的文件时,一般用双引号方式。

文件包含命令是编译预处理命令,是在编译前执行的。编译程序在执行#include命令时将被包含文件插入到#include命令所在的位置,合并在一起当作一个文件来处理,并不是作为两个文件连接(用link命令实现连接),而是作为一个源程序编译,得到一个目标(.obj)文件,因此被包含的文件也只能是源文件而不能是目标文件(.obj文件)。

用文件包含的方法可以减少重复代码的输入,减轻劳动强度,提高编程效率。

使用#include命令的注意事项:

(1)一个#include命令只能指定一个被包含文件。如果要包含n个文件,要用n个#include命令。

(2)在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。但不能循环嵌套。

(3)被包含文件中的全局变量也是包含文件中的全局变量,在包含文件中这些量不必使用extern声明即可直接引用。

(4)C语言为用户提供了标准函数和宏定义。用户要想使用这些库函数,必须用#include命令将有关头文件包含在自己的源程序中。

11.3 条件编译

11.3.1 #ifdef…#else…#endif命令

一般形式如下:

#ifdef 标识符

程序段1

#else

程序段2

#endif

功能:如果标识符已经被#define命令定义过,则在程序编译时对程序段1进行编译;否则,对程序段2进行编译。

11.3.2 #ifndef…#else…#endif命令

一般形式如下:

#ifndef 标识符

程序段1

#else

程序段2

#endif

功能;如果标识符没被#define命令定义过,则对程序段1进行编译;否则,对程序段2进行编译。这与格式1的功能恰好相反。

11.3.3 #if命令

一般形式如下:

#if常量表达式

程序段1

#else

程序段2

#endif

功能:如果常量表达式的值为真(非0),则对程序段1进行编译;否则,对程序段2进行编译。

11.3.4 #undef命令

一般形式如下:

       #undef 标识符

功能:将已经定义的标识符变为未定义的。

12.1 逻辑位运算

12.1.1按位“与”运算符&

按位“与”运算的运算符用“&”表示。

按位“与”的运算规则是:将两个操作数二进制位中的对应位相与,当对应位都为1时结果为1,否则结果为0

12.1.2 按位“或”运算符|

按位“或”运算的运算符用“|”表示。

按位“或”的运算规则是:将两个操作数二进制位中的对应位相或,对应位都为0时结果为0,否则结果为1

12.1.3 按位“异或”运算符^

按位“异或”运算的运算符用“^”表示。

按位“异或”的运算规则是:将两个操作数二进制位中的对应位相异或,对应位相同时结果为0,不同时结果为1

12.1.4 按位“取反”运算符~

按位“取反”运算的运算符用“~”表示。

按位“取反”的运算规则是:将操作数的各二进制位按位取反,将0变为1,将1变为0

12.2 移位运算符

12.2.1 左移运算符<<

左移运算的运算符用“<<”表示。

左移运算的运算规则是:将一个操作数的二进制表示形式按指定的移位次数向左移动,移出的高位丢掉,空出的低位补0

12.2.2 右移运算符>>

右移运算的运算符用“>>”表示。

右移运算的运算规则是:将一个操作数的二进制表示形式按指定的移位次数向右移动,移出的低位丢掉。空出的高位,根据操作数的类型来定,如果是无符号数,则高位补0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1031485.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一章 计算机网络基础

目录 1.1 网络体系结构 1.1.1 OSI/RM七层参考模型 1.1.2 OSI/RM和TCP/IP模型的比较 1.1.3 五层协议的体系结构 1.1.4 计算机1向计算机2发送数据过程 1.1.5 TCP/IP体系结构的具体实现 1.2 网络设备概述 1.2.1 互联设备与OSI的对应关系 1.2.2 集线器(HUB) 1.2.3 网桥(B…

新势力在智能化路上,正抢了Tier 1的生意

作者 | Amy 编辑 | 德新 上半年的汽车行业价格内卷&#xff0c;下半年则一下资本涌入&#xff0c;风起云涌。 先是蔚来拿到了11亿美元来自中东的投资&#xff0c;紧接着7月大众以7亿美元投资小鹏汽车&#xff0c;8月哪吒完成70亿元Crossover轮投资。传闻中&#xff0c;还有大众…

GE IS220PAICH2A 336A4940CSP11 控制脉冲模块

GE IS220PAICH2A 336A4940CSP11控制脉冲模块是一种用于工业自动化和控制系统的模块&#xff0c;通常用于监测和生成脉冲信号&#xff0c;以控制各种设备和过程。以下是可能与该控制脉冲模块相关的一些产品功能&#xff1a; 脉冲生成&#xff1a;GE IS220PAICH2A 336A4940CSP11控…

JCEF中js与java交互、js与java相互调用

jcef中js与java相互调用&#xff0c;java与js相互调用&#xff0c;chrome与java相互调用&#xff0c;java与chrome相互调用、jcef与java相互调用 前提&#xff1a;https://blog.csdn.net/weixin_44480167/article/details/133170970&#xff08;java内嵌浏览器CEF-JAVA、jcef、…

天玑科技PBData信创数据库私有云平台荣获“专题展优秀成果奖”

9月15-16日&#xff0c;由湖南省人民政府、工业和信息化部联合主办的2023世界计算大会在湖南长沙盛大启幕。天玑科技作为云服务、信息技术应用创新领域优秀的解决方案提供商受邀参会参展。 大会以“计算万物 湘约未来——计算产业新变革”为主题&#xff0c;全国政协副主席、民…

GE IS420UCSCH2A-C-V0.1-A模拟量输入模块

GE IS420UCSCH2A-C-V0.1-A 模拟量输入模块是一种用于数据采集和监测的电子模块&#xff0c;通常应用于工业控制系统、监测设备和自动化系统中。以下是可能与该模拟量输入模块相关的一些产品特点&#xff1a; 多通道输入&#xff1a; GE IS420UCSCH2A-C-V0.1-A 模拟量输入模块通…

这个世界,永远靠实力说话

这个世界&#xff0c;永远靠实力说话。与其寄望于运气或机会的降临&#xff0c;还不如脚踏实地&#xff0c;努力提升自己。因为只有强者&#xff0c;才能在这个充满挑战和机遇的世界里谈笑风生&#xff0c;创造出属于自己的成功和辉煌。 就比如峰民dyfm888给人取名改名&#x…

基于Java的Base64编解码优化探讨

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

腾讯云16核CPU服务器配置大全,CVM和轻量服务器

腾讯云16核CPU服务器有哪些配置可以选择&#xff1f;可以选择标准型S6、标准型SA3、计算型C6或标准型S5等&#xff0c;目前标准型S5云服务器有优惠活动&#xff0c;性价比高&#xff0c;计算型C6云服务器16核性能更高&#xff0c;轻量16核32G28M带宽优惠价3468元15个月&#xf…

如何搭建数据驱动自动化测试框架?

前言 说到数据驱动自动化测试&#xff0c;你会不会有这样的疑问&#xff1a;数据怎么管理&#xff1f;数据怎么才能驱动测试用例执行&#xff1f;到底怎么样才算数据驱动&#xff1f;那么本篇文章就教你如何进行数据驱动测试&#xff0c;相信你一定能对数据驱动自动化测试有一…

【Java 集合】常用的Java集合框架体系详解(134)

一、集合的体系 概述&#xff1a;java中存储对象数据的一种容器&#xff0c;集合只能存储引用类型的数据。用泛型来规定需要操作元素的数据类型&#xff0c;可以在编译阶段约束集合只能操作某种数据类型。集合分为两个家族 MAP和Collection 特点&#xff1a;大小不固定&#…

YOLOv8 YOLOv7 YOLOv5 训练 SCB-Dataset3-U

目录 0 相关资料1 SCB-Dataset3-U 数据2 YOLOv8 训练2.1 YOLOv8 安装2.2 训练的yaml文件2.3 YOLOv8 训练2.3.1 yolov8n 训练2.3.2 yolov8n 验证 0 相关资料 YOLOV8环境安装教程.&#xff1a;https://www.bilibili.com/video/BV1dG4y1c7dH/ YOLOV8保姆级教学视频:https://www.…

实施预测性维护解决方案的挑战及PreMaint的应对方法

前面我们介绍了企业选择预测性维护解决方案的常见问题和PreMaint的策略&#xff0c;本期我们将带来实施过程中可能会遇到的挑战&#xff0c;以及如何通过PreMaint来应对这些挑战&#xff0c;以实现可靠的预测性维护。 随着工业技术的不断进步&#xff0c;预测性维护作为一种先进…

【C语言】结构体内存对齐机制详解

目录 一、前言二、结构体内存对齐规则三、实例解析 一、前言 在讲解结构体内存对齐机制之前&#xff0c;我们先来看1个例子&#xff1a; typedef struct {char sex; // 性别int id; // 学号char name[20]; // 姓名float score; // 成绩char addr[30]; …

中秋特辑——3D动态礼盒贺卡(可监听鼠标移动)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

华纳云:如何搭建Nginx服务器做到负载均衡

要搭建Nginx服务器实现负载均衡&#xff0c;您可以使用Nginx作为反向代理来分发客户端请求到多个后端服务器。以下是一个基本的步骤指南&#xff1a; 前提条件&#xff1a; 您需要一台安装有Nginx的服务器。您需要有多台后端服务器&#xff0c;这些服务器将处理客户端请求。 …

centos7 装机遇到的问题

centos7 U盘启动装机 设置完启动项后重启 在菜单界面选择install centos7 按e编辑启动项&#xff0c;修改成如下 --> 之所以这么改是u盘的LABEL超过长度了只能显示到x8这里&#xff0c;nomodeset 是disable 视频驱动比如gpu 开始安装后如果选择的硬盘没有多余的空间了会提…

TikTok的媒体革命:新闻业如何适应短视频时代?

在数字时代&#xff0c;媒体行业一直在不断演变和创新&#xff0c;以适应观众的变化需求和技术的发展。而在这个进化的过程中&#xff0c;短视频应用TikTok已经崭露头角&#xff0c;成为了一个重要的信息传播平台。 这篇文章将深入探讨TikTok如何引领了媒体的一场革命&#xf…

mininum_snap

位置 速度 加速度 角度 jerk 角速度 驱动力 snap 角加速度 推力的导数 凸优化算法 convex optimization 凸优化&#xff08;Convex Optimization&#xff09;是数学和计算机科学领域的一个重要分支&#xff0c;主要研究如何有效地解决凸优化问题。凸优化问题的主要目标是找…

pytest进阶之conftest.py

前言 前面几篇随笔基本上已经了解了pytest 命令使用&#xff0c;收集用例&#xff0c;finxture使用及作用范围&#xff0c;今天简单介绍一下conftest.py文件的作用和实际项目中如是使用此文件&#xff01; 实例场景 首先们思考这样一个问题&#xff1a;如果我们在编写测试用…