C语言 15 预处理

C 语言学习已经快要接近尾声了,但是有一个东西迟迟还没有介绍,就是一直在写的:

#include <stdio.h>

这到底是个什么东西,为什么每次都要加上呢?这里将详细讨论它缘由。

C 语言中带 # 号的指令并不是 C 关键字的一部分,不属于 C 语言。

# 号的指令是写给编译器看的,告诉它一些事情,好让它更好的为 C 代码服务。

比如 #include</font> 指令就是告诉编译器看到这句话就要把我写的文件包含进来,#define 指令就是告诉编译器看到这个宏就用前面已经定义好的内容替换。

文件包含

当预处理器发现#include指令时,会查看后面的文件名并把文件的内容包含到当前文件中,来替换掉#include指令。比如:

int main() {printf("Hello World!");
}

这个函数是由系统提供的函数,实际上这个函数是在其他源文件中定义好的,而定义这个函数的源文件,就是stdio.h,可以点进去看看:

除了printf之外,看到还有很多很多的函数原型定义,他们都写到这个源文件中,而这个文件并不是以.c结尾的,而是以.h结尾的,这种文件称为头文件。头文件一般仅包含定义一类的简单信息,只要能让编译器认识就行了。

#include则是将这些头文件中提供的信息包含到 C 语言源文件中,这样才能使用定义好的printf函数,如果不添加这个指令的话,那么会:

直接不认识了,如果不告诉编译器这个函数是从哪来的,它怎么知道这个函数的具体定义是什么,程序又该怎么执行呢?

#include的具体使用格式如下:

#include <文件名称>

当然也可以写成:

#include "文件名称"

这两种写法虽然都能引入头文件,但是区别还是有的:

  • 尖括号: 引用的是编译器的库路径里面的头文件。
  • 双引号: 引用的是程序目录中相对路径中的头文件,如果找不到再去上面的库里面找。

可以看到系统已经提供好了多种多样的头文件了,通过这些系统提供的库,就可以做很多的事情了。

当然也可以自己编写一个头文件,直接在项目根目录下创建一个新的 C/C++ 头文件 test.h

// 声明函数原型
int test(int a, int b);

接着就可以编写源文件 test.c 引入这个头文件了:

#include <stdio.h>
// 因为是自己项目目录中的,所以需要使用双引号
#include "test.h" int main() {// 这样就可以使用头文件中声明的函数了int c = test(1, 2);printf("%d", c);
}// 编写函数具体实现
int test(int a, int b) {   return a + b;
}
3

实际上预处理器正是通过头文件得到编译代码时所需的一些信息,然后才能把程序需要的内容(比如这里要用到的 test函数)替换到源文件中,最后才能正确编译为可执行程序。

比如现在要做一个学生管理库 student.h,这个库中提供了学生结构体的定义,以及对学生信息相关操作:

// 学生结构体定义
struct stu {int id;int age;char name[20];
} typedef Student;// 打印学生信息
void print(Student* student);// 修改年龄
void modifyAge(Student* student, int newAge);// 修改学号
void modifyId(Student* student, int newId);

再定义源文件 student.c

#include <stdio.h>
#include "student.h"int main() {Student student = {1, 18, "小明"};modifyAge(&student, 19);print(&student);
}void print(Student* student) {printf("ID: %d, 姓名: %s, 年龄: %d岁\n", student->id, student->name, student->age);
}void modifyAge(Student* student, int newAge) {student->age = newAge;
}void modifyId(Student* student, int newId) {student->id = newId;
}
ID: 1, 姓名: 小明, 年龄: 19

通过使用#include就可以将项目拆分成多个模块去进行编写了。


环境:

  • GCC 11.4.0
  • VSCode 1.93.1

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

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

相关文章

ASCII Unicode UTF-8 字符集 字符编码

ASCII Unicode UTF-8 字符集 字符编码 基本概念字符字符集字符编码 字符集和字符编码ASCII 字符集Unicode 字符集UTF-8 附录 基本概念 字符集为每个字符分配了一个唯一的编号&#xff0c;通过这个编号就能找到对应的字符。在编码过程中我们经常会使用字符&#xff0c;而使用字…

【工具分享】FONIX勒索病毒解密工具

前言 FONIX勒索软件首次出现在2020年6月&#xff0c;并迅速成为勒索即服务&#xff08;RaaS&#xff09;平台的一部分。尽管它最初的影响力有限&#xff0c;FONIX从2020年11月开始显著增加了攻击频率。FONIX以其复杂的加密方法著称&#xff0c;使用了AES、Salsa20、ChaCha和RS…

阿博图书馆管理系统:SpringBoot实现细节

第三章 系统分析 通过对系统功能模块分析可以得知&#xff0c;主要是对项目元素组合、分解和更换做出相应的单元&#xff0c;再通过系统模块来规划出一个原则&#xff0c;系统的设计首先是围绕用户需求进行开发设计的&#xff0c;主要是为了能够更好的管理信息和方便用户&#…

002、视频格式转换

下载地址 http://www.pcfreetime.com/formatfactory/CN/index.html

高校教师成果管理小程序的设计与实现springboot(lw+演示+源码+运行)

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对高校教师成果信息管理混乱&#xff0c;出错率高&#xff0c;信息安全…

怎么把word转化为ppt?这2款在线转换工具不容错过!

怎么把word文档转化为ppt&#xff1f; 在当今快节奏的办公日常中&#xff0c;高效处理文档格式转换已成为职场人必备的一项技能。当我们要进行演示报告、汇报工作&#xff0c;或是分享知识时&#xff0c;经常需要把Word文档转换为PPT演示文稿。然而&#xff0c;这个看似简单的…

