C语言 宏

目录

一、宏定义

1.1 预定义符号

1.2 预处理指令 #define

1.3 带有副作用宏定义

1.4 宏和函数的一个对比

​编辑

1.5 #undef

二、条件编译

2.1 #if、#else、#elif、#endif

2.2 #ifdef和#ifndef

2.3 C语言中如何通过条件编译来预防头文件的重复包含?


一、宏定义

在C语言中,宏定义是通过  #define 关键字实现的,它可以将被定义的标识符替换为相应的字符串或代码片段。宏定义主要用于简化代码、提高程序的通用性和易读性,同时也能在一定程度上提高程序的运行效率

1.1 预定义符号

在C语言中,预定义符号是由编译器提供的,它们具有特殊的含义和功能。

以下是C语言中的一些常见预定义符号及其用途:

  • __FILE__:表示当前源文件的文件名,可用于调试时显示文件名。 
  • __LINE__:表示当前代码所在的行号,可用于调试时显示代码位置。 
  • __DATE__:表示当前编译的日期,格式为"MMM DD YYYY",例如"Jul 29 2023"。 
  • __TIME__:表示当前编译的时间,格式为"HH:MM:SS",例如"10:30:36"。 
  • __STDC__:如果编译器遵循ANSI C标准,其值为1,否则未定义。这个符号通常用于检测编译器的兼容性。

在VS中(__STDC__)未定义,所以该编译器不支持ANSC l 标准,如下图:

1.2 预处理指令 #define

宏定义主要有两种类型:

  • 不带参数的宏定义和。
  • 带参数的宏定义。

不带参数的宏定义简单地将宏名替换为定义的字符串,例如:

#define PI 3.14159

带参数的宏定义除了进行简单的文本替换外,还会对参数进行计算。例如:

#define S(a,b) a*b

#define 定义的规则

  • 宏替换发生在预处理阶段,即编译前
  • 宏替换是简单的文本替换,不涉及计算
  • 宏替换不占用运行时间,只占用编译时间

1.3 # 和 ##

#操作符用于预编译时期,将宏参数转换为字符串。如图:

##操作符用于在预编译期间将两个宏参数连接起来,形成一个单独的标识符。如图:

1.3 带有副作用宏定义

例如,假设有一个宏定义MAX(a, b),它在预处理阶段展开为((a) > (b) ? (a) : (b))。如果使用MAX(x++, y++),预处理后的结果将是((x++) > (y++) ? (x++) : (y++))。这意味着xy都将被自增两次,这可能并非程序员原本的意图。

正常情况下:

带有副作用情况下:

  • ret 返回的是7,自增了一次,在问好(?)前面。
  • a 的值是3 ,自增了一次,在问号(?)前面。
  • b 的值是8,自增了两次,在则问号前后各增加一次。
1.4 宏和函数的一个对比

相比之下,宏在预编译阶段将宏名替换为后面的替换体,避免了函数调用的开销。宏的展开是简单的文本替换,没有类型检查,因此可能会导致一些潜在的错误。然而,宏的使用可以提高代码的可读性和可维护性,并且在某些情况下,宏的使用可以提高程序的效率。

1.5 #undef

#undef是C语言预处理指令的一种,它的作用是取消之前通过#define指令定义的宏或符号常量

#include <stdio.h>

int main() {
    #define MAX 200
    printf("MAX = %d\n", MAX);
    #undef MAX
    int MAX = 10;
    printf("MAX = %d\n", MAX);
    return 0;
}

二、条件编译

条件编译的主要指令包括#if#else#elif#endif#ifdef#ifndef

2.1 #if#else#elif#endif
  • #if用于判断表达式是否为真,如果为真则编译其后的代码;
  • #else用于与#if搭配,当前面的条件不满足时,编译#else后的代码;
  • #elif相当于#else#if的结合,用于多个条件中的其他条件
  • #endif用于结束一个条件编译块;
2.2 #ifdef#ifndef

#ifndef#ifdef相反,用于判断一个宏是否未被定义,如果未被定义则编译其后的代码。

2.3 C语言中如何通过条件编译来预防头文件的重复包含?

1、使用#ifndef、#define、#endif预处理指令

