# 和 ## 运算符

news2024/12/23 14:29:55

#运算符

1.#运算符用于在预处理期将宏参数转换为字符串。
2.#的作用是在预处理期间完成的,因此只有在宏定义中有效
3.编译器不知道 # 的转换作用

#include <stdio.h>

#define STRING(x) #x

int main()
{
    printf("%s\n",STRING(Hello World!));
    printf("%s\n",STRING(100));
    printf("%s\n",STRING(while));
    printf("%s\n",STRING(return));

    return 0;
}

经过预处理器,处理过后的程序如下所示:

//gcc -E main.c -o test.i
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"
##include <stdio.h>
int main()
{
    printf("%s\n","Hello World!");
    printf("%s\n","100");
    printf("%s\n","while");
    printf("%s\n","return");

    return 0;
}

想一个问题,怎么样在程序中,把函数调用的函数名字打印出来?
这里需要要用到宏,而且必须用到 #,否者用函数是实现不了的。

#include <stdio.h>

#define CALL(f,p) (printf("Call function %s\n",#f),f(p))

int square(int n)
{
    return n*n;
}

int func(int x)
{
    return x;
}
 
int main()
{
    int result=0;

    result = CALL(square,4);

    printf("result = %d\n",result);

    result = CALL(func,10);

    printf("result = %d\n",result);

    return 0;
}

程序经过预处理器处理过后,为下面所示:

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"

int square(int n)
{
    return n*n;
}

int func(int x)
{
    return x;
}

int main()
{
    int result=0;

    result = (printf("Call function %s\n","square"),square(4));

    printf("result = %d\n",result);

    result = (printf("Call function %s\n","func"),func(10));

    printf("result = %d\n",result);

    return 0;
}

##运算符

1.##运算符用于在预处理器期间,粘住两个标识符
2.##的连接作用是在预处理器期间完成的,因此只在宏定义中有效
3.编译器不知道##的连接作用

#include <stdio.h>

#define NAME(n) name##n

int main()
{
    int NAME(1);
    int NAME(2);

    NAME(1)=1;
    NAME(2)=2;

    printf("%d\n",NAME(1));
    printf("%d\n",NAME(2));

    return 0;
}

经过预处理器处理之后的代码为:

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"

int main()
{
    int name1;
    int name2;

    name1=1;
    name2=2;

    printf("%d\n",name1);
    printf("%d\n",name2);

    return 0;
}

再来看一个实例程序:

//#include <stdio.h>

#define STRUCT(type) typedef struct _tag_##type type;\
                     struct _tag_##type

STRUCT(Student)
{
    char* name;
    int id;
};

int main()
{
    Student s1;
    Student s2;

    s1.name="s1";
    s1.id=0;

    s2.name="s2";
    s2.id=1;

    printf("s1.name = %s\n",s1.name);
    printf("s1.id = %d\n",s1.id);
    printf("s2.name = %s\n",s2.name);
    printf("s2.id = %d\n",s2.id);

    return 0;
}

同样经过预处理器之后,程序为:

# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "main.c"

typedef struct _tag_Student Student; struct _tag_Student
{
    char* name;
    int id;
};

int main()
{
    Student s1;
    Student s2;

    s1.name="s1";
    s1.id=0;

    s2.name="s2";
    s2.id=1;

    printf("s1.name = %s\n",s1.name);
    printf("s1.id = %d\n",s1.id);
    printf("s2.name = %s\n",s2.name);
    printf("s2.id = %d\n",s2.id);

    return 0;
}

小结:
1.#运算符用于在预处理期间将宏参数转化为字符串。
2.##运算符用于在预处理器期间连接两个标识符
3.编译器不知道#和##运算符的存在
4.#和##运算符只在宏定义中有效。

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

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

相关文章

ListView的基本创建方式

ListView的基本创建方式 1.ListView 主要介绍了采用标签创建以及ArrayAdapter适配器以及采用继承ListActivity的方式创建列表项 1.简介 是一个列表控件&#xff0c;以列表的形式展示具体内容&#xff0c;可以给各行设置事件监听器ListView中View负责显示和更新&#xff0c;数据…