「JavaScript深入」聊一聊 new操作符具体干了什么?

JavaScript深入 — new操作符 概念流程手写new操作符 概念 在JavaScript中&#xff0c;new 操作符用于创建一个给定构造函数的实例对象 function Person(name, age){this.name name;this.age age; } Person.prototype.sayName function () {console.log(this.name) } cons…

WT2605C蓝牙语音芯片智能对话模型 人机互动 让机械设备更智能

随着人工智能技术的飞速发展&#xff0c;AI语音芯片在机械设备领域的应用日益广泛。WT2605C作为一款集成了在线TTS&#xff08;Text-To-Speech&#xff0c;文本到语音&#xff09;功能的蓝牙语音芯片&#xff0c;凭借其卓越的性能和广泛的应用前景&#xff0c;为机械设备产品带…

C++简单缓冲区类设计

目录 1.引言 2.静态缓冲区 3.动态缓冲区 4.数据引用类 5.自动数据引用类 6.几种缓冲区的类关系图 7.注意事项 8.完整代码 1.引言 在C中&#xff0c;设计静态和动态缓冲区类时&#xff0c;需要考虑的主要差异在于内存管理的方式。静态缓冲区类通常使用固定大小的内存区域…

JAVA使用Scanner类的nextLint()方法无法正确读取中文。

在练习的时候&#xff0c;我发现我使用Scanner类的nextLint&#xff08;&#xff09;方法无法正确读取到中文了。检查了我的idea编辑器&#xff0c;用的编码格式也是”utf-8“。所以编码格式没有问题。 问题如下棉两张图所示&#xff0c;我输入宝马后&#xff0c;控制台不打印…

外包干了2年,收获不少。。。

有一种打工人的羡慕&#xff0c;叫做“大厂”。 真是年少不知大厂香&#xff0c;错把青春插稻秧。 但是&#xff0c;在深圳有一群比大厂员工更庞大的群体&#xff0c;他们顶着大厂的“名”&#xff0c;做着大厂的工作&#xff0c;还可以享受大厂的伙食&#xff0c;却没有大厂…

STM32F407单片机编程入门(二十七)以太网接口详解及实战含源码

文章目录 一.概要二.单片机以太网系统基本结构1.OSI 七层模型2.单片机实现以太网功能组成 三.STM32F407VET6单片机以太网内部结构1.MII接口介绍2.RMII接口介绍 四.LWIP TCP/IP协议栈介绍五.PHY收发器LAN8720介绍1.LAN8720内部框图2.LAN8720应用电路3.LAN8720以太网模块 六.Cube…

测试的底层逻辑

写这篇文章&#xff0c;是希望把我的一些我认为是非常有价值的经验总结出来&#xff0c;能够帮助刚做测试不久的新同事&#xff0c;或者是测试经验丰富的老同事以共享。希望我们可爱的新同事&#xff0c;准备要在测试领域耕耘的伙伴&#xff0c;能够通过我的文章了解到测试的底…

【智慧城市】新中地GIS开发实训项目:华农优秀学生学习成果展示(3)智游江城

华农GIS开发实训项目答辩③-智游江城/一个月学习成果展示 项目名称&#xff1a;智游江城 项目功能 主页面展示 菜单功能 控制台 3D城市 查询 导航 游览路线推荐 测量 资讯

Node的安装和配置

1、安装Node 下载nodejs 链接&#xff1a;下载 | Node.js 中文网 官网下载最新版本&#xff1a;https://nodejs.org/en/download/ 一路点击Next&#xff0c;最后Finish。nodejs一般会下载在C盘里。 下载完成后&#xff0c;可以在cmd中查看安装的nodejs和npm版本&#xff0c;…

【C++】红黑树的封装——同时实现map和set

目录 红黑树的完善默认成员函数迭代器的增加 红黑树的封装红黑树模板参数的控制仿函数解决取K问题对Key的非法操作 insert的调整map的[]运算符重载 在list模拟实现一文中&#xff0c;介绍了如何使用同一份代码封装出list的普通迭代器和const迭代器。今天学习STL中两个关联式容器…

lime使用记录

主要是对预测结果进行可解释 import numpy as np import pandas as pd from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_re…

thinkphp6调用微信商户支付-合单支付工具代码开发

合单支付基本在加盟店或是分公司或是营销系统里面常见。他的出现&#xff0c;打破了传统提现支付或是转账支付。他的业务原理其实很简单&#xff0c;就是需要优先申请非普通商户&#xff0c;其次是每个入驻的商户都需要申请普通商户。在这之前一定要申请好对应的场景服务&#…

大学学校用电安全远程监测预警系统

1.概述&#xff1a; 该系统是基于移动互联网、云计算技术&#xff0c;通过物联网传感终端&#xff0c;将办公建筑、学校、医院、工厂、体育场馆、宾馆、福利院等人员密集场所的电气安全数据&#xff0c;实时传输至安全用申管理服务器&#xff0c;为用户提供不间断的数据跟踪&a…

2024年项目经理不能错过的开源项目管理系统大盘点:全面指南

在2024年&#xff0c;随着项目管理领域的不断发展&#xff0c;开源项目管理系统成为了项目经理们提升工作效率的利器。本文将全面盘点几款备受推荐的开源项目管理系统&#xff0c;帮助项目经理们找到最佳选择&#xff0c;不容错过。 在项目管理日益复杂的今天&#xff0c;开源项…