一篇学会c语言预处理命令

C语言预处理器

在C语言中,预处理器是一个执行文本替换的程序。在编译器编译代码之前,预处理器会处理代码中的预处理指令,并将其替换为预处理器指定的文本。预处理器指令以“#”开头,不以“;”结尾。

以下是C语言中的全部预处理器指令:

  1. #define:用于定义宏。可以定义函数宏和对象宏。
  2. #include:用于包含头文件。
  3. #undef:用于取消宏定义。
  4. #ifdef:用于判断某个宏是否已经定义。
  5. #ifndef:用于判断某个宏是否未定义。
  6. #endif:用于结束#ifdef#ifndef的条件编译。
  7. #if:用于条件编译。
  8. #else:用于在#if条件不成立时执行另外的操作。
  9. #elif:用于在#if条件不成立时,继续判断另外的条件是否成立。
  10. #line:用于指定编译器输出错误信息时所显示的行号和文件名。
  11. #error:用于在编译时输出错误信息并终止编译过程。
  12. #pragma:用于向编译器发送特定的指令或信息

以下是一些预处理命令的实际应用。

#define

定义一个宏:

#define PI 3.1415926

#include

包含一个头文件:

#include <stdio.h>

#ifdef#ifndef

#ifndef PI
#define PI 3.1415926
#endif

#if#else

#if DEBUG == 1
    printf("Debug mode enabled.\\n");
#else
    printf("Debug mode disabled.\\n");
#endif

#error

#ifdef MAX_SIZE
    #error "MAX_SIZE already defined"
#else
    #define MAX_SIZE 100
#endif

#pragma

#pragma once

预定义宏是指由编译器预先定义的宏。这些宏的名称都以双下划线开头和结尾。以下是一些常见的预定义宏:

  • __FILE__:表示当前源代码文件的文件名。
  • __LINE__:表示当前代码行号。
  • __DATE__:表示当前编译日期的字符串。
  • __TIME__:表示当前编译时间的字符串。
  • __STDC__:如果编译器遵循 ANSI 标准,则此宏被定义为 1。

例如,以下代码使用预定义宏 __FILE____LINE__ 来输出代码所在的文件名和行号:

printf("This code is in %s on line %d\\n", __FILE__, __LINE__);

除了预定义宏,我们还可以使用 #define 来定义自己的宏。例如:

#define MAX(a, b) ((a) > (b) ? (a) : (b))

这个宏可以用来求两个数的最大值,例如:

int x = 10;
int y = 20;
int z = MAX(x, y); // z = 20

注意,定义宏时需要注意宏的作用域和值的计算顺序,以避免出现意外的错误。

以下是C语言中的预处理运算符:

  1. #:用于将宏参数转换为字符串。
  2. ##:用于将两个宏参数进行连接。
  3. defined:用于判断某个宏是否已经定义。

以下是一些预处理命令的实际应用。

#

#define PRINT_VAR(x) printf(#x "=%d\\\\n", x)
int main() {
    int a = 10;
    PRINT_VAR(a);
    return 0;
}

##

#define CONCAT(a, b) a##b
int main() {
    int xy = 100;
    int result = CONCAT(x, y);
    printf("%d\\\\n", result); // 输出 100
    return 0;
}

defined

#ifdef DEBUG
    // 调试模式下的代码
#else
    // 正常模式下的代码
#endif

#ifndef DEBUG
    // 非调试模式下的代码
#endif

#if defined(DEBUG) && DEBUG == 1
    // DEBUG 宏已定义且值为 1 的代码
#endif

C语言中的预处理运算符还包括延续运算符,用于将一行代码延续到下一行。延续运算符是反斜杠(\),将其放在行末即可将该行代码延续到下一行。例如:

printf("Hello, "
       "world!\\\\n");

上面的代码实际上是两行代码,但由于使用了延续运算符,它们被视为一行代码。这种技巧在需要写较长的字符串时很有用。

注意,延续运算符只能出现在字符串常量或注释中,不能出现在代码中。否则会导致编译错误。

int a = 1 + \\
        2; // 正确
int b = 1 \\ // 错误
        + 2;

延续运算符还可以与预处理指令一起使用,例如:

#define LONG_MACRO \\
    do { \\
        printf("Hello, world!\\\\n"); \\
    } while (0)

上面的代码定义了一个较长的宏,使用延续运算符将其分成了多行,使代码更加易读。