最小生成树

文章目录基本原理Kruskal算法Prim算法基本原理 连通图中的每一棵生成树&#xff0c;都是原图的一个极大无环子图&#xff0c;即&#xff1a;从其中删去任何一条边&#xff0c;生成树就不在连通&#xff1b;反之&#xff0c;在其中引入任何一条新边&#xff0c;都会形成一条回路…

二叉树9:二叉树的最大深度

主要是我自己刷题的一些记录过程。如果有错可以指出哦&#xff0c;大家一起进步。 转载代码随想录 原文链接&#xff1a; 代码随想录 leetcode链接&#xff1a; 104. 二叉树的最大深度 559.n叉树的最大深度 104.二叉树的最大深度 题目&#xff1a; 给定一个二叉树&#xff0…

校招面试真题 | 你的期望薪资是多少?为什么

很多人去面试的时候&#xff0c;就像打游戏&#xff0c;过五关斩六将&#xff0c;终于到最后一关了&#xff0c;但是谈薪资的难度堪比打游戏中搞定终级 boss 的难度&#xff0c;真的是太「南」了&#xff0c;好多人都是因为这个问题让自己五味杂陈呀。报高了怕好 offer 失之交臂…

Ubuntu: Docker安装与操作

在进行docker安装前&#xff0c;我们首先得有以下工具&#xff1a;xshell,FileZilla Client Xshell下载安装教程 FileZilla Client下载安装教程 如果你的Ubuntu是纯净的(也就是说刚下好并且刚用虚拟机装好的)&#xff0c;你得先 打开终端&#xff08;CtrlAltT&#xff09; 一…

远程连接服务器(运用密钥)连接winscp/vscode/mobaxterm

1.连接ssh 先检查自己是否登上校园VPN校园VPN导航页 (xjtu.edu.cn) sslvpn 进入cmd&#xff08;黑框框&#xff09; 输入&#xff1a; &#xff08;1&#xff09; ssh &#xff08;用户名&#xff09;&#xff08;IP名&#xff09; -p &#xff08;端口如22、2022&#x…

基于SSM框架的旅游网站的设计与实现

1 简介 今天向大家介绍一个帮助往届学生完成的毕业设计项目&#xff0c;*基于SSM框架的旅游网站的设计与实现 *。 计算机毕业生设计,课程设计需要帮助的可以找我 2 设计概要 1.1.研究背景 随着互联网技术的飞速发展&#xff0c;网络与我们的生活息息相关&#xff0c;在我们日…

汉诺塔问题的时间复杂度

一、汉诺塔问题 汉诺塔&#xff08;Tower of Hanoi&#xff09;是一个经典的递归算法问题。它描述的是有三根杆子和若干个不同大小的圆盘&#xff0c;圆盘可以按照大小顺序放在杆子上。初始时&#xff0c;所有圆盘都放在左边的杆子上&#xff0c;目标是将所有圆盘移动到右边的…

PS CS6视频剪辑基本技巧(三)添加声音和字幕

上一讲&#xff0c;介绍一下视频剪接和添加图片这两个功能。这一讲介绍添加声音和字幕&#xff0c;给上一讲剪接的视频添加一个背景音乐和解说字幕。 目录 一、添加音频 1、添加背景音乐 2、剪掉多余音乐 二、添加字幕 1、制作字幕模板 &#xff08;1&#xff09;新建背…

统治扩散模型的U-Net要被取代了,谢赛宁等引入Transformer提出DiT

来自 UC 伯克利的 William Peebles 以及纽约大学的谢赛宁撰文揭秘扩散模型中架构选择的意义&#xff0c;并为未来的生成模型研究提供经验基线。 近几年&#xff0c;在 Transformer 的推动下&#xff0c;机器学习正在经历复兴。过去五年中&#xff0c;用于自然语言处理、计算机视…