#ifndef MY_HEADER_H
#define MY_HEADER_H
// 头文件内容
#endif

当头文件第一次被包含时,由于没有定义MY_HEADER_H,编译器会执行#define指令,定义该宏。当头文件再次被包含时,由于该宏已被定义,编译器会跳过#ifndef#endif之间的代码,从而避免重复包含。

2、使用#pragma once指令:

#pragma once
// 头文件内容

这种方法的好处是不会出现宏名冲突的问题,且对于大型项目来说,可以提高编译速度。 

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

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

相关文章

cobaltstrike启动teamserver报错Picked up _JAVA_OPTIONS:

1.报错如下图所示&#xff1a; 解决方法&#xff1a; 这是因为系统环境变量里多了一个变量&#xff1a; _JAVA_OPTIONS 只需要删掉它就行了&#xff01; 1、windows下在环境变量里找到、然后删除就行了 2、linux下、在/etc/profile文件中添加以下命令&#xff08;可添加至第一行…

uniapp或微信小程序一些问题解决

1.按钮边框如何去除&#xff1f; 参考博主&#xff1a;微信小程序按钮去不掉边框_微信小程序button去掉边框-CSDN博客文章浏览阅读1k次。最近在学uni-app&#xff0c;顺便自己写个小程序。左上角放了个button&#xff0c;可边框怎么也去不掉…原来微信小程序的按钮要去掉边框要…

重构2:重构的原则

最近在看重构2&#xff1a;改善既有代码的设计这本书&#xff0c;对于代码重构指导非常有帮助&#xff0c;然后也是做个笔记记录下&#xff0c;以下是我阅读本书的前两章的时候整理的思维导图&#xff1a;

用户流失分析:如何使用Python训练一个用户流失预测模型?

引言 在当今商业环境中&#xff0c;客户流失分析是至关重要的一环。随着市场竞争的加剧&#xff0c;企业需要更加注重保持现有客户&#xff0c;并深入了解他们的离开原因。本文探讨了用户流失分析的核心概念以及如何构建客户流失预测模型的案例。通过分析用户行为数据和交易模式…

动手学操作系统(四、MBR读取硬盘加载Loader)

动手学操作系统&#xff08;四、MBR读取硬盘加载Loader&#xff09; 在上一节中&#xff0c;我们学习了使用MBR来直接控制显卡进行显示&#xff0c;在这一节中我们学习如何让MBR来操作硬盘&#xff0c;加载Loader来完成操作系统的后续启动过程。 文章目录 动手学操作系统&…

005、API_数据结构

键的数据结构类型&#xff0c;它们分别是&#xff1a; string&#xff08;字符串&#xff09;、hash&#xff08;哈希&#xff09;、list&#xff08;列表&#xff09;、set&#xff08;集合&#xff09;、zset&#xff08;有序集 合&#xff09;&#xff0c;这些只是Redis对外…

pg_lakehouse 与 datafusion

原理分析 pg_lakehouse 是 ParadeDB 推出的一个开源插件&#xff0c;支持对多种数据湖里的数据做分析计算。它的出现&#xff0c;使得 Postgres 能够像访问本地数据一样轻松访问 S3 等对象存储&#xff0c;轻松访问 Delta Lake 上的表格&#xff0c;具备数据湖分析能力。 pg_…

ES报错1

ES在kibana的JSON如图: 提交后错误信息如下 所以是什么错误呢: 原来是:json的格式有误改成 这里的错误其实是我在文件传输时,为了节约空间,没有以json格式传递,而是一串字符就传过来了,需要使用josn的格式化工具格式化才行,结果格式化的不正确,才遇到此坑

Guns框架:基于主流技术Spring Boot2 + Vue3 + Antd Vue的现代Java应用开发新纪元

Guns框架&#xff1a;基于主流技术Spring Boot2 Vue3 Antd Vue的现代Java应用开发新纪元 摘要&#xff1a;随着信息技术的飞速发展&#xff0c;软件开发框架在提升开发效率、降低成本方面扮演着至关重要的角色。Guns框架&#xff0c;作为一个现代化的Java应用开发框架&#x…

【Linux多线程】认识多线程创建线程

