-
编译器和预处理器
2013-04-09 08:36:14编译器 就是把源代码翻译成目标代码的工具,目标代码可以是机器码,也可以是其他代码 预处理器 就是在代码交给编译器处理前,预先进行一些处理,比如包含头文件,宏展开等等编译器
就是把源代码翻译成目标代码的工具,目标代码可以是机器码,也可以是其他代码
预处理器
就是在代码交给编译器处理前,预先进行一些处理,比如包含头文件,宏展开等等
-
C++ 编译器和预处理器定义的可以显示源代码信息的变量
2021-02-19 11:28:45预处理器定义了用于调试的名字: __FILE__//存放文件名的字符串字面量 __LINE__//存放当前行号的整型字面值 __TIME__//存放文件编译时间的字符串字面值 __DATE__//存放文件编译日期的字符串字面值 ...编译器为每个函数定义了
__func__
来显示函数的名字
预处理器定义了用于调试的名字:__FILE__//存放文件名的字符串字面量
__LINE__//存放当前行号的整型字面值
__TIME__//存放文件编译时间的字符串字面值
__DATE__//存放文件编译日期的字符串字面值
-
尽量以const、enum、inline替换#define(编译器替换预处理器)
2018-04-24 15:55:08一、中心内容:1、对于单纯常量,最好以const对象或enums替换#defines...二、简述(1)const和#definee.g #define ASPECT_RATIO 1.653; 改为 const double AspectRatio = 1.653;//大写名称通常用于宏1、前者的ASPEC...一、中心内容:
1、对于单纯常量,最好以const对象或enums替换#defines;
2、对于形似函数的宏,最好改用inline函数替换#define。
二、简述
(1)const和#define
e.g
#define ASPECT_RATIO 1.653; 改为
const double AspectRatio = 1.653;//大写名称通常用于宏
1、前者的ASPECT_RATIO符号可能在开始处理源码前就被预处理器移走了,而没有进入记号表;
2、后者const是一个语言常量,绝对会进入符号表
3、两种特殊情况:
1)定义常量指针(常放在头文件中)
必须写两次const:
const char* const authorName = "Scott Meyers"; 改为
const std::string authorName("Scott Meyers");//string对象更合时宜
2)class专属常量
为了将常量的作用域限制于class内,必须成为class的一个成员;
为确保只有一个实体,必须使他成为class的一个static成员。
class GamePlayer{
private:
static const int NumTurns = 5;
...
}
note:
由于C++要求所使用的任何东西都得提供一个定义式,而上述只是声明,so:
const int GamePlayer::NumTurns;//由于声明是已经提供了初值,所以不再赋值。
另外,由于#define并不重视作用域,一旦定义,之后编译中均有效,所以其不能用来定义class专属常量,也不能提供任何诸如 private #define 之类的封装特性。
通常情况下,不允许static成员在声明式子上获得初值(除了整数常量),这时候常常放在定义式中。
(3)#define和enum
特殊情况,当class编译期间需要一个class的常量值,例如定义一个数组必须知道其数组的大小时,但编译器又不允许完成“in_class初值设定”,可以改用enum。
即:
class GamePlayer{
private:
enum{ NumTurns = 5};
int scores[Numeturns];
...
};
用enum的理由如下:
1)在某方面来说等价于#define:
例如:取一个const的地址是合法的但是取一个enum和define的 地址是不合法的,这就可以避免别的用户获得一个指针/引用指向你定义的整数常量;
2)enum或define在所有编译器中可以避免非必要的内存分配,即分配内存。
(3)#define和inline
有时候为避免额外开销,将短小、简单的函数定义成宏,如:
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b));
形如这种形式的宏有许多的缺点:
e.g
int a = 5, b = o;
CALL_WITH_MAX(++a, b) ;//会导致a累加两次
CALL_WITH_MAX(++a, b+10); //导致a累加一次
即,a的递增次数取决与其的比较对象的大小。
为避免这种情况的发生,可以用template inline函数来代替:
template <typname T>
inline void callWithMax(const T& a, const T& b)
{
f(a>b ? a:b);
}
note:
遵守作用域和访问规则。
-
Effective c++学习笔记——用 const 和 inline 语句 代替 #define预处理命令( 尽量用 编译器 替代预处理器 ...
2018-05-26 13:37:25这是由于#define由预处理器替换成 666666, 所以编译器只知道 666666, 而不知道 max 你会很懵逼。 你要一个个去 “aa.h"这个头文件中去找??? too young too simple 解决方法; 用const代替 #define, 这个操作...使用 #define 的缺点:
你的工程组成员,定义了一个文件
“aa.h”
#define max 666666
你包含了这个头文件
#include <iostream> #include "aa.cpp" int main() { 。。。。。。 }
这时候你的程序运行出错了, 抛出了一个 666666 处的错误。 why?这是由于#define由预处理器替换成 666666, 所以编译器只知道 666666, 而不知道 max
你会很懵逼。 你要一个个去 “aa.h"这个头文件中去找??? too young too simple
解决方法;
用const代替 #define, 这个操作由编译器执行( 作为一个语言常量,max肯定会被编译器获知,并且进入记号表内), 所以不会出现报 666666 这种错误,而会直接抛出变量名 的错误。 以便于定位错误
const auto max = 666666;
使用列表初始化初始化成员变量(注意赋值与初始化的区别)
c++规定, 成员变量的初始化在进入 构造函数 之前!!
所以 如果写成这样, 会执行两步操作 :
1. 先给 start, finish, end_of_stroge 初始化 //成员变量在进入构造函数之前进行了 初始化操作
2. 再给 这三个变量赋值 //赋值为先擦掉变量的值,再给其构造一个值。 而初始化只是在什么也没有的内存上构造一个新值
vector() { start = nullptr; finish = nullptr; end_of_stroge = nullptr; }
如果用 列表初始化
只会进行一步操作: 赋值
vector():start(nullptr), fininsh(nullptr), end_of_stroge(nullptr) { }
再进入构造函数 { } 之前, 已经为成员变量完成了初始化。
结论: 用列表初始化的效率要高的多, 而且对于 const 变量, 先赋值后就不能再进行初始化了!!!
-
KEIL编译器预处理器和预定义宏(include,ifdef,def等)
2020-03-08 21:01:59Keil使用的C编译器支持常用的编译器预定义宏和对文件...首先,我们了解一下何为预定义宏和预处理器以及他们起什么作用 预定义宏:ARM编译器预定义了很多宏,这些宏提供了工具链版本号和编译器选项的相关信息。 预处... -
Scheme 编译器--预处理器制作 (一) 去掉注释 及 实现单宏
2015-04-08 20:34:33预处理器做了一半大概 把;单行注释 和#! !#多行注释 在ClearRemark中实现 然后在PreProduce中处理宏,由于scheme的宏支持多态,和递归,我暂时只做了单宏 宏储存在map中,内容是一个结构 中一个链表作为 参数的... -
1.预处理器,编译器,汇编器和链接器
2016-06-11 19:03:001.预处理器,编译器,汇编器和链接器 (1).预处理(cpp):预处理器不止一种,而C/C++的预处理器就是其中最低端的一种——词法预处理器,主要是进行文本替换、宏展开、删除注释这类简单工作。 gcc -E 选项... -
预处理器,编译器,汇编器和链接器
2015-04-11 11:26:11预处理(cpp):预处理器不止一种,而C/C++的预处理器就是其中最低端的一种——词法预处理器,主要是进行文本替换、宏展开、删除注释这类简单工作。 gcc -E 选项可以得到预处理后的结果,扩展名为.i;C/C++预处理不... -
AIX性能——预处理器和编译器利用
2010-06-27 20:37:58预处理器可以通过重新整理一些源代码结构来形成一个功能上相当的源模块,该模块可以编译成更有效率的可执行代码。 正如存在一些体系结构变量一样,存在一些编译器选项允行对特殊变量或变量集合进行最优编译。 ... -
Surelog:SystemVerilog 2017预处理器,解析器,详细说明,UHDM编译器。 提供IEEE DesignTB CC ++ VPI和...
2021-02-24 12:19:22SystemVerilog 2017预处理器,解析器,UHDM编译器。 提供IEEE Design / TB VPI和Python AST API。 目标 该项目旨在提供完整的SystemVerilog 2017前端:预处理器,解析器,设计和测试平台的详细说明。 应用领域 ... -
预处理器,编译器,汇编器,连接器的概念和区别
2019-02-14 16:14:21好记性不如烂笔头,所以准备详细的记录一下这几个东西的功能和区别,有例子为证。 参考博客:https://www.cnblogs.com/hutao886/p/5614296.html hello程序的生命周期是从一个源程序(hello.c)(称为高级c语言)... -
预处理器
2014-11-06 17:31:15#include 设施是C++预处理器的一部分,预处理器处理程序的源代码,在编译器之前进行。预处理器用指定的头文件内容代替每个#include。 无论头文件以何种格式保存,一般都含有支持分别编译所需的类定义及变量和函数的... -
预处理器指令
2020-03-15 16:54:42文章目录预处理器文件包含指令#include宏定义指令#define 和#undef逻辑条件判断指令#if和#elsec++中的预定义宏参考资料 预处理器是编译器在把程序编译成机器指令之前,进行的一系列操作。记住,预处理器不同于编译... -
C_预处理器和C库
2020-07-24 20:09:363) 预处理器可以包含程序所需的其他文件,可以选择让编译器查看哪些代码 1.预处理之前 在预处理之前,编译器必须对该程序进行一些翻译处理 1.首先,编译器把源代码中出现的字符映射到源字符集 2.编... -
C预处理器和C库
2016-07-04 16:49:15编译程序之前,先由预处理器检查程序(因此称为预处理器)。...预处理器可以根据您的请求包含其他文件,还可以选择让编译器处理哪些代码。预处理器不能理解C,它一般是接受一些文本并将其转换为其他文本。 -
C# 预处理器指令
2020-11-24 08:10:01预处理器指令指导编译器在实际编译开始之前对信息进行预处理。 所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。 C# ... -
SASS 预处理器
2020-05-31 22:16:19使用预处理器,会很大程度上降低我们的代码编写量,浏览器的兼容性问题是一直存在的,通常我们会采用css重置技术和加前缀这两种方式,为了解决浏览器兼容性问题,一般我们会写很多行相同的代码,而预处理器就很好的... -
c语言预处理器
2016-10-27 10:55:10预处理器是一个小软件,它可以在编译前处理c程序,和其他语言不同,c和c++语言十分依赖预处理器,现在一般和编译器集成在一起。 预处理器的优缺点 预处理器是一种强大的程序处理工具,但预处理经常导致一些难以发现... -
C语言回炉之预处理器
2018-12-19 14:46:24C语言回炉之预处理器C 预处理器includedefine用#define实现求最大值和最小值的宏宏参数的连接用宏得到一个字的高位或低位的字节用宏定义得到一个数组所含元素的个数ifdef 和 ifndefiferrorextern "C"... -
宏和预处理器
2013-10-31 11:53:041、头文件中的 ifndef/...2、#include 和 #include “filename.h” 有什么区别?(5分) 答:对于#include ,编译器从标准库路径开始搜索 filename.h 对于#include “filename.h” ,编译器从用户的工作路径 -
虚幻脚本预处理器
2013-12-28 18:49:58转自官网 虚幻脚本预处理器 (UPP) 概述基础作用范围使用宏宏参数内置宏 ... / else / endifincludeisdefinedundefinelog ...在虚幻引擎 3 中,虚幻脚本编译器...预处理器的工作方式和 C++ 的预处理器类似,它支持通