C语言 宏

news2024/11/18 21:37:54

目录

一、宏定义

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
// 头文件内容

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

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

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

相关文章

卓豪Zoho CRM客户管理系统采购费用?

企业如何高效地管理客户关系&#xff0c;卓豪Zoho CRM&#xff0c;作为一款领先的客户关系管理系统&#xff0c;不仅为企业提供了一套完整的客户管理解决方案&#xff0c;更在价格上实现了公开透明和合理优惠&#xff0c;助力企业实现数字化转型&#xff0c;迈向更高效、更智能…

深入解析Python中的两种导入方法:from...import与import

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、from...import与import的基本区别 1. 导入方式的不同 2. 命名空间的差异 三…

倍福TwinCAT3 PLC编程软件下载安装

1、哪里下载TwinCAT3 链接: Search result | 倍福 中国https://www.beckhoff.com.cn/zh-cn/support/download-finder/search-result/?download_group=97028248下载倍福PLC编程软件需要注册,大家可以提前注册,注册好后就可以开始愉快的下载了 安装前需要注意将各杀毒软件卸…

常用的优化器汇总及keras实现

1.SGD&#xff08;Stochastic Gradient Descent&#xff09; 2.RMSprop&#xff08;Root Mean Square Propagation&#xff09; 3.Adadelta 4.Adam&#xff08;Adaptive Moment Estimation&#xff09; 5.Nadam 6.代码实现 from sklearn.compose import make_column_transforme…

Linux下Git的基本使用

认识Git 先基于Windows下的git操作&#xff0c;熟悉了git的基本概念和使用&#xff0c;直接参考这几篇文章&#xff1a; Git概述、安装与本地仓库的基本操作-CSDN博客 Git本地仓库与远程仓库的交互-CSDN博客 GtiHub远程仓库之间的交互-CSDN博客 Git仓库的分支操作-CSDN博客 仓库…

python如何巧妙地利用内置函数与列表切片组织舞会派对

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、问题分析 三、解决方案 1. 利用内置函数创建参会人员名单 2. 利用列表切片…

每期一个小窍门 k8s版本的 Prometheus + grafana + alertmanager 三件套部署监控落地

首先部署prometheus 首先是pvc apiVersion: v1 kind: PersistentVolumeClaim metadata:name: prometheus-data-pvcnamespace: monitor spec:accessModes:- ReadWriteManystorageClassName: "data-nfs-storage"resources:requests:storage: 10Gi然后接着 cluster-ro…

【条形码code39】基础知识

条形码-39码&#xff08;code39&#xff09; 符号集。(共43个字符)包括 数字0 ~ 9,大写字母A~Z,空格,-,。,$,/,,% Extended Code39&#xff0c;支持全部ASCII字符。 完整的code39条形码&#xff1a;起始字符&#xff08; * &#xff09; 数据数值 &#xff08;可选的&#…

关于微信小程序低功耗蓝牙ECharts实时刷新(涉及自定义缓冲区)

简单的蓝牙显示&#xff08;串口手动发数据测试&#xff09; 最近搞了这方面的东西&#xff0c;是刚刚开始接触微信小程序&#xff0c;因为是刚刚开始接触蓝牙设备&#xff0c;所以这篇文章适合既不熟悉小程序&#xff0c;又不熟悉蓝牙的新手看。 项目要求是获取到蓝牙传输过来…

uni-app全局弹窗的实现方案

背景 为了解决uni-app 任意位置出现弹窗 解决方案 一、最初方案 受限于uni-app 调用组件需要每个页面都引入注册才可以使用&#xff0c;此方案繁琐&#xff0c;每个页面都要写侵入性比较强 二、改进方案 app端&#xff1a;新建一个页面进行跳转&#xff0c;可以实现伪弹窗…

探索数组处理:奇数的筛选与替换

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、数组中的奇数筛选 二、将奇数替换为负一 总结 一、数组中的奇数筛选 在处理数组数据时…

在WHM中如何调整max_post_size参数大小

今日我们在搭建新网站时需要调整一下PHP参数max_post_size 的大小&#xff0c;我们公司使用的Hostease的美国独立服务器产品默认5个IP地址&#xff0c;也购买了cPanel面板&#xff0c;因此联系Hostease的技术支持&#xff0c;寻求帮助了解到如何在WHM中调整PHP参数&#xff0c;…

告别虚拟机,在Windows10启动Linux子系统

背景 如果要在自己的windows电脑安装一个Linux系统,一般是用虚拟机软件例如VMware软件来创建。但是这种方式显得非常的笨重。而Windows10自带的Linux子系统则非常的方便。 分析 在Windows10中启用子系统的方式来安装Linux,用于学习和开发是非常方便的。子系统的实用就和一个…

Android SDK下载安装(_指定版本)

安装完sdk&#xff0c;就可以直接使用adb命令了&#xff0c;如果想做app相关自动化测试&#xff0c;也是需要sdk环境依赖的 一、SDK下载 A&#xff1a;官网下载&#xff1a; 管内镜像网站(推荐)&#xff1a;https://www.androiddevtools.cn/index.html 官网&#xff1a;htt…

分享10个我常逛的技术社区

多逛社区&#xff0c;了解新鲜的事情和技术&#xff0c;或许会有意想不到的观点给你灵感&#xff01; 国外技术交流网站合集&#xff08;30个类别&#xff09;的github地址: https://github.com/sdmg15/Best-websites-a-programmer-should-visit 这里收集了超过200个程序员应该…

17 C语言学生管理系统

学生管理系统 &#x1f44d;&#x1f602;&#x1f4af; 项目代码 代码可能存在细节上的错误&#xff0c;希望大家可以指导意见。 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h> #include <stdlib.h> #include <string.h>#define MAX_STUDENTS 100…

轻量级 C Logger

目录 一、描述 二、实现效果 三、使用案例 四、内存检测 一、描述 最近实现一个 WS 服务器&#xff0c;内部需要一个日志打印记录服务器程序的运行过程&#xff0c;故自己实现了一个轻量级的 logger&#xff0c;主要包含如下特征&#xff1a; 可输出 debug、info、warn、er…

C++ 进阶(3)虚函数表解析

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 请多多指教&#xff01; 目录 一、虚函数表 二、单继承&#xff08;无虚函数覆盖&#xff09; 继承关系表&#xff1a; 对于实例&#xff1a;derive d 的虚函数表&#xff1a; 对于实例&#xff1a;b…

现货白银交易点差是多少

现货白银投资者通过交易平台进行买卖操作的时候&#xff0c;平台会以“点差”的形式向投资者收取一定的交易费用。所谓的点差&#xff0c;也就是平台所报出的买入价和卖出价之间的固定差额&#xff0c;由于现货白银的报价是“成对”的&#xff0c;所以点差的存在也是其交易模式…

连锁收银系统支持带结算功能

连锁实体店的收银系统需要支持结算功能&#xff0c;以适应连锁运营效率和提升连锁管理的水平。商淘云连锁收银系统与您一起分享连锁收银系统需支持结算功能的三大必要点。大家点赞收藏&#xff0c;以免划走后找不到了。 一是&#xff0c;连锁模式的运营比较复杂&#xff0c;有加…