预处理和文件操作

预处理和文件操作

预处理是在编译前所做的工作,编译器自动调用预处理程序对源码中以’#’开头的预处理部分进行处理,处理完毕 后,进入源码的编译阶段 

预处理有:宏定义、条件编译、文件包含。

一、宏定义 

宏定义,又称为宏替换,自定义一个宏(要符合标识符的命名规则),用于替换任意数据、标识符或者表达式。

1,无参宏定义

定义无参宏的基本格式:#define 宏名 宏替换 比如:

#define A 35 //宏A就代表整型数据35.
#define TEST "abddgdsfdlfj" //宏TEST就代表字符串"abddgdsfdlfj"
#define TEST abddgdsfdlfj //宏TEST就代表abddgdsfdlfj
#define I int //宏I就代表int(相当于给数据类型取别名)

 注意:①宏名不可以被赋值②定义宏,通常会给宏替换打括号,避免出现优先级的问题

2,有参宏定义

定义带参宏的基本格式: #define 宏名(参数表) 宏替换 带参宏可以像函数一样调用

3,特点

一改全改

4、常量的定义

除了宏定义以外,还可以通过const关键字定义常量: 普通常量: < const> = ; 如:

const int a = 30; //定义一个常量a,其值等于30

注意:定义成常量后,值不可被改变 。

二、条件编译

条件编译也就是根据不同的条件编译不同代码段。

作用:适当减轻编译器的负担 (提高编译的效率)

1、#if……#else的使用

#if 表达式 //判断表达式的逻辑值(真或假),若逻辑值为真,则编译代码段1,否则编译代码段2.

        代码段1;

#else

         代码段2;

#endif

#define FLAG 1
#include<stdio.h>
#include<string.h>
//#include<stdlib.h>
//#include<time.h>
int main() {
	char str[1024] ="\0";
	int i = 0;
	gets_s(str);
	while (str[i] != '\0') {
#if FLAG
		if(str[i]>='a'&&str[i]<='z')//小写转大写
		{
			str[i] = str[i] - ('a' - 'A');
		}
#else
		if(str[i]>='A'&&str[i]<='Z')//大写转小写
		{
			str[i] = str[i] + ('a' - 'A');
		}
#endif
		i++;//这条语句是while循环里的遍历:应该养成良好的敲代码习惯,在写while时就早早得将这条遍历语句添上,防止遗忘
	}

	puts(str);
}

2、#ifdef……#endif的使用

第一种应用场景

#ifdef 宏名

//如果定义了宏"宏名",则编译代码段.

代码段;

#endif

第二种应用场景

#if 表达式

//判断表达式的逻辑值(真或假),若逻辑值为真,则编译代码段1,否则编译代码段2.

代码段1;

#else

代码段2;

#endif

3、#ifndef……#endif的使用

#ifdef 宏名

//如果定义了宏"宏名",则编译代码段.

代码段;

#endif

#ifndef 宏名

//如果没有定义宏"宏名",则编译代码段1,否则编译代码段2;

代码段1;

#else 代码段2;

#endif

因此宏名只会被定义一次 

三、文件包含

1、包含库函数头文件

我们想要用库函数就需要包含头文件,也就是文件包含,当然也可以编写自定义头文件,包含自己编写的头文件。 如:

#include <stdio.h>
//包含系统头文件用<>,只会在系统头文件中找
#include "name.h"
//包含自定义头文件用””,先在自定义头文件中找,找不到就会在系统头文件中找

文件包含允许嵌套,即在一个被包含文件中可以包含其它文件。

2、头文件的重复包含

头文件的嵌套包含可能会引起头文件的重复包含,从而出现函数和变量的重定义问题 所以需要避免头文件重复包 含,某些宏定义语句可以防止头文件重复包含,如:

#pragma once //防止头文件重复包含,不让文件的内容被包含两次,在头文件最前面添加

