C语言include-文件包含

1. 关于 include 的知识

文件包含是预处理的一个重要功能 ,它将多个源文件链接成一个源文件进行编译,结果将生成一个目标文件。C 语言提供 #include 命令来实现文件包含的操作,它实际是宏替换的延伸,有两种格式。

  1. 格式 1:
#include <filename> 

其中,filename 为要包含的文件名称,用尖括号括起来,也称为头文件,表示预处理到系统规定的路径中去获得这个文件(即 C 编译系统提供的并存在指定子目录下的头文件)。找到文件后,用文件内容替换该语句。
2. 格式 2:

#include "filename"

其中,filename 为要包含的文件名称。双引号表示预处理应在当前目录中查找文件名为 filename 的文件;若没有找到,则按照系统指定的路径信息搜索其他目录。找到文件后,用文件内容替换该语句。
Note 1:#include 是将已存在文件的内容嵌入到当前文件中。
Note 2:#include 支持相对路径,. 代表当前路径;.. 代表上层目录。

2. 示例代码

errno. h 文件包含错误码宏定义

#define EPERM 1
#define ENOENT 2
#define ESRCH 3
#define EINTR 4
#define EIO 5
……
#define ENOTRECOVERABLE 131
#define ERFKILL 132
#define EHWPOISON 133

strerror. h 文件包含 E (错误码宏定义, 错误码描述信息),这个文件不能在 main. c 开头直接 include “strerror. h”,因为本文件中的 E 是未定义的。具体引用方式可以参考 main. c 中的代码。

#include "errno.h"

E(0, "No error information")
E(EILSEQ, "Illegal byte sequence")
E(EDOM, "Domain error")
E(ERANGE, "Result not representable")
……
E(EKEYEXPIRED, "Key has expired")
E(EKEYREVOKED, "Key has been revoked")
E(EKEYREJECTED, "Key was rejected by service")

main. c 文件

#include <stddef.h>
#include <stdio.h>

static const struct errmsgstr_t
{
#define E(n, s) char str##n[sizeof(s)];
#include "strerror.h"  // 此处会将strerror.h的内容按照第6行的宏定义展开
#undef E
} errmsgstr = {
#define E(n, s) s,
#include "strerror.h"  // 此处会将strerror.h的内容按照第10行的宏定义展开
#undef E
};

static const unsigned short errmsgidx[] = {
// 利用offsetof来定位各个错误码对应的描述信息的指针
#define E(n, s) [n] = offsetof(struct errmsgstr_t, str##n),
#include "strerror.h"  // 此处会将strerror.h的内容按照第17行的宏定义展开
#undef E
};

char *strerror(int e)
{
	const char *s;

	if (e >= sizeof errmsgidx / sizeof *errmsgidx)
		e = 0;
	s = (char *)&errmsgstr + errmsgidx[e];
	return (char *)s;
}

int main()
{
	// printf("%s\n", errmsgstr.str0);
	printf("%s\n", strerror(EKEYREJECTED)); 
	return 0;
}

3. 思考 :

main. c 中的 errmsgstr 结构体需要考虑字节对齐问题吗?
在一个结构体中的成员全部是字符数组时,不需要特别考虑内存对齐。因为字符数组默认对齐方式为1字节,而 C 语言标准规定结构体成员的内存对齐方式必须满足其本身大小的整数倍,因此如果结构体中只有字符数组类型的成员,则每个成员都会按照1字节对齐。
不过,如果该结构体还包含其他类型的成员,比如int、double等,那么为了避免浪费空间,可能需要手动进行内存对齐,可以使用#pragma pack(n)指令或者__attribute__((aligned(n)))属性来实现。具体的对齐方式要根据具体的硬件平台和编译器来确定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值