高级宏定义

news2024/9/21 10:43:40

平时常说的 C 语言三大预处理功能是什么?(吹牛谈资,不能不知) 

答:宏定义;文件包含;条件编译。

说到底,宏定义的实质是什么?

答:替换。

关于宏定义有一点大家一定要了解,就算再复杂,它也只是替换,不做计算,也不做表达式求解。

 请问下面的宏为什么无法比较 x 和 y 两个参数的大小?

#define MAX (x, y) (((x) > (y)) ? (x) : (y))

答:这是由于在 MAX 和参数 (x, y) 之间存在空格导致的。

从初学者的角度来看,带参数的宏定义和函数十分相似,你作为渐入佳境的大牛,你能否从实现逻辑上指出它俩的不同之处?

答:虽然宏定义也有所谓的”形参“和”实参“,但在宏定义的过程中,并不需要为形参指定类型。这是因为宏定义只是进行机械替换,并不需要为参数分配内存空间

而函数不同,在函数中形参和实参是两个不同的变量,都有自己的内存空间和作用域,调用时是要把实参的值传递给形参。

下面这个宏定义存在什么安全隐患?

#define SQUARE(x) x * x

答:如果单独传入一个数字,那是没问题的。

但如果你传入一个式子,那么问题就来了。

比如传入 3+2,那么宏定义替换后的结果便是 3+2 * 3+2,显然不能获得预期的计算结果。

比较稳妥的做法给参数也加上小括号:#define SQUARE(x) ((x) * (x))

课堂中留下的问题,请问下面宏定义隐藏着一个难以发现的 BUG,请你找出来?

#define SQUARE(x) ((x) * (x)

答:当宏定义的参数遇到 ++、-- 运算符的时候,BUG 出现

下面是触发 BUG 的代码:

#include <stdio.h>

#define SQUARE(x) ((x) * (x))

int main(void)
{
        int i = 1;

        while (i <= 5)
        {
                printf("%d 的平方是%d\n", i-1, SQUARE(i++));
        }

        return 0;
}

看,程序完全不按套路出牌:

但如果将宏定义改成函数:

#include <stdio.h>

int square(int x);

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

int main(void)
{
        int i = 1;

        while (i <= 5)
        {
                printf("%d 的平方是%d\n", i-1, square(i++));
        }

        return 0;
}

程序妥妥地按照我们的要求去实现:

这是因为 C 语言默认将参数从右到左的顺序依次入栈,参数和局部变量都是存放在栈中的,还记得吧?

printf("%d 的平方是%d\n", i-1, SQUARE(i++));

SQUARE(i++) 先展开了,变成 ((i++) * (i++))。

由于 ++ 在后,所以是先使用 i 的值,再自增,上面式子的结果是 1,完事之后 i 的值变成了 3(自增了两次)。

所以,第一次打印便是:2 的平方是 1

同样的道理,第二次先展开 SQUARE(i++),此时 i 的值是 3,完事之后变成 5,所以第二次打印便是:4 的平方是 9。

大千世界,无奇不有,学习编程,就要动手!

不要想当然,哈哈哈哈~

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

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

相关文章

CSS技巧专栏:一日一例 18 -纯CSS实现背景浮光掠影的按钮特效

CSS技巧专栏:一日一例 18 -纯CSS实现背景浮光掠影的按钮特效 先发图,再说话: 案例图片 案例分析 按钮是好几种颜色的背景色组成的,使用css的话,应该会有几个不同颜色的层,在按钮后面移动。每个层互相叠加,大概还会用到图片混合模式产生了更多的叠加的颜色,然后边缘过…

云计算实训20——mysql数据库安装及应用(增、删、改、查)

