文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言中带返回值的宏定义方式是什么

2023-07-05 06:27

关注

这篇文章主要介绍“C语言中带返回值的宏定义方式是什么”,在日常操作中,相信很多人在C语言中带返回值的宏定义方式是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言中带返回值的宏定义方式是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

C语言中带返回值的宏定义

相信大家在实际工作中,一定有遇到需要编写一个宏定义,且希望它能带返回值的场景吧?

比如我之前就遇到一个场景,早期的代码是使用函数实现的功能,现在想换成宏定义,但是又要保留之前调用函数的代码不动,这样我就只能想办法写一个带返回值的宏了。

宏定义编写

直接上demo:

#include <stdio.h>#define RETURN_MACRO()            ({do {} while(0);1;})#define RETURN_MACRO2()            1#define A_PLUS_B_MACRO(a, b)    ({int ret; ret = (a) + (b); ret;})#define A_PLUS_B_MACRO2(a, b)    ({int ret; ret = add((a), (b)); ret;})int add(int a, int b){    return (a + b);}int main(int argc, const char *argv[]){    int a = 6;    int b = 7;    printf("Hello world !\n");    printf("RETURN_MACRO: %d\n", RETURN_MACRO());    printf("RETURN_MACRO2: %d\n", RETURN_MACRO2());    printf("a + b = %d\n", A_PLUS_B_MACRO(a, b));    printf("a + b = %d\n", A_PLUS_B_MACRO2(a, b));    return 0;}

宏定义分析

为了分析宏定义的写法,我们得知道宏定义最终被展开是什么样的。

我在之前的博文中有提到,使用gcc编译器的话,可以在CFLAGS上加上-save-temps=obj这个编译选项,这样就可以得到预编译处理之后的文件,后缀名是.i。

我们使用编译脚本编译之后,得到.i文件如下:

//前面的内容忽略# 3 "main.c" 2# 12 "main.c"# 12 "main.c"int add(int a, int b){ return (a + b);}int main(int argc, const char *argv[]){ int a = 6; int b = 7; printf("Hello world !\n"); printf("RETURN_MACRO: %d\n", ({do {} while(0);1;})); printf("RETURN_MACRO2: %d\n", 1); printf("a + b = %d\n", ({int ret; ret = (a) + (b); ret;})); printf("a + b = %d\n", ({int ret; ret = add((a), (b)); ret;})); return 0;}

从.i文件我们可以看到,宏定义被正常展开,下面确认下功能是否正常。

宏定义验证

我们执行编译出来的可执行文件:

return_macro$ ./test Hello world !RETURN_MACRO: 1RETURN_MACRO2: 1a + b = 13a + b = 13

验证成功。

经验总结

C语言中一些宏定义和常用的函数

typeof 关键字

如果你是 C++ 程序员,应该接触过 C++11 里的 decltype 操作符,它的作用是自动推导表达式的数据类型,以解决泛型编程中有些类型由模板参数决定而难以(甚至不可能)表示的问题。

其实这个特性在 C 语言中也早有类似的实现,GNU C 标准中的一个扩展特性 typeof 作用与 decltype 类似。

__typeof__ (ret) errnum = (ret);

snprintf()函数的作用

#include<stdio.h>int snprintf(char* dest_str,size_t size,const char* format,...);

【函数功能】:

先将可变参数 “&hellip;” 按照format的格式格式化为字符串,然后再将其拷贝至dest_str中。

如果格式化后的字符串长度小于size,则将字符串全部拷贝至dest_str中,并在字符串结尾处加上&lsquo;\0&rsquo;; 如果格式化后的字符串长度大于或等于size,则将字符串的(size-1)拷贝至dest_str中,然后在字符串结尾处加上&rsquo;\0&rsquo;. 函数返回值是 格式化字符串的长度。

__builtin_expect的作用

__builtin_expect(errnum != 0, 0)

这个指令是gcc引入的,作用是"允许程序员将最有可能执行的分支告诉编译器"。

这个指令的写法为:__builtin_expect(EXP, N)。意思是:EXP==N的概率很大。

一般的使用方法是将__builtin_expect指令封装为LIKELY和UNLIKELY宏。

C语言中常用的预定义

反斜杠的作用

反斜杠起到换行作用,用于宏定义和字符串换行。其中宏定义中使用居多。

如果一行代码有很多元素,导致太长影响阅读,可以通过在结尾加\的方式,实现换行,编译时会忽略\及其后的换行符,当做一行处理。

#define CHECK_ACTION_RETURN(expr) \    if (!expr) { \        printf(":failed(%d)\n", ret); \        return ret; \                } else { \        printf(":ok\n"); \                }

到此,关于“C语言中带返回值的宏定义方式是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