c 语言里关 于预处理的知识,C 语言中的预处理

C 语言中以 # 开头的就是预处理指令,例如 #include 。

预处理指令的用途

所有的预处理指令都会在 GCC 编译过程的预处理步骤解析执行,替换为对应的内容。在下一步编译过程中,看不到任何预处理信息,只需要对独立的程序文件进行操作即可。

预处理指令的类型

包含类 #include 头文件

通过 #include 引入的头文件,会在 GCC 编译过程中的预处理步骤进行展开,替换为完整的头文件内容。

宏定义类 #define 宏名 宏体

定义的宏在预处理时不进行语法检查,原样替换。等到编译的时候再进行语法检查。宏体如果有多个组成部分时,通常要加括号,防止发生优先级的问题。

宏变量:支持表达式。例如 #define MY_VAR 3+4,使用的时候如果是这样 int i = MY_VAR * 5,会在预处理时替换为 int i = 3+4 * 5,最终得到的 i 是23。而 #define MY_VAR (3+4)则无次问题

宏函数:可以将定义的宏当做函数处理。例如 #define MY_FUN(x) (3+x),使用 int i = MY_FUN(4)*5 得到的 i 是 35。

条件编译 #ifdef #ifndef #else #endif

预定义宏:全部以两个下划线开始和结束,方便调试

FILE:文件名

FUNCTION:函数名

LINE:行号,数值

DATE:编译的日期

TIME:编译的时刻

例如,对于这个 C 文件:

#include

int main()

{

printf("file is:%s, function is:%s, line is:%d, %s, %s", __FILE__, __FUNCTION__, __LINE__, __DATE__, __TIME__);

}

执行结果如下:

file is:define.c, function is:main, line is:5, Jan 19 2019, 15:10:57

宏定义

预处理时,会把所有出现宏名的地方自动替换为对应的宏值。

#define 宏名 宏值

宏定义的规则:

宏值中可以有其他宏的名字,预处理时也会被替换,例如:

#define PI 3.14

#define PI2 PI * 2

宏值超过一行时,可以用 \ 换行,例如:

#define PRT printf("%f ", PI); \

printf("%f", PI2)

如果不需要宏值,可以定义无值的宏:

#define DEBUG

预定义宏可以在任何地方直接使用。

宏定义结尾不能加分号 ;,否则会被替换导致异常。

综合示例:

#include

#define PI 3.14

#define PI2 PI*2

#define PRT printf("%f ", PI); \

printf("%f\n", PI2)

#define MIN(a, b) ((a) < (b) ? (a) : (b))

int main()

{

PRT;

printf("%d", MIN(2+3*5, 666));

}

有参数的宏

可以带一个或多个参数。有参数的宏的原则是:

一切地方都有加括号,放在因为运算的优先级导致异常

整个宏值要加括号

每个参数都有加括号

#include

#define MIN(a, b) ((a) < (b) ? (a) : (b))

#define FUN1(a) (a * 5)

#define FUN2(a) (a) * 5

int main()

{

printf("%d\n", MIN(2+3*5, 666));

printf("%d\n", FUN1(5 + 6));//5 + 6 * 5 = 35

printf("%d\n", 100 / FUN2(5));//100 / 5 * 5 = 100

}

宏定义的优缺点

优点:有参数的宏定义比函数速度快,无参数的宏定义可以在C语言的各个版本中使用。

缺点:无法进行参数类型的检查,可能编译通过但运行时报错。

可以使用 inline 内联函数替代有参数的宏定义,速度快的同时还可以检查参数类型。

对于 C99 之后的版本,可以使用常量定义来代替无参数的宏定义:

const double PI 3.14;

条件预处理

通过条件预处理指令,可以在预处理阶段控制要编译的代码,从而实现条件预编译。对编译器来说这个步骤是透明的,它只需要编译所有它看见的代码即可。例如:

#include

#define DEBUG

int main()

{

#ifdef DEBUG

printf("debug info");// 只有定义了 DEBUG,才会执行这段代码

#endif

printf("hello world\n");

return 0;

}

当然,在文件中直接定义宏的话,每次都有修改源文件,不灵活。GCC 提供了一个指定宏定义的选项 gcc -D,例如 gcc -DDEBUG -o build 1.c 会自动在代码中添加一段定义 DEBUG 的指令 #define DEBUG,这样就可以在上面的源代码中删除 #define DEBUG 这一行了。

预处理中 # 和 ## 的区别

在宏体中(宏名中不可以使用)可以使用一个或两个 # 作为前缀。

#:字符串化,如果需要向宏方法中传字符串参数时可以使用

##:连接符号,用于连接字符串和变量

示例:

#include

#define MY1(x) #x//传入的参数转为字符串

#define MY2(x) day##x //传入的参数自动拼接到 day 后面,例如出入1时为 day1

int main()

{

int day1 = 666;

printf(MY1(abc\n)); // 打印 abc 字符串后换行

printf("%d", MY2(1));// 打印 666,即变量 day1

}

C语言中的预处理命令

预处理功能是C语言的重要功能. 问:为什么要预处理,什么是预处理? 答:我们知道高级语言的运行过程是通过编译程序(编译器)把源代码翻译成机器语言,实现运行的.编译程序的工作包含:语法分析.词法分析.代 ...

C语言中 &ast;&period;c和&ast;&period;h文件的区别!

C语言中 *.c和*.h文件的区别!  http://blog.163.com/jiaoruijun07@126/blog/static/68943278201042064246409/        ...