一、mysql安装基本步骤 1.下载安装包 wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 2.解压 tar -xf mysql-8.0.33-1.el7.x86_64.rpm-bundle.tar 3.卸载mariadb yum -y remove mariadb 查看解压后的包 [rootmysq…

二叉树遍历算法的应用

1、二叉树的创建 2、二叉树的复制 3、二叉树的深度 4、计算结点总个数

jsp 自定义taglib

一、简介 我们在javaWeb开发中&#xff0c;经常会用到jsp的taglib标签&#xff0c;有时候并不能满足我们的实际需要&#xff0c;这就需要我们自定义taglib标签&#xff0c; 二、开发步骤 1、编写control方法&#xff0c;继承BodyTagSupport 2、定义zdytaglib.tld标签文件 3、…

AI Agent 如何入门?来看看这本新书!!!

半个月前&#xff0c;粗心的我细心地发现&#xff0c;有一本关于 Agent 的书籍&#xff0c;作者还是熟悉的咖哥&#xff08;黄佳老师&#xff0c;当年拜读过他的《零基础学机器学习》&#xff09;。 而在昨天&#xff0c;我终于收到了&#xff01;立刻花了半个小时品读起来~觉…

LeetCode 572.另一棵树的子树 C写法

LeetCode 572.另一棵树的子树 C写法 思路&#x1f9d0;&#xff1a; 可以用上判断两棵树是否相同的方法&#xff0c;root的每个结点都去与subroot进行该方法的比较&#xff0c;如果有一轮比较成功就表示root包含subroot。 代码&#x1f50e;&#xff1a; bool isSameTree(struc…

【时时三省】(C语言基础)函数的声明和定义

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 函数声明 1.告诉编译器有一个函数叫什么&#xff0c;参数是什么&#xff0c;返回类型是什么。但是具体是不是存在&#xff0c;无关紧要。 2.函数的声明一般出现在函数的使用之前。要满足先声…

视频监控汇聚平台LntonCVS安防管理平台构建互联网视频监控安全管理系统方案

随着互联网和人工智能技术的发展&#xff0c;我们致力于建设一种云端平台&#xff0c;统一整合各类二三类视频资源&#xff0c;实现对网络工程最后100米、10米甚至1米的全域覆盖。 依托互联网与VPN网络&#xff0c;我们提供了一种视频监控安全管理系统方案&#xff0c;集成了大…

SpringSecurity+Mysql数据库实现用户安全登录认证

Spring Security 是一个提供身份认证、授权和防范常见攻击的安全权限框架。无论是对命令式&#xff0c;还是响应式web应用程序都完美支持&#xff0c;现在主要用作保护基于 Spring 框架的应用程序的事实标准。相对于shiro来说&#xff0c;SpringSecurity功能更加复杂而且更加强…

深入浅出:可视化理解揭示决策树与梯度提升背后的数学原理

决策树是一种非参数的监督学习算法&#xff0c;可用于分类和回归。它使用类似树的结构来表示决策及其潜在结果。决策树易于理解和解释&#xff0c;并且可以轻松地进行可视化。但是当决策树模型变得过于复杂时&#xff0c;它不能很好地从训练数据中泛化&#xff0c;会导致过拟合…

64、ELK记录nginx、httpd、mysqld日志

logstash收集服务日志文件 一、logstash收集appache日志文件&#xff0c;转发到elasticsearch 1、建立在elk1、2、3搭建好elk架构基础之上192.168.168.61 es1 2/4g192.168.168.62 es2 2/4g192.168.168.63 logstash kibana nginx/http 4/8g三台开启服务systemctl s…

《数据结构》(C语言版)第1章 绪论(上)

第1章 绪论 1.1 数据结构的研究内容1.2 基本概念和术语 1.1 数据结构的研究内容 N.沃思&#xff08;Niklaus Wirth)教授提出&#xff1a; 程序算法数据结构 电子计算机的主要用途 早期&#xff1a;主要用于数值计算 后来&#xff1a;非数值计算&#xff0c;复杂的具有一定结构…

Gstreamer配合srs服务器实现RTMP直播和WebRtc直播

前言 上一篇文章,实现了配合腾讯云直播的推流,但是需要花钱,于是就在思考能不能搞一个局域网内,免费的RTMP直播呢? 最终发现了可以使用srs服务器。如果成功了,以后也可以使用webrtc的直播推流。 以下是实现效果: 一、搭建srs服务器: 参考:ubuntu环境下搭建SRS服务器(…

windows系统关闭开机自检硬盘

效果&#xff1a; 注册表关闭开机硬盘自检&#xff0c;你可以按照以下步骤操作&#xff1a; 打开注册表编辑器&#xff1a; 按 Win R 键打开“运行”对话框。输入 regedit 并按回车&#xff0c;打开注册表编辑器。 定位到自检相关的键&#xff1a; 依次展开以下路径&#x…

认识经典蓝牙

现在BLE很流行&#xff0c;本人接触BLE也更多&#xff0c;而对经典蓝牙BR/EDR的开发知之甚少&#xff0c;而且网上关于经典蓝牙的资料也很少&#xff0c;所以&#xff0c;想要有更多了解。 参考&#xff1a; https://www.nordicsemi.cn/news/bluetoothle-and-bluetoothclassic/…

mac|运行别人的SpringBoot+Vue项目

一、运行vue 1、查看项目版本&#xff0c;在package.json中查看&#xff0c;在dependencies中的vue就是对应的版本 2、查看本机的vue版本&#xff1a;vue -V 3、删除node_modules 、package-lock.json 4、运行npm install 如果卡住不动&#xff0c;可能是因为网络问题&…

EasyAR_稀疏空间图

EasyAR_稀疏空间图 EasyAR4.6.3 丨 Unity2020.3.15f2 1.创建稀疏空间地图 在EasyAR开发中心后台创建Scene许可证密钥&#xff0c;并且使用稀疏空间地图 2.设置稀疏空间地图库名&#xff0c;对稀疏空间地图进行管理&#xff0c;设置密钥 3.复制密钥到Unity中 添加Spatial Map Ap…

N4 - Pytorch实现中文文本分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目录 任务描述步骤环境设置数据准备模型设计模型训练模型效果展示 总结与心得体会 任务描述 在上周的任务中&#xff0c;我们使用torchtext下载了托管的英文的…

Web 框架

Web 框架 Web服务器Web服务器的主要功能常见的Web服务器软件包 Web 框架常用 Python Web 框架选择Python Web框架的考虑因素 WSGIWSGI的主要特点WSGI的工作原理常见的WSGI服务器和框架&#xff1a; 静态资源定义与特点静态资源的类型静态资源的管理与优化 动态资源定义与特点动…

Java入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享

场景 作为一名Java开发者&#xff0c;势必经历过从入门到自学、从基础到进阶、从学习到强化的过程。 当经历过几年企业级开发的磨炼&#xff0c;再回头看之前的开发过程、成长阶段发现确实是走了好多的弯路。 作为一名终身学习的信奉者&#xff0c;秉承Java体系需持续学习、…