深度学习程序的预处理

news2025/1/23 7:01:59

目录

引入

1、预定义符号

 1、为什么oj的编译器是clang和gcc呐?

        1、vs测试

         2、gcc测试

 2、#define

1、#define定义标识符

1、#define的花样使用

2、续行符\的使用

3、预处理文件的内容展示和为什么头文件不能重复包含

4、vs下如何生成预处理后的文件?

5、为什么#define定义的标识符常量后不能跟分号;

2、#define定义宏

1、初次使用

 2、为什么要宏体要加括号()?

 3、#define替换规则

在程序中扩展#define定义符号和宏时,需要涉及几个步骤。

注意

 4、#和##

1、引入1

2、引入2​编辑

3、#详解(解决函数不能打印传值前的变量名称以及引入1具体作用)

 4、##详解

 5、带副作用的宏参数

6、宏和函数的对比

引入:

宏的缺点:

宏厉害的表现

宏和函数的对比图

 7、命名约定

3、undef

4、命令行定义

5、条件编译

常见的条件编译指令

1.if...endif

 2.多个分支的条件编译

3.判断标识符是否被定义

第一种写法(defined()、!defined())

第二种写法(ifdef、ifndef)

 一般条件需要执行的内容不用像if那样加大括号{}。

4.嵌套指令

6、文件包含

防止头文件多次包含的两种方法

1.本地文件包含

2.库文件包含

7、其他预处理指令


引入

预处理是文本操作,博主认为预处理能够省去很多冗余代码,也能够使用标识符常量来更好的表明代码含义,深度学习预处理能够提高代码玩家们的程序设计能力。

         预处理前                                                                                预处理后

 

1、预定义符号

这些预定义符号都是语言内置的

        

 

这些预定义符号可以用来写日志。

 1、为什么oj的编译器是clang和gcc呐?

使用__STDC__来测试编译器是否遵循C标准

vs不遵循,gcc遵循 clang也遵循等等。

        1、vs测试

         2、gcc测试

 

 2、#define

1、#define定义标识符

1、#define的花样使用

语法:
        #define name stuff

例如:

        

#define 定义的内容在编译的预处理阶段会进行文本替换。 

下面的是因为有的语言switch case 不使用break,代码玩家就设计了这种写法,省事了许多。

 

2、续行符\的使用

注意:续行符的后面是不能有其他东西的!

3、预处理文件的内容展示和为什么头文件不能重复包含

前一万多行都是包含的头文件展开

这里的#define定义的标识符常量直接进行了文本替换

所以,尽量避免重复包含相同的头文件,时间和空间都会影响!

4、vs下如何生成预处理后的文件?

使用完成后要把选项改回去,不然还是编译不了,只能编译到预处理后的结果。

预处理后的文件在当前项目的Debug文件中后缀为.i。

5、为什么#define定义的标识符常量后不能跟分号;

 这个虽然没有报错,但是是因为文本替换后return 0前有两个分号,第二个分号是个空语句,所以不起什么作用。

 从上可以看出#define为什么不要加‘;’,存在很大的隐患!

2、#define定义宏

语法:#define 宏名(参数) 宏体