C语言中的命名空间

C语言中的命名空间 命名空间是为了解决 "在相同作用域内如何区分 相同的标识符". 说明: ①只有在相同作用域的情况下才能使用到命名空间去区分标识符,在嵌套的作用域.不同的作用域区 ...

C语言中的宏定义

目录(?)[-] 简单宏定义 带参数的宏 运算符 运算符 宏的通用属性 宏定义中圆括号 创建较长的宏 较长的宏中的逗号运算符 宏定义中的do-while循环do 空操作的定义 预定义宏 C语言中常用的 ...

C C语言中关键词,以及知识点复习

C语言学习 C语言练习知识点 auto        局部变量(自动储存) break       无条件退出程序最内层循环 case        switch语句中选择项 char         ...

c语言中条件编译相关的预编译指令

一. 内容概述 本文主要介绍c语言中条件编译相关的预编译指令,包括#define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. 二.条件编 ...

C语言中变量名及函数名的命名规则与驼峰命名法

一.C语言变量名的命名规则:(可以字母,数字,下划线混合使用) 1. 只能以字母或下划线开始:2. 不能以数字开始:3. 一般小写:4. 关键字不允许用(eg:int float=2//error  ...

c语言中会遇到的面试题

预处理器(Preprocessor) 1 . 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)         #define SECONDS_PER_YEAR (60 ...

C语言中一些术语的梳理&lowbar;持续更新

关键字.标识符.宏.预定义.预处理.编译.替换.预处理指令. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 标识符: ...

随机推荐

JS 预解释相关理解

1.JS中的内存空间分为两种:栈内存.堆内存 栈内存:提供JS代码执行的环境;存储基本数据类型的值; ->全局作用域或者私有的作用域其实都是栈内存 堆内存:存储引用数据类型的值(对象是把属性名和 ...

AMD and CMD are dead之KMDjs在JS工程化的努力

总览 kmdjs发布了最接近最终版本的0.0.4版本https://github.com/kmdjs/kmdjs,你已经完全可以在项目中使用.我已经无法用语言形容其完美程度.借用我发的微博:   模块 ...

jquery选择器案例

一.预期效果 实现一个效果,如下. 品牌列表默认精简显示,单击“显示全部品牌”按钮显示全部品牌,同时列表将推荐的品牌的名字高亮显示,按钮里的文字变成“精简显示品牌”.再次点击“精简显示品牌”回到初始页 ...

用HTML5构建一个流程图绘制工具

在我们的开发工程中经常会使用到各种图,所谓的图就是由节点和节点之间的连接所形成的系统,数学上专门有一个分支叫图论(Graph Theroy).利用图我们可以做很多工具,比如思维导图,流程图,状态机,组 ...

git -分支管理(创建、推送、删除)

分支创建并推送: 1.查看当前所有分支,当前分支前面会标出一个*号 git branch -a 2.新建分支 git branch android_O 3.切换到新分支 git checkout an ...

一个简单的加载动画,js实现

简单效果图: html:

  • CentOS7安装OpenStack&lpar;Rocky版&rpar;-01&period;控制节点的系统环境准备

    分享一下Rocky版本的OpenStack安装管理经验: OpenStack每半年左右更新一版,目前是版本是201808月发布的版本-R版(Rocky),目前版本安装方法优化较好,不过依然是比较复杂 ...

    hdoj2612 Find a way &lpar;bfs&rpar;

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2612 思路: 这个题我wa了十多发QAQ. 刚开始的思路是搜索每个‘@’,然后广搜该点到Y和M的最小距 ...

    Android 数据加密算法 Des&comma;Base64详解

    一,DES加密: 首先网上搜索了一个DES加密算法工具类: import java.security.*;import javax.crypto.*; public class DesHelper { ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!针对2023全国大学生数学建模比赛的C题数据预处理,我可以为你提供一些常见的方法和步骤。请注意,以下是一般性的建议,具体处理方式可能需要根据数据的具体特点和要求进行调整。 1. 数据导入:将原始数据导入到一个适合的数据分析环境,例如Python的pandas库或者R语言。确保数据的格式正确,并对缺失值进行处理。 2. 数据清洗:删除不需要的列或者行,根据任务需求进行筛选和过滤。如果有重复数据,则进行去重操作。 3. 数据转换:将需要处理的数据进行转换,例如将文本型数据转换为数值型数据,或者进行单位转换等。 4. 缺失值处理:对于存在缺失值的数据,可以选择删除含有缺失值的行或者列,或者使用插补方法填充缺失值。 5. 异常值处理:检查数据是否存在异常值,如极大值、极小值或者超出合理范围的数值。可以选择删除异常值或者通过插补等方法进行处理。 6. 数据归一化:对于不同量纲的数据,可以进行归一化处理,使得不同特征具有可比性。 7. 特征工程:根据问题需求和业务背景,对原始数据进行特征构建和选择,可以使用统计学方法、数据挖掘技术或者领域知识。 8. 数据可视化:通过绘制图表,对数据进行可视化分析,探索数据的分布、变化趋势和相关关系。这有助于进一步理解数据。 9. 数据分割:根据建模需求,将数据集划分为训练集、验证集和测试集等,以便进行模型训练和评估。 以上是一般性的数据预处理步骤,具体实施时需要根据具体情况进行调整和选择。希望对你有所帮助!如果你有更具体的问题或者需要进一步的指导,请告诉我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值