文章目录 什么是多线程为什么称linux下的线程是轻量级进程呢&#xff1f; 线程的优点线程的缺点线程异常线程和进程创建线程1.pthread_create2.pthread_self 什么是多线程 进程是正在运行的程序的实例&#xff0c;而线程&#xff08;thread&#xff09;是进程中的一个执行路线…

如何顺利通过软考中级系统集成项目管理工程师?

中级资格的软考专业包括"信息系统"&#xff0c;属于软考的中级级别。熟悉软考的人都知道&#xff0c;软考分为初级、中级和高级三个级别&#xff0c;涵盖计算机软件、计算机网络、计算机应用技术、信息系统和信息服务五个专业&#xff0c;共设立了27个资格。本文将详…

GPT-4o:重塑人机交互的未来

一个愿意伫立在巨人肩膀上的农民...... 一、推出 在人工智能&#xff08;AI&#xff09;领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术一直被视为连接人类与机器的桥梁。近年来&#xff0c;随着深度学习技术的快速发展&#xff0c;NLP领域迎来了前所未有的变革…

Excel快速判断大量身份证性别,VBS代码

身份证判断性别的原理就是,身份证倒数第二位是单数表示是男的,单数是女的 可以用IF公式来判断,但是需要下拉,如果几百上千条数据还好,要是上万就不好拉取了,如果数据太多,可以用VBA代码判断 IF(MOD(VALUE(MID(A1,17,1)),2)0,"女","男") 原理:MID(A1,17,1…

MacBook 怎么玩Windows游戏 苹果笔记本怎么玩游戏?mac上如何玩windows游戏

传统上&#xff0c;Mac 不被认为是好的游戏机。然而&#xff0c;苹果已经开始在 Mac 上的游戏上投入更多精力&#xff0c;特别是自从转向苹果芯片以来。这使得 Mac 游戏的本机移植数量和模拟 Windows 游戏的能力都得到了显著提高。 方法一&#xff1a;Boot Camp 1、Boot Camp是…

正确地安装 Python

Python由荷兰国家数学与计算机科学研究中心的吉多范罗苏姆于1990年代初设计&#xff0c;作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构&#xff0c;还能简单有效地面向对象编程。Python语法和动态类型&#xff0c;以及解释型语言的本质&#xff0c;使它成为多数…

windows10远程桌面端口,修改Windows 10远程桌面端口的步骤

在Windows 10操作系统中&#xff0c;远程桌面功能为企业用户、技术支持人员以及个人用户提供了极大的便利&#xff0c;允许他们远程访问和管理另一台计算机的桌面环境。然而&#xff0c;默认的远程桌面端口&#xff08;通常为3389&#xff09;常常成为安全漏洞的潜在目标&#…

粒子辐照环境中相机镜头防护及LabVIEW图像处理注意事项

在粒子辐照环境测试电路板性能的实验中&#xff0c;需要对相机镜头进行有效防护&#xff0c;同时利用LabVIEW进行图像识别和处理。本文将讨论相机镜头防护的关键因素和LabVIEW处理过程中的注意事项&#xff0c;包括防辐射材料选择、辐射屏蔽措施、散热管理、空间布局及LabVIEW软…

Linux驱动开发笔记(二) 基于字符设备驱动的GPIO操作

文章目录 前言一、设备驱动的作用与本质1. 驱动的作用2. 有无操作系统的区别 二、内存管理单元MMU三、相关函数1. ioremap( )2. iounmap( )3. class_create( )4. class_destroy( ) 四、GPIO的基本知识1. GPIO的寄存器进行读写操作流程2. 引脚复用2. 定义GPIO寄存器物理地址 五、…

SC8205LA 20VN沟道增强型MOS(Mos)场效应管

特点 ❥专有的先进平面技术 ❥高密度超低电阻设计 ❥大功率、大电流应用 ❥理想的锂电池应用 ❥封装形式:SOT23-6

总是不能盈利?试着用这两个观点去学习现货白银的技巧

一进入现货白银市场&#xff0c;投资者都想着如何去找到现货白银交易的机会&#xff0c;学习现货白银投资的方法。其实这些都是手段&#xff0c;而最终的目的还是为我们的盈利服务。而对于盈利来说&#xff0c;其实胜率和风险报酬比才是影响盈利的重要因素&#xff0c;我们带着…