【C++】STL——priority_queue的介绍和使用及模拟实现

priority_queue的介绍和使用及模拟实现 文章目录priority_queue的介绍和使用及模拟实现1.priority_queue的介绍和使用priority_queue的介绍priority_queue的使用2. 仿函数3.堆的调整算法堆的向上调整算法堆的向下调整算法4.priority_queue的模拟实现1.priority_queue的介绍和使…

史上最简单易懂的TypeScript教程(更新中)

TypeScript欢迎观看由大型东方幻想车编写的typescript教程1. TypeScript: 类型&#xff08;1&#xff09;其他类型欢迎观看由大型东方幻想车编写的typescript教程 TypeScript介绍: TypeScript是JavaScript类型的严格超集&#xff0c;它可以编译成纯JavaScript。TypeScript可以在…

基于VitePress搭建静态文档系统

文章目录前言一、快速上手二、常用配置2.1 类Vue风格首页2.2 顶部导航配置themeConfig.nav2.3 侧边栏导航设置2.3 文档中的链接跳转2.3.1 上一页与下一页2.3.2 文档中链接2.3.3 生成成员页三、进阶配置四、参考代码前言 vitePress&#xff1a;与vue press相似&#xff0c;是一…

Spring中自定义事件监听

目录 一、Spring中的事件监听 二、自定义事件监听 三、例子 1、事件 2、事件监听器 3、事件发布操作 三、测试注意 一、Spring中的事件监听 当处理完一段代码逻辑&#xff0c;后面需要同时执行多个任务&#xff0c;有什么好方法呢&#xff1f;如果在微服务项目中&…

【自用】VUE项目 宝塔部署 上线阿里云服务器CentOS7.6

一、给VUE项目打包 1.开始打包 运行命令&#xff1a; npm run build2.找到打包好的 dist 文件夹 要记住这个dist文件放在了哪儿&#xff0c;记住哦&#xff01; 二、服务器端安装宝塔面板 1.进入root用户并执行命令 yum install -y wget && wget -O install.…

Node基础——认识Node

什么是Node 首先JavaScript是一门编程语言&#xff0c;就像Java、Python、C#、GO一样&#xff0c;在Node出来之前&#xff0c;JavaScript主要运行于浏览器中&#xff0c;用来控制页面的展示逻辑&#xff0c;以及交互操作等。JavaScript之所以能够在浏览器中执行&#xff0c;是…

Docker搭建Mysql主主架构

文章目录mysql主从架构原理MySQL通用架构方案搭建步骤1. docker创建俩台mysql 端口&#xff1a;23306 和 333062. 创建my.cnf&#xff0c;并将my.cnf拷贝到docker容器中&#xff0c;并重启生效3. 配置完成&#xff0c;开始执行sql&#xff0c;设置主从主主同步mysql主从架构原理…

CSDN每日一练非负整数求和 C语言

题目名称&#xff1a;非负整数求和 时间限制&#xff1a;1000ms 内存限制&#xff1a;256M 题目描述&#xff1a; 给定两个字符串形式的非负整数 num1 和 num2 &#xff0c;计算它们的和。 注意&#xff1a; - num1 和 num2 的长度都小于 5100. - num1 和 num2 都只包含数字 0…

【圣诞节特辑】爱心代码(程序员的浪漫plus+)-李峋

2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ 唯有热爱&#xff0c;可抵岁月漫长&#xff0c;唯有热爱&#xff0c;不畏世间无常&#xff01; 一、前言 前段时间《点燃我温暖你》中李峋的爱心代码超级火&#xff0c;看着特别心动&#xff01;这不&#xff0c;圣…

贪心算法(Java版本)

一、贪心算法 1、算法描述 贪心算法&#xff08;Greedy algorithm&#xff09;&#xff0c;又叫做贪婪算法。 在对问题求解时&#xff0c;不从整体考虑&#xff0c;而是从问题的某一个初始解出发&#xff0c;每一步选择中都采取在当前状态下最好或最优的选择&#xff08;局部…