当前位置: 首页 > news >正文

C++学习——编译的过程

编译的过程——预处理

  • 引言
  • 预处理
    • 包含头文件
    • 宏定义指令
    • 条件编译
  • 编译、链接

引言

C++程序编译的过程:预处理 -> 编译(优化、汇编)-> 链接
编译和链接的内容可以查阅这篇文章(点击查看)

预处理

编译预处理是指,对我们写的源代码进行预处理,生成临时文件。
预处理指令主要有以下 三种:

  • 包含头文件:#include
  • 宏定义:#define(定义宏)、#undef(删除宏)
  • 条件编译:#ifdef#ifndef

包含头文件

#include包含头文件有两种方式:

  • #include <文件名>:直接从编译器自带的函数库目录中寻找文件。这种情况用于包含编译器自带的头文件,也叫系统文件
  • #include "文件名":先从自定义的目录中寻找文件,如果找不到,再从编译器自带的函数库目录中寻找。这种情况用于包含程序员自定义的头文件

#include也包含其它的文件,如:.h.cpp或其它的文件。#include包含文件的本质是把需要包含的文件的内容复制进来。

C++98标准后的头文件分为C标准库和C++标准库

  • C的标准库:老版本的有.h后缀;新版本没有.h的后缀,增加了字符c的前缀。例如:老版本是<stdio.h>,新版本是<cstdio>,新老版本库中的内容是一样的。在程序中,不指定std命名空间也能使用库中的内容。
  • C++的标准库:老版本的有.h后缀;新版本没有.h的后缀。例如:老版本是<iostream.h>,新版本是<iostream>,老版本已弃用,只能用新版本。在程序中,必须指定std命名空间才能使用库中的内容。
    注意:用户自定义的头文件还是用.h为后缀。

宏定义指令

  • 无参数的宏:#define 宏名 宏内容
  • 有参数的宏:#define MAX(x,y) ((x)>(y) ? (x) : (y))

编译的时候,编译器把程序中的宏名宏内容替换,是为宏展开(宏替换)
宏可以只有宏名,没有宏内容。
在C++中,内联函数可代替有参数的宏,效果更好。
C++中常用的宏:

  • 当前源代码文件名:__FILE__
  • 当前源代码函数名:__FUNCTION__
  • 当前源代码行号:__LINE__
  • 编译的日期:__DATE__
  • 编译的时间:__TIME__
  • 编译的时间戳:__TIMESTAMP__
  • 当用C++编译程序时,宏__cplusplus就会被定义。
    可以自行打印一下宏的内容,如下:
cout << "__FILE__: " << __FILE__ << endl;
cout << "__FUNCTION__: " << __FUNCTION__ << endl;
cout << "__TIMESTAMP__: " << __TIMESTAMP__ << endl;
cout << "__cplusplus: " << __cplusplus << endl;

条件编译

最常用的两种:#ifdef#ifndef

#ifdef 宏名程序段一
#else程序段二
#endif

含义:如果#ifdef后面的宏名已存在,则使用程序段一,否则使用程序段二。

#ifndef 宏名程序段一
#else程序段二 
#endif

含义:如果#ifndef后面的宏名不存在,则使用程序段一,否则使用序段二。
什么是宏名存在?什么是不存在?
如果用#define定义宏,宏名就存在;没定义宏,宏名就不存在。宏的内容无所谓,只要有名字就行。
ifdefifndefelseendif这些是条件编译语句,与条件判断语句不是一回事。
在C++中,头文件只需要被包含一次就行了。在C/C++中,在使用预编译指令#include的时候,为了防止头文件被重复包含,有两种方式。

  • 方式1:用#ifndef指令。
#ifndef _CAR_#define _CAR_//代码内容。
#endif
  • 方式2:#pragma once指令放在文件的开头
#pargma once
#include <iostream>using namespace std:
...

#ifndef方式受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式有些编译器不支持。
#ifndef可以针对文件中的部分代码;而#pragma once只能针对整个文件。
#ifndef更加灵活,兼容性好;#pragma once操作简单,效率高。

编译、链接

点击查看这篇文章
感谢浏览,一起学习!

http://www.lryc.cn/news/488925.html

相关文章:

  • 当你要改文件 但是原来的文件内容又不能丢失的时候,拷贝一份(备注原来的),然后添加后缀:.bak
  • MATLAB神经网络(五)——R-CNN视觉检测
  • mock.js:定义、应用场景、安装、配置、使用
  • 【GAT】 代码详解 (1) 运行方法【pytorch】可运行版本
  • Transformer中的Self-Attention机制如何自然地适应于目标检测任务
  • 2411rust,1.75.0
  • 远程办公新宠:分享8款知识共享软件
  • 3.9MayBeSomeAssembly
  • i春秋-签到题
  • TypeScript 中扩展现有模块的用法
  • 【报错记录】解决Termux中pulseaudio启动报错,报:E: [pulseaudio] main.c: Daemon startup failed.
  • Java list
  • MAC借助终端上传jar包到云服务器
  • 对原jar包解压后修改原class文件后重新打包为jar
  • YY币支付系统改源码(改良版本)
  • 【Swift】类型标注、类型安全和类型推断
  • 06 —— Webpack优化—压缩过程
  • uniapp页面样式和布局和nvue教程详解
  • 单条推理转批量推理prompt
  • 网络安全审计概述与分类
  • 【已解决】“EndNote could not connect to the online sync service”问题的解决
  • 数据脱敏工具:基于 FFmpeg 的视频批量裁剪
  • Debezium日常分享系列之:Debezium3版本Debezium connector for JDBC
  • 「Mac玩转仓颉内测版24」基础篇4 - 浮点类型详解
  • 【UGUI】Unity 背包系统实现02:道具信息提示与显示
  • 掌握移动端性能测试利器:深入JMeter手机录制功能
  • springboot010大学生入学审核系统的设计与实现(源码+包运行+LW+技术指导)
  • Qt/C++离线地图的加载和交互/可以离线使用/百度和天地图离线/支持手机上运行
  • 从繁琐到优雅:用 PyTorch Lightning 简化深度学习项目开发
  • UE5 第一人称射击项目学习(完结)