注意:参数的(左括号一定要紧挨着宏名,否则#define SUM (a,b) ((a)+(b))就变成了标识符了。

1、初次使用

上述展示是否有问题呐?向下看解读!

 2、为什么要宏体要加括号()?

 宏替换,不是先计算后替换,而是先替换后计算

上图解析:宏替换X*X   ->    5+1*5+1=11

正确写法:

 因为存在优先级的原因,宏体当中的因子如果是一个整体就要加括号(),外层也要加(),为什么呐?再给大家一个案例:

为什么宏体外还要加大括号?

 

还是优先级的原因导致,正确写法:

 

 3、#define替换规则

在程序中扩展#define定义符号和宏时,需要涉及几个步骤。

1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。

2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。

3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。

注意

1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归(例如SUM自己调用自己,不要把宏和函数混淆)。

2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索(字符串里的内容如果出现标识符常量时不会被替换)。

 4、#和##

1、引入1

        

打印内容是什么?

这个字符串是会合并在一起的。

2、引入2

 这个代码的目的是为了表明函数不能够把变量名打印出来,只能够吧变量值打印出来,x是固定的。

3、#详解(解决函数不能打印传值前的变量名称以及引入1具体作用)

使用 # ,把一个宏参数变成对应的字符串!

这里我使用上述的问题来解释#的厉害!

#n相当于"n",因为宏替换的特性是文本替换,我变量名时,检测参数后,文本会插入到本身位置

print(a)-->printf("the value of""a"" is %d",n);

基于引入1进行的具体实践

如果类型不同需要打印呐?宏替换!字符串合并!

 4、##详解

 在宏体中将相邻的两个符号合并成一个符号

 5、带副作用的宏参数

大家先算一下下列代码m、a、b打印的值

 

 答案解析:后置++是先使用后++,宏替换后,判断5>4?先使用原来的a和b,然后++,此时a是6,b是5,逻辑上该走?a++:这里的a++,先使用,所以返回值是6,然后++。后面的b++没执行,所以最终a加了两次,b加了一次,m = 6,a =7,b = 5

 x+1;//不带副作用
x++;//带有副作用

当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。

所以我们在设计宏的时候要避免带有副作用的宏参数。

6、宏和函数的对比

宏的封装能够大大减少代码量,更加方便。宏处理小程序比函数快和小。

引入:

比如:比较两个数,求最大值。

 从步骤明显看出宏对小程序的easy,并且宏是没有类型检查的,函数有,对于重复操作的逻辑,一个宏就可以搞定不同类型,所以宏比函数在程序的规模和速度方面更胜一筹。

更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反

之这个宏可以适用于整形、长整型、浮点型等可以用于>来比较的类型。宏是类型无关的。

宏的缺点:

当然和函数相比宏也有劣势的地方:
1. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。

2. 宏是没法调试的。

3. 宏由于类型无关,也就不够严谨。

4. 宏可能会带来运算符优先级的问题,导致程容易出现错。

宏厉害的表现

方便、简洁!

宏和函数的对比图

在C++的内联函数是把宏和函数合体了。

 7、命名约定

一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。
那我们平时的一个习惯是:
        把宏名全部大写
        函数名不要全部大写

 

 但并不是全都按照这个规则。例如:ofsetof是个宏,getchar有些实现也是宏

3、undef

这条指令用于移除一个宏定义。
#undef NAME
//如果现存的一个名字需要被重新定义,那么它的旧名字首先要被移除。

4、命令行定义

 在命令行定义一个标识符常量

vs不好演示,这里使用Linux环境演示

 编译错误,缺少SZ,并且for循环里定义int i仅仅在C99标准模式下使用,所以在for循环外定义int i就行了。

 所以直接在命令行添加标识符SZ

编译指令:gcc -D ARRAY_SIZE=10 programe.c

 执行结果展示

 这样就可以在命令行随意设置标识符常量值。

5、条件编译

满足条件就编译,不满足就不编译

常见的条件编译指令

以endif来结束一个条件编译。

1.if...endif

 也能看出来条件为假,VS会将此部分颜色变淡

 2.多个分支的条件编译

#if 常量表达式
//...
#elif 常量表达式
//...
#else
//...
#endif

3.判断标识符是否被定义

第一种写法(defined()、!defined())

#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol
 

 

第二种写法(ifdef、ifndef)

 

 一般条件需要执行的内容不用像if那样加大括号{}。

4.嵌套指令


#if defined(OS_UNIX)
    #ifdef OPTION1
        unix_version_option1();
    #endif
    #ifdef OPTION2
        unix_version_option2();
    #endif
#elif defined(OS_MSDOS)
    #ifdef OPTION2
        msdos_version_option2();
    #endif
#endif

6、文件包含

防止头文件多次包含的两种方法

 

1.本地文件包含

#include "filename"

查找策略:先在源文件所在目录下查找,如果该头文件未找到,编译器就像查找库函数头文件一样在标准位置查找头文件。
如果找不到就提示编译错误。

2.库文件包含

#include <filename.h>

查找头文件直接去标准路径下去查找,如果找不到就提示编译错误。
这样是不是可以说,对于库文件也可以使用 “” 的形式包含?
答案是肯定的,可以。
但是这样做查找的效率就低些,当然这样也不容易区分是库文件还是本地文件了。

7、其他预处理指令

#error
#pragma
#line
...
#pragma pack()在结构体部分介绍。

参考《C语言深度解剖》学习

-------------------------------------------------本章内容完-----------------------------------------------------------------

欢迎大家在评论区留言讨论,补充知识,让内容更加丰富,让细节更加饱满,让知识海洋不断扩大!

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

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

相关文章

高分综述:人类肠道病毒组分类的进展和挑战

期刊&#xff1a;Cell Host Microbe 影响因子&#xff1a;31.316发表时间&#xff1a;2022.7 - 一、摘要 -人类肠道病毒组通常被称为肠道微生物组的“暗物质”&#xff0c;仍未得到充分研究。了解不同人群肠道病毒组的组成和变化对于探索其对人类健康的影响至关重要。人类肠道病…

聊透Spring事件机制

1、概述 事件机制是Spring为企业级开发提供的神兵利器之一&#xff0c;它提供了一种低耦合、无侵入的解决方式。 但其实Spring事件的设计其实并不复杂&#xff0c;它由三部分组成&#xff1a;事件、发布器、监听器。事件是主体&#xff0c;发布器负责发布事件&#xff0c;监听…

Lottie简介 + 结合到vue3中使用

Lottie简介 结合封装到vue3中使用前言&#xff1a;一、Lottie是什么1. 官方介绍2. 实现流程3. 动画资源二、为什么要选择Lottie三、lottie-web的使用1. 安装导入2. 初始化动画实例3. lottie-web支持的控制动画的主要方法4. lottie-web支持的监听动画的常用的事件四、lottie-we…

C++字符编码详解及利用string遍历中文字符串

作者&#xff1a;非妃是公主 专栏&#xff1a;《笔记》《C》 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录C遍历英文字符串C遍历中文字符串&#xff08;不会出问题情况&#xff09;C遍历中文字符串&#xff…

Linux基础——进程的概念和控制(操作系统级讲解)

前言 我们经常会听到一个概念——进程。但是进程并不是一个孤立的概念&#xff0c;需要对操作系统有比较深入的了解。所以这篇博客将在读者的脑中先对操作系统构建一个大概的印象&#xff0c;再对进程做了解。 冯诺依曼结构 冯诺依曼结构也称普林斯顿结构&#xff0c;是一种…

微信小程序|智能停车系统中车牌计费功能实现

&#x1f4cc;个人主页&#xff1a;个人主页 ​&#x1f9c0; 推荐专栏&#xff1a;小程序开发成神之路 --【这是一个为想要入门和进阶小程序开发专门开启的精品专栏&#xff01;从个人到商业的全套开发教程&#xff0c;实打实的干货分享&#xff0c;确定不来看看&#xff1f; …

数据结构基础篇》》约瑟夫环

数据结构开讲啦&#xff01;&#xff01;&#xff01;&#x1f388;&#x1f388;&#x1f388; 本专栏包括&#xff1a; 抽象数据类型线性表及其应用栈和队列及其应用串及其应用数组和广义表树、图及其应用存储管理、查找和排序将从简单的抽象数据类型出发&#xff0c;深入浅出…

python 基础入门

文章目录前言python 基础入门一、python环境如何搭建、开发工具pycharm如何破解01 python下载02 python 安装03 python开发工具安装(pycharm )03::01 安装pycharm03::02 多次试用二、python 常规基础01 python 规范02 python中的关键字03 python缩进04 python注释哈哈哈前言 如…

07-JVM 类加载机制?

1.JVM 类加载机制分为五个部分&#xff1a;加载&#xff0c;验证&#xff0c;准备&#xff0c;解析&#xff0c;初始化。 2.一个类型从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#xff0c;它的整个生命周期将会经历加载&#xff08;Loading、验证&#xff08;V…

分布式版本控制Git

从基本的环境配置与安装到Git的基本操作&#xff0c;轻松应对Git在使用时遇到的常见问题。 https://blog.csdn.net/a18307096730/article/details/124586216?spm1001.2014.3001.550202_版本控制器的方式03_svn(过时)_git04git工作流程简述05git环境配与安装06 获取本地仓库Git…

P3375 【模板】KMP字符串匹配

题目描述 给出两个字符串 s_1s1​ 和 s_2s2​&#xff0c;若 s_1s1​ 的区间 [l, r][l,r] 子串与 s_2s2​ 完全相同&#xff0c;则称 s_2s2​ 在 s_1s1​ 中出现了&#xff0c;其出现位置为 ll。 现在请你求出 s_2s2​ 在 s_1s1​ 中所有出现的位置。 定义一个字符串 ss 的 bor…

概率论【离散型二维变量与连续性二维变量(上)】--猴博士爱讲课

5.离散型二维变量与连续性二维变量&#xff08;上&#xff09; 1/8 已知二维离散型分布律&#xff0c;求??? 离散型直接看表 【做题方法参考如下】 2/8 已知二维离散型分布律&#xff0c;判断独立性 如果满足p(xy) p(x) * p(y)&#xff0c;那么相互独立 则我们只需要验证每…

C 程序设计教程(12)—— C 语言顺序结构程序设计

C 程序设计教程&#xff08;12&#xff09;—— C 语言顺序结构程序设计 该专栏主要介绍 C 语言的基本语法&#xff0c;作为《程序设计语言》课程的课件与参考资料&#xff0c;用于《程序设计语言》课程的教学&#xff0c;供入门级用户阅读。 目录C 程序设计教程&#xff08;1…

深入探索Flutter性能优化

前言 Flutter 作为目前最火爆的移动端跨平台框架&#xff0c;能够帮助开发者通过一套代码库高效地构建多平台的精美应用&#xff0c;并支持移动、Web、桌面和嵌入式平台。对于 Android 来说&#xff0c;Flutter 能够创作媲美原生的高性能应用&#xff0c;但是&#xff0c;在较…

【nvivo11plus教程】02_编码与节点

1、对文档进行编码(1)建立节点(2)使用快速编码栏进行编码(3)将整个文件编码为一个代码(4)范围编码(5)在vivo中编码(6)使用节点昵称加快编码速度2、取消、增加和查看编码(1)编码带(2)删除编码(3)查看编码邻近区(4)增加编码(5)查看编码信息3、组织节点(1)节点结构化(2)移动归类节…

leetcode-每日一题-还原排列的最少操作步数(中等,数学逻辑)

回家了很少看了&#xff0c;今天突然心血来潮做了今天的每日一题&#xff0c;还不错&#xff0c;最后是一次AC&#xff0c;说明这么长时间没看实力没有下降多少&#xff0c;哈哈哈哈&#xff0c;自恋一下&#xff0c;后面我会更新一些课设和实验作业&#xff0c;进入正题。给你…

密码学_ECC椭圆曲线加密算法

算法介绍 椭圆加密算法&#xff08;ECC&#xff09;是一种公钥加密体制&#xff0c;最初由Koblitz和Miller两人于1985年提出&#xff0c;其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类&#xff1a…

【jQuery】常用API——jQuery样式操作

一、操作 css 方法 jQuery 可以使用 css 方法来修改简单元素样式。1. 参数只写属性名&#xff0c;则是返回属性值$(this).css(color);2. 参数是属性名&#xff0c;属性值&#xff0c;逗号分隔&#xff0c;是设置一组样式&#xff0c;属性必须加引号&#xff0c;值如果是数字可以…

Go基础学习

文章目录回看下历史环境安装和开发工具&#xff1a;基础语法&#xff1a;go的注释&#xff1a;变量定义&#xff1a;简短定义模式Go的变量交换匿名变量&#xff08;空白标识符&#xff09;&#xff1a;变量的作用域&#xff1a;iota常量计数器数据类型布尔类型数值型整数浮点数…

新冠COVIN-19流感病患轨迹追溯

实验背景 冬季是流感的高发季节&#xff0c;现已知某流感病毒的传播力很强&#xff0c;政府部门也陆续公开了部分流感确诊患者&#xff08;后续简称“病患”&#xff09;的非隐私信息&#xff0c;这部分数据为相关研究人员研究该流感病毒的传播与防控提供了重要的数据支撑。 然…