(#pragma once是vs独有的,有使用平台的限制,其他平台可能不存在)

3、C程序的分文件编写

多文件编程就是把多个头文件(.h文件)和源文件(.c文件)组合在一起构成一个程序,这是C语言的重点,也是C 语言的难点。 C语言头文件的编写是其中的重点内容,有很多细节需要注意,文件编程既涉及到了内存,也涉及到 了编译原理,有的甚至会让你感觉奇怪。 学会了多文件编程,你就可以使用C语言来开发中大型项目了,对初学者 来说,这简直是跨域了一大步。 在开发中大型项目中,一般用头文件封装函数的声明,在源文件里完成函数功能 的定义。

四、文件操作

1.文件的概念

什么是文件?

文件有不同的类型,在程序设计中,主要用到两种文件:

(1)程序文件。包括源程序文件(后缀名为.c)、目标 文件(后缀名为.obj)、可执行文件(后缀名为.exe)等。这一类型的文件主要用于存储程序代码。

(2)数据文件。此文件的内容不是程序,而是程序运行时读写的数据,比如程序运行过程中输出到磁盘或其他设备上的数据, 或在程序运行过程中供程序读取的数据。

这里C语言的文件操作主要是对数据文件的操作。

在之前程序中所处理 的数据的输入和输出都是以终端为对象的,都是从键盘输入数据,然后运行结果输出到终端显示器上。

实际上,我 们有时候需要将一些数据(程序运行的最终结果或者中间数据)保存起来,方便以后需要时再调用,而这就需要用 到磁盘文件了。

(1)文件名 每一个文件都需要一个唯一的文件标识,以便用户使用,就像我们的变量名一样,同一程序中不能有相同的变量 名。 文件标识也称为文件名,它由3部分组成:

        ①文件路径:表示文件在外存设备中的存储位置; ②文件名主 干:表示文件的名字,可由用户自定义,命名规则应遵循标识符的命名规则。 ③文件后缀:表示文件的性质,也 称为文件的格式,用于描述文件的类型(如txt、ppt等)。

        文件路径能唯一标识文件在外存中的位置。 如:D:\C++\VSproject\TEXT\text.c

(2)文件的分类 根据数据的组织形式,数据文件可分为ASCII文件和二进制文件。

         数据在内存中是以二进制形式存储的,如果不加 转换的输出到外存,就是二进制文件,可以认为它是存储在内存的数据的映像,所以称之为映像文件。如果要求在 外存上以ASCII码形式存储,就需要在存储前进行转换。

        ASCII文件又称为文本文件,每一个字节存放一个字符的 ACSII码。

(3)文件存储方法的区别 一个数据在磁盘上存储,字符一律以ASCII形式存储,数值型既可以用ASCII形式存储也可以用二进制形式存储。

        如 整数10000,用ASCII码形式存储在磁盘上占5个字节(每个字符占一个字节),而用二进制形式存储在磁盘上只占4 个字节(00000000 00000000 00100111 00010000)。

        用ASCII形式存储时字符与字节一一对应,一个字节代表一个 字符,便于逐个处理,但占的存储空间较多,而且处理的时候要花费转换时间(二进制与ASCII码之间的转换)。二 进制形式存储就相当于直接把内存中的内容原封不动存储在磁盘上,由于不需要转换,所以二进制文件更加方便计 算机处理。 

 2、文件的基本操作 

          

(1)文件指针的定义

由于文件类型已经在stdio.h头文件中有声明了,所以我们不需要另外声明,直接使用就行了。 文件类型变量的定 义格式为:FILE 文件变量名; 

   (2)文件的打开

①使用fopen函数打开文件

C语言规定用文件标准输入输出函数fopen来实现打开文件。 fopen函数的调用方式为: fopen(文件名,使用文件的 方式); 例如:fopen(“text1.txt”,”r”); 意思是以只读的方式打开名为“text1.txt”文件。 此时fopen函数返回的 是“text1.txt”文件的起始地址,我们通常将fopen函数的返回值赋值给一个文件指针,用文件指针指向此文件的地 址。例如:

FILE *fp;//定义一个文件指针fp

fp=fopen(“text1.txt”,”r”);

//使fp指向文件“text1.txt”的首地址 这样fp就 与文件“text1.txt”有联系了。

②文件的打开方式

文件打开方式及含义如下表所示

(3)文件操作函数

可以通过c/c++参考手册查阅相关文件操作函数用法:如让文件指针位置移动的函数fseek()、文件字符写入fputc()、文件字符输出fgetc()、文件字符串读入fputs()、文件字符串输出fgets()、文件格式化读入fprintf()、文件格式化输出fscanf()

 

 

FEEK_SET 是0的宏名,以此类推

 

 修改后:(①fopen函数里的第一个参数是图片文件的属性 ②要细心,不要弄错文件操作的顺序)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {
	FILE* fp1;//创建文件指针
	fp1 = fopen("D.data", "w+");//打开文件
	char a = 'a';
	putc(a, fp1);
    fclose(fp1);//关闭文件
	FILE* fp2;
	fp2 = fopen("小怪兽.png", "rb");
	fseek(fp2, 0, 2);
	int size = ftell(fp2);
	printf("图片大小:%d\n", size);
    fclose(fp2);
	return 0;
	/*真难受,已经连续两天卡在这里了*/
}

运行如下

 

 

fp1指向的文件写入了一个'a'

 

附上可爱的小怪兽——不要被困难打倒,共勉!

(4)文件的关闭

在使用完一个文件之后,为了防止它被误用,应该关闭它。“关闭”就是撤销文件信息区和文件缓冲区,使指针不再 指向此文件了,也无法操作此文件了,除非重新打开此文件,使指针指向此文件。 关闭文件用fclose函数。 fclose 函数的一般形式为: fclose(文件指针); 

在每次程序终止之前都要养成习惯关闭所有的文件。 当fclose函数成功关闭文件时,返回0;否则返回EOF(-1)。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿井侯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值