在C语言中,我们可以使用参数化的宏来定义更加灵活的宏。参数化的宏可以接受一个或多个参数,并根据参数生成相应的代码。例如,下面的代码定义了一个参数化的宏:

#define SQUARE(x) ((x) * (x))

这个宏可以用来求一个数的平方,例如:

int x = 5;
int y = SQUARE(x); // y = 25

注意,参数化的宏在使用时需要小心。由于宏是在编译时进行文本替换的,因此在宏中使用参数时需要使用括号将参数括起来,以避免优先级错误。例如,下面的代码是错误的:

#define SQUARE(x) x * x
int x = 5;
int y = SQUARE(2 + 3); // 错误:y = 11 而不是 25

正确的写法应该是:

#define SQUARE(x) ((x) * (x))
int x = 5;
int y = SQUARE(2 + 3); // 正确:y = 25

除了参数化的宏,我们还可以使用 #undef 来取消宏定义。例如:

#define PI 3.1415926
#undef PI

这个代码片段定义了一个宏 PI,并在定义后立即取消了它的定义。在取消宏定义之后,我们就不能再使用 PI 这个宏了。

需要注意的是,取消宏定义只能取消已经定义的宏,不能取消未定义的宏。另外,取消宏定义并不会删除宏在代码中已经替换的部分,它只会影响后续代码中对该宏的使用。

以上是C语言预处理器的相关内容,希望对您有所帮助!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[蓝桥杯单片机]——八到十一届初赛决赛客观题

第八届初赛 一、填空题 采用外部12MHz晶振&#xff0c;经过系统12分频时定时器获得最大定时长度&#xff0c;此时定时器定时脉冲为1MHz&#xff0c;周期为1s&#xff0c;而定时器计时均为16位加法计数器&#xff0c;即计时长度为。 二、 选择题 ①带阻滤波器是指能通过大多数频…

处理窄区路径规划的业务问题

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、通过栅格地图的处理解决二、使用bug绕障的方式走出窄区&#xff0c;或者结合边界图形参考bug算法沿边出来三、使用维诺图计…

字符串函数和内存函数

&#x1f355;博客主页&#xff1a;️自信不孤单 &#x1f36c;文章专栏&#xff1a;C语言 &#x1f35a;代码仓库&#xff1a;破浪晓梦 &#x1f36d;欢迎关注&#xff1a;欢迎大家点赞收藏关注 字符串函数和内存函数 文章目录字符串函数和内存函数前言1. 字符串函数介绍1.1 s…

【MySQL】MySQL的优化(一)

目录 查看SQL执行频率 定位低效率执行SQL 定位低效率执行SQL-慢查询日志 定位低效率执行SQL-show processlist 查看SQL执行频率 MySQL 客户端连接成功后&#xff0c;通过 show [session|global] status 命令可以查看服务器状态信息。通 过查看状态信息可以查看对当…

jvm类与类加载

1.类加载过程&#xff1a; 首先要加载某个类一定是出于某种目的&#xff0c;比如要运行java程序&#xff0c;那么久必须加载主类才能运行其中的方法&#xff0c;所以一般在这些情况下&#xff0c;如果类没有被加载&#xff0c;就会自动被加载&#xff1a; 1.使用new创建对象时 …

MyBatis开发环境搭建

1.创建工程 2.引入相关的依赖 pom.xml <dependencies><!--1.引入mybatis包--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><!--2.单元…

FPGA和IC设计怎么选?哪个发展更好?

很多人纠结FPGA和IC设计怎么选&#xff0c;其实往小了说&#xff0c;要看你选择的具体是哪个方向岗位。往大了说&#xff0c;将来你要是走更远&#xff0c;要成为大佬&#xff0c;那基本各个方向的都要有涉及的。 不同方向就有不同的发展&#xff0c;目前在薪资上IC设计要比FP…

Qt之高仿QQ系统设置界面

QQ或360安全卫士的设置界面都是非常有特点的,所有的配置项都在一个垂直的ScrollArea中,但是又能通过左侧的导航栏点击定位。这样做的好处是既方便查看指定配置项,又方便查看所有配置项。 一.效果 下面左边是当前最新版QQ的系统设置界面,右边是我的高仿版本,几乎一毛一样…

【Linux】进程的程序替换

文章目录1. 程序替换1.创建子进程的目的是什么&#xff1f;2.了解程序是如何进行替换的3. 程序替换的基本原理当创建进程的时候&#xff0c;先有进程数据结构&#xff0c;还是先加载代码和数据&#xff1f;程序替换是整体替换&#xff0c;不是局部替换execl 返回值4. 替换函数1…

