c 宏应用举例
1.概要
#include <iostream>
//变量可以直接使用
#define fun() a =100;
//用变量计算可以
#define fun2(a) a*2;
//用变量替换可以
#define fun3(a) d[a] = a;
//##链接的作用,一般用于链接变量名
#define fun4(type,name) type name##_s = 4;
//#的作用是转换成字符串
#define fun5(a) #a;
2.代码
#include <iostream>
//变量可以直接使用
#define fun() a =100;
//用变量计算可以
#define fun2(a) a*2;
//用变量替换可以
#define fun3(a) d[a] = a;
//##链接的作用,一般用于链接变量名
#define fun4(type,name) type name##_s = 4;
//#的作用是转换成字符串
#define fun5(a) #a;int main()
{int a;fun();std::cout << a << "\n";int b = 5;int c = fun2(b);//b*2std::cout << c << "\n";int d[3];for (size_t i = 0; i < 3; i++){fun3(i);// d[i] = i}for (size_t i = 0; i < 3; i++){std::cout << d[i] << "\n";}fun4(int, ta);//int ta_s = 5;std::cout << ta_s << "\n";int e = 5;const char* f = fun5(e);std::cout << f << "\n";std::cout << "Hello World!\n";
}
3.运行结果
100
10
0
1
2
4
e
Hello World!
4.附加
4.1c 宏的返回值如何确定
在C语言中,宏(macros)本身并不返回值,因为宏是预处理器(preprocessor)在编译前进行文本替换的工具。当你在代码中调用一个宏时,预处理器会简单地将宏名替换为其定义的内容。
但是,我们可以说宏“展开”后的代码可以产生返回值,这取决于宏是如何定义的以及它是如何被使用的。
例如,一个简单的宏可能定义如下:
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
这个宏用于比较两个值并返回较大的一个。但是,请注意,这并不是宏本身“返回”值,而是宏展开后的代码(即条件运算符表达式)在运行时返回值。
要确定宏“展开”后的代码如何返回值,你需要查看宏的定义并理解它是如何工作的。在上述例子中,MAX宏使用了条件运算符(?:),该运算符在C语言中用于根据条件返回两个值中的一个。
注意:由于宏只是文本替换,所以在使用宏时需要特别小心,以避免意外的副作用或错误。例如,在上面的MAX宏中,如果参数是复杂的表达式或具有副作用的表达式(如自增或自减),则可能会导致问题。为了避免这些问题,通常建议使用括号将宏的参数括起来,如上例所示。
4.2 #的作用
在C和C++编程中,# 符号在预处理器指令中有特殊的作用,但它本身并不是宏的一部分。预处理器指令是以 # 开头的特殊指令,它们在编译器的实际编译过程之前由预处理器处理。
以下是一些常见的以 # 开头的预处理器指令:
-
#include:用于包含其他文件的内容。#include <stdio.h> // 包含标准输入输出头文件#include "myheader.h" // 包含当前项目中的头文件 -
#define:用于定义宏。#define PI 3.14159 // 定义一个名为PI的宏,其值为3.14159#define MAX(a, b) ((a) > (b) ? (a) : (b)) // 定义一个名为MAX的宏,用于比较两个数 -
#undef:用于取消已定义的宏。#undef PI // 取消PI宏的定义 -
#if、#elif、#else、#endif:用于条件编译。#if DEBUG// 调试代码#else// 非调试代码#endif -
#ifdef和#ifndef:用于检查某个宏是否已定义。#ifdef SOME_MACRO// 如果SOME_MACRO已定义,则包含此代码#endif#ifndef SOME_OTHER_MACRO// 如果SOME_OTHER_MACRO未定义,则包含此代码#endif -
#line:用于改变预处理器对行号和文件名的跟踪。#line 100 "newfile.c" // 将接下来的代码视为在newfile.c文件的第100行开始 -
#error和#warning:用于在编译时生成错误或警告消息。#if SOME_CONDITION_THAT_SHOULD_NOT_HAPPEN#error "This condition should not happen!"#endif#warning "This is a warning message." -
#pragma:这是一个特定于编译器的指令,用于提供编译指示,如优化设置、警告控制等。#pragma once // 一些编译器支持此指令来防止头文件被多次包含
请注意,虽然 # 符号在预处理器指令中很重要,但它本身并不是C或C++语言的一部分。在C或C++的代码中,你不能直接使用 # 符号(除了作为预处理器指令的一部分)来执行任何操作或定义变量。
4.3 # 在宏表达式内的作用
在宏表达式内部,# 符号具有特殊的作用,当它与 ## 一起使用时,它们是 C/C++ 预处理器的运算符,分别被称为“字符串化”运算符和“标记连接”运算符。
-
字符串化运算符
#:
当#运算符用于宏参数时,它会把该参数转换为一个用双引号括起来的字符串。例如:#define TO_STRING(x) #xint main() {printf("%s\n", TO_STRING(hello)); // 输出 "hello"printf("%s = %d\n", TO_STRING(PI), PI); // 假设 PI 是一个宏,输出 "PI = 3.14159"(假设 PI 定义为 3.14159)return 0;}在这个例子中,
TO_STRING(hello)会被替换为"hello",而TO_STRING(PI)会被替换为"PI"。 -
标记连接运算符
##:##运算符用于连接两个标记(token),通常用于连接宏参数和其他标记以形成新的标记。这在编写可重用和灵活的宏时特别有用。例如:#define CONCAT(x, y) x ## yint xy = CONCAT(x, y); // 这将声明一个名为 xy 的变量// 或者更复杂的用法,例如与类型一起使用#define TYPED_VAR(type, name) type nameTYPED_VAR(int, myVar); // 这将声明一个名为 myVar 的 int 类型变量// 使用 `##` 可以让类型也是动态的#define TYPED_NAMED_VAR(type, name) type name ## _varTYPED_NAMED_VAR(int, my); // 这将声明一个名为 my_var 的 int 类型变量需要注意的是,
##运算符不能用于连接两个字符串字面量或其他类型的表达式;它只能用于连接标记。
在宏表达式中,# 和 ## 通常一起使用或单独使用,以提供宏的额外功能。然而,它们的使用需要谨慎,因为不正确的使用可能会导致编译错误或不可预测的行为。
相关文章:
c 宏应用举例
1.概要 #include <iostream> //变量可以直接使用 #define fun() a 100; //用变量计算可以 #define fun2(a) a*2; //用变量替换可以 #define fun3(a) d[a] a; //##链接的作用,一般用于链接变量名 #define fun4(type,name) type name##_s 4; //#的作用是转换…...
微信公众号(公众平台) 和 微信开放平台的scope的差异
微信公众号(公众平台) 和 微信开放平台 是两码事。 公众号(公众平台)获取的scope只包括两种:snsapi_base 和snsapi_userinfo,前者是静默获取,用户无感知;后者是需要用户确认同意的。…...
基于pytorch实现的DenseUnet医学图像分割(腹部多脏器)
1、前言 本章将介绍将densenet的主干网络引入unet中 官方实现的代码:kits19-challenge/network at master nitsaick/kits19-challenge (github.com) 本章实现的项目目录如下: 主要代码有train、evaluate、predict脚本 2、代码介绍 数据预处理脚本 数据…...
富格林:正规策划实现安全做单
富格林悉知,在投资理财的过程中,最重要的是控制风险实现安全做单避免损失。但是市场客观因素带来的风险并不能完全避免,因此投资者需要采取一些正规技能来减低风险投资风险实现安全做单。接下来就由富格林给大家分享一些实现安全做单的正规方…...
02. 异常捕捉和处理
检索特定内容的邮件,当检索失败,就会在终端输出“获取不了值” try: #代码块A except: #代码B 试一下运行代码A,当代码A报错时,执行代码B 这是main_exe.py文件中的内容 略过 #今天 for job_name,end_time in zip(bji.job_inf…...
Oracle和mysql中插入时间字段
例如有id 和 times两个字段 Oracle insert into xxx values|(1,sysdate) mysql insert into xxx values(1,now()) 在 MySQL 中,SYSDATE() 函数也是可用的,它与 NOW() 类似,但略有不同: NOW…...
注册小程序
每个小程序都需要在 app.js 中调用 App 方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。 详细的参数含义和使用请参考 App 参考文档 。 整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp 方法获取到全…...
【YOLOv8改进[CONV]】使用MSBlock二次创新C2f模块实现轻量化 + 含全部代码和详细修改方式 + 手撕结构图 + 轻量化 + 涨点
本文将使用MSBlock二次创新C2f模块实现轻量化,助力YOLOv8目标检测效果的实践,文中含全部代码、详细修改方式以及手撕结构图。助您轻松理解改进的方法,实现有效涨点。 改进前和改进后的参数对比: 目录 一 MSBlock 二 使用MSBlock二次创新C2f模块实现轻量化 1 整体修改 …...
three.js使用环境贴图或者加载hdr图
1、three.js使用环境贴图 1.1、效果视频 环境贴图 1.2、使用步骤(个人认为) (1)导入引入相关方法 (2)创建场景 (3)创建相机 (4)添加物体材质 (5…...
GPT-4o多模态大模型的架构设计
GPT-4o:大模型风向,OpenAI大更新 OpenAI震撼发布两大更新!桌面版APP与全新UI的ChatGPT上线,简化用户操作,体验更自然。同时,全能模型GPT-4o惊艳亮相,跨模态即时响应,性能卓越且性价比…...
Facebook:社交世界的引领者
导语 在当今数字化时代,Facebook已经成为了人们社交生活的重要一环。然而,除了成为社交媒体的象征外,它还在不断探索并领导着社交世界的新方向。 1. 社交平台的发展者 Facebook不仅仅是一个社交平台,更是社交方式的引领者。从其…...
qt 加载字体 c++
目录 qt 加载字体 c label设置大小和字体: 资源配置路径失败 解决方法:exe相对目录: pro配置: resource.qrc qt 加载字体 c #include <QApplication> #include <QLabel> #include <QFontDatabase> #incl…...
Linux ldd和ldconfig
ldconfig ldconfig 查看默认库路径和ld.so.conf包含的库路径,来建立运行时动态装载的库查找路径。 ldconfig命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib*.so*),…...
Python 学习flask创建项目
1、使用pycharm创建flask项目 2、运行访问地址 3、可以看到访问地址内容 4、可以增加路由,尝试访问获取参数...
.NET集成DeveloperSharp实现图片的裁剪、缩放、与加水印
🏆作者:科技、互联网行业优质创作者 🏆专注领域:.Net技术、软件架构、人工智能、数字化转型、DeveloperSharp、微服务、工业互联网、智能制造 🏆欢迎关注我(Net数字智慧化基地),里面…...
阿里发布最强开源大模型通义千问Qwen2,国产最好用的LLM
前言 近年来,大模型技术发展迅速,开源模型的出现为AI研究和应用带来了新的活力。在这一背景下,阿里云通义千问团队发布了全新升级的Qwen2系列开源模型,为国内外开发者提供了更强大的工具和更丰富的选择。 Huggingface模型下载&am…...
探索风电机组:关键软件工具全解析
探索风电机组:关键软件工具全解析 随着可再生能源市场的迅猛发展,风电作为一种重要的可再生能源,其相关技术和工具也越来越受到重视。风电机组的设计、仿真、优化及运维等方面,都需要依靠一系列专业软件工具来实现。这些软件涵盖…...
HOW - CSS 常见效果实现
目录 渐隐渐显曲线&抛物线气泡框水波纹悬浮&漂浮长按控制进度条圆弧&圆形进度条引导蒙层随机物品掉落渐变边框光晕按钮下压反馈头像(圆形半透明阴影) 常见 CSS 效果实现总结。 渐隐渐显 <!DOCTYPE html> <html> <style>…...
EI/CPCI/Scopus会议论文是啥?
EI/CPCI/Scopus会议论文是啥? EI/CPCI/Scopus是学术圈常见的字母缩写了,它们并非某一种期刊或是某一种杂志,而是一种便捷的论文检索工具。它们之间的区别在于,各自涵盖的领域的不同。▌EI (The Engineering Index&…...
【递归、搜索与回溯】穷举vs暴搜vs深搜vs回溯vs剪枝
穷举vs暴搜vs深搜vs回溯vs剪枝 1.全排列2.子集 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃😃 管他什么深搜、回溯还是剪枝,画出决…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
