C语言复习004_预处理、结构体、文件操作

C语言复习004_预处理、结构体、文件操作

一、预处理(#)

//常见的两类预处理
#include <stdio.h>
#define PI 3.1415926535897
//注意:预处理最后边不加分号“;”

在源程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们称为预处理部分。

(一)宏定义#define

宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对他不做任何检查,如有错误,只能在编译已被宏展开后的源程序时发现。

宏定义写在函数之外,作用域为从宏定义命令到原程序结束,如果要终止则使用**#undef**命令

#define PI 3.1415926
...
#undef PI

(二)类型定义typedef

在编译时处理的,对类型说明符重新命名。被命名的标识符具有类型定义说明的功能。

小例题:不用嵌套和循环,打印出0~999数字

#include <stdio.h>
#define A(x) x;x;x;x;x;x;x;x;x;x;
void main()
{
	int n = 0;
	A(A(A(printf("%d", nn++))));
}

(三)带参数的宏定义

一般命名形式:

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

一般调用形式:

宏名(实参表);

宏定义中的形参时标识符,二宏调用中的实参可以是表达式

在宏定义中,字符串内的形参通常要用括号括起来避免出错

#include <stdio.h>
#define SQ(y) ((y) * (y))  //注意这地方的define定义的括号添加
void main()
{
	int a, sq;
	printf("Input a number:");
	scanf("%d", &a);
	sq = 160 / SQ(a+1);
	printf("sq = %d\n", sq);
}

(四)文件包含

#include <stdio.h>
#include "stdio.h"

两种形式的不同之处:
1、使用尖括号表示在包含文件目录中取查询(包括文件目录是由用户在这设置环境设置的),而不再源文件目录去查找;
2、使用双引号则表示首先在当前的源文件目录中查找,若未找到才到半酣目录中取查找。用户编程时可以按照自己文件所在目录来选择某一种命令行形式。

(五)条件编译

第一种形式
如果标识符被#define命令定义过则编译程序段1,否则编译程序段2

#ifdef 标识符
	程序段1
#else
	程序段2
#endif

如果没有程序段2(他为空),本格式中的#else可以没有,可以写为:

#ifdef 标识符
	chengxuduan 1
#endif

第二种形式

#ifndef 标识符
	程序段1
#else
	程序段2
#endif

第三种形式

#if 常量表达式
	程序段1
#else
	程序段2
#endif

二、结构体

(一)定义

定义一个结构体的一般形式

struct 结构体名称
{
	//成员列表
	类型说明符 成员名;
	类型说明符 成员名;
	。。。
};

例子:

struct student
{
	int num;
	char name[20];
	char sex;
	int age;
	float score;
	char addr[30];
};

定义结构以i变量的一般形式:
1、
struct 结构体名 变量名;
2、
struct 结构体名称
{
//成员列表
类型说明符 成员名;
类型说明符 成员名;
。。。
} 变量名1, 变量名2, …;

(二)引用

引用结构体变量中成员的方式:j结构体变量名.成员名

"."是成员(分量)运算符,它在所有的元素安抚中优先级最高,因此可以把student1.num作为一个整体来看待。

(三)指向结构体类型数据的指针

1、定义的一般形式:
struct 结构名 *结构指针变量名;

赋值是把结构变量的首地址赋予该指针变量,不是把结构名赋予该指针变量。例如:

struct stu
{
	char name;
	int age;
	char sax;;
};
struct stu *pstu;
struct stu boy;
pstu = &boy; //这条语句是正确的
pstu = &stu; //这条语句是错误的

2、访问的一般形式:
(*结构体指针变量).成员名 //括号是必须带着的
或者为:
结构体指针变量->成员名
例如:
(*pstu).num;
或者
pstu->num;

(四)动态存储分配

C语言提供了一些内存管理函数,这些内存管理函数可以按照需要动态地非标配内存空间,也可以把不再使用的空间回收待用,为有效地使用内存资源提供了手段。

常用的内存管理函数:
分配内存空间函数:malloc,calloc
始放内存空间函数:free
(1)malloc
函数原型为void *malloc(unsigned int size);
其作用是在内存的动态存储区中分配一个长度为size的连续空间(size是一个无符号数)
此函数的返回值是一个指向分配域起始地址的指针
如果此函数未能成功执行(内存不足),则返回空指针NULL

(2)calloc
函数原型为void *calloc(unsigned n, unsigned size);
其作用是在内存的动态存储区中分配n个长度为size的连续空间。
函数返回一个指向分配域起始地址的指针。
如果分配不成功,则返回NULL
用calloc函数可以为一维数组开辟动态存储空间,n为数组元素的个数,每个元素长度为size。

(3)free
函数原型为void free(void *p);
其作用是始放由p指向的内存区,使这部分内存区能被其他变量使用。
p是最近依次调用calloc或malloc函数时返回的值
free函数没有返回值。

(五)链表

#include <stdio.h>

struct student
{
	long num;
	float score;
	struct student *next;
}

void main()
{
	struct student a, b, c, *head;
	a.num = 10101;
	a.score = 89.5;
	b.num = 10102;
	b.score = 90;
	c.num = 10103;
	c.score = 85;

	head = &a;
	a.next = &b;
	b.next = &c;
	c.next = NULLdo
	{
		printf("%ld, %s.1f\n", head->num, head->score);
		head = head->next;
	}while(head != NULL);
}

(六)typedef的使用

用typedef生命新的类型名来代替已有的类型名。

比如生命INTEGER为整型:typedef int INTEGER;

用typedef来定义一个新的结构体类型能够大大简化代码的书写,在windows的头文件中使用了大量的结构体类型的重新定义。

#include <stdio.h>

typedef struct
{
	int month;
	int day;
	int year;
} DATE;

void main()
{
	DATE date_one;
	date_one.year = 2021;
	date_one.month = 03;
	date_one.day = 12;
	printf("%d-%d-%d \n", date_one.year, date_one.month, date_one.day);
}

三、文件操作

(一)文件的打开与关闭

文件型指针变量:
FLIE *fp;
fp是一个指向FLIE类型结构体的指针变量。

1、文件的打开函数(fopen)
函数调用:

FLIE *fp;
fp = fopen(文件名, 使用文件的方式)

注意:
(1)需要打开的文件名,也就额是准备访问的文件的名字(文件路径)
(2)使用文件的方式(“读”还是“写”等)
(3)让每一个指针变量指向被打开的文件

文件的打开方式关键字
2、文件的关闭函数(fclose)
函数调用:

fclose(文件指针)

函数功能:
是文件指针变量指向该文件,也就是文件指针变量与文件“脱钩”,此后不能再通过该指针对原来与其联系的文件进行读写操作。

返回值:关闭成功返回值为0,否则返回值EOF(-1)

3、文件的读写
C语言中提供了很多的文件读写函数:
字符读写函数:fgetc和fputc
字符串读写函数:fgets和fputs
数据块读写函数:freed和fwrite
格式化读写函数:fscanf和fprintf

以上函数都要包含stdio.h头文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

仲子_real

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

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

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

打赏作者

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

抵扣说明:

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

余额充值