【三维几何学习】从零开始网格上的深度学习-2:卷积网络CNN篇(Pytorch)

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 从零开始网格上的深度学习-2:卷积网络CNN篇引言一、概述1.1 卷积操作简述1.2 网格上的面卷积二、核心代码2.1 面卷积2.2 网络框架三、基于CNN的网格分类3.1 分类结果3.2 全部代码引言…

FPGA之时钟规划图解

目录 一、前言 二、时钟规划概念 三、时钟规划的模块 四、时钟规划之时钟单元布局 4.1 BUFG 4.2 BUFH 4.3 BUFR 4.4 BUFIO 五、时钟规划之时钟单元走线 5.1 BUFG->BUFH 5.2 BUFR->FF 5.3 BUFIO->FF 一、前言 对于vivado这类使用verilog语言的进…

《Netty》从零开始学netty源码(七)之NioEventLoop.selectStrategy

NioEventLoop是一个事件轮询器&#xff0c;在它的run方法中其实是一个for死循环&#xff0c;不断重复三个过程&#xff1a;1. 获取IO事件&#xff0c;2. 处理IO事件&#xff0c;3. 处理任务队列中的task&#xff0c;而SelectStractegy就是用于第一步获取IO事件&#xff0c;它的…

css:使用filter和backdrop-filter实现高斯模糊效果

背景 今天接到一个需求是&#xff0c;使用高斯模糊的效果对一个页面进行模糊处理&#xff0c;正好借这个机会来整理一下 css3 中高斯模糊的两个 API API介绍 filter 说明&#xff1a; 该 API 是一个过滤器&#xff0c;不仅能实现高斯模糊&#xff0c;还有很多比如颜色偏移、…

接口文档包含哪些内容?怎么才能写好接口文档?十年测试老司机来告诉你

目录 接口文档结构 参数说明 示例 错误码说明 语言基调通俗易懂 及时更新与维护 总结 那么我们该如何写好一份优秀的接口文档呢&#xff1f; 接口文档结构 首先我们要知道文档结构是什么样子的。接口文档应该有清晰明确的结构&#xff0c;以便开发人员能快速定位自己需…

经典文献阅读之--Dynamic-VINS(动态点滤除VINS)

0. 简介 现在的SLAM算法在静态环境中表现良好&#xff0c;但在动态环境中很容易失败。最近的工作将基于深度学习的语义信息引入到SLAM系统以减轻动态对象的影响。然而&#xff0c;在资源受限的机器人的动态环境中应用鲁棒定位仍然具有挑战性。所以《RGB-D Inertial Odometry f…

ES+Redis+MySQL,这个高可用架构设计太顶了!

一、背景 会员系统是一种基础系统&#xff0c;跟公司所有业务线的下单主流程密切相关。如果会员系统出故障&#xff0c;会导致用户无法下单&#xff0c;影响范围是全公司所有业务线。所以&#xff0c;会员系统必须保证高性能、高可用&#xff0c;提供稳定、高效的基础服务。 …

vue笔记

第一个Vue应用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"widthdevice-…

【零基础入门前端系列】—动画和弹性盒模型(二十四)

【零基础入门前端系列】—动画和弹性盒模型&#xff08;二十四&#xff09; 一、概念 动画是使元素从一种样式逐渐变化为另一种样式&#xff0c;你可以改变任意多的样式任意多的次数。 请用百分比来规定变化发生的时间&#xff0c;或用关键词from和to&#xff0c;等同0%和10…

购物清单(蓝桥杯C/C++省赛)

目录 1 问题描述 2 文件的读取格式 3 代码实现 1 问题描述 小明刚刚找到工作&#xff0c;老板人很好&#xff0c;只是老板夫人很爱购物。老板忙的时候经常让小明帮忙到商场代为购物。小明很厌烦&#xff0c;但又不好推辞。 这不&#xff0c;XX大促销又来了&#xff01;老板…

项目实战典型案例26——nacos的命名空间名称和id不一致带来的思考

nacos的命名空间名称和id不一致带来的思考一&#xff1a;背景介绍Nacos命名空间相关知识点思考总结一&#xff1a;背景介绍 项目用的naocs做的配置中心和服务发现。由于开发环境和本地环境使用的都是同一个命名空间&#xff0c;我们多个服务相互调用的时候&#xff0c;由于开发…
最新文章