C 宏的作用域规则

2023-12-12

我不是一个 C 程序员,但我假设 C 宏几乎是一种查找和替换功能,其中预处理器获取宏定义并将其放在它看到宏名称的任何位置。

这是 Dragon Book 的动态范围规则及其如何应用于宏的示例:

#define a (x + 1)

int x = 2;
void b () { int x = 1; printf("%d\n", a); }
void c () { printf("%d\n", a); }
void main () { b(); c(); }

他们还讨论了动态范围规则如何应用于名称x宏内a。我的假设是它基本上会取代a with (x + 1)然后编译程序,因此范围规则将与您编写的完全相同(x + 1)代替a(这将是静态范围规则)。

有人能澄清一下吗?

编辑:所指的书是《编译器:原理、技术和工具第二版》。引用的示例来自第 31-32 页。


您对 #define 行为的理解是正确的。

我认为这本书所说的“动态作用域”的意思是名称 x 是根据调用宏的环境而不是定义它的环境来解析的。因此,如果您在 #define 之前设置了全局变量 x=3,则这与 #define 中 x 的值无关 - 无论您使用宏,它都会使用 x 的值 - 如果还有其他本地变量如果在使用宏的函数中使用变量 x,则将使用本地值。

这与词法作用域(C 语言和几乎所有现代语言中实际使用的)形成鲜明对比,在词法作用域中,名称指的是其本地词法环境。例如,如果您将示例中的 #define 替换为简单语句a = x+1,那么函数中 a 的值将比此时 x 的值大 1a = x+1出现在代码中。如果您使用值 a 时碰巧存在其他名为 x 的局部变量,也没关系。类似地,如果你定义了一个函数int f() { return x + 1; }, x 将引用全局变量 x,而不是调用 f() 时恰好存在的其他名为 x 的局部变量。如果这看起来非常明显,那是因为,正如我所说,几乎所有语言都使用词法作用域(尽管 Perl 也允许使用动态作用域)local功能)。

See http://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scoping_and_dynamic_scoping对这个概念有更多的解释。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 宏的作用域规则 的相关文章

随机推荐

  • 当多次调用外部函数时,php 中的嵌套函数会引发异常

    以免假设我有以下内容 function a function b a pass a error 为什么在第二次调用中抛出异常并且它说 cannot re declare function b 我认为每个函数调用都会创建一个新的活动记录 它包
  • 是否可以更改 h:outputStylesheet 和 h:outputScript 使用的 /resources 文件夹名称

    引用css文件和js文件时是否需要给文件夹名称 resources h outputStylesheet and h outputScript 因为当我给出文件夹名称 assets 而不是 resources 时 这些文件不会加载 这就是我
  • 将 iPad 应用程序转换为 iPhone 应用程序?

    我编写了一个基于选项卡的 iPad 应用程序 效果很好 我从来没有打算让它成为一个 iPhone 应用程序 因为它显示的内容确实不适合这么小的屏幕 然而 我收到了很多要求该应用程序也与 iPhone 兼容的请求 有人可以向我指出一些文档的方
  • Javascript 无缘无故地将浮点数转换为整数

    我编写了一个函数 它的行为根据其参数的数字类型而有所不同 整数或浮点数 使用这个问题中的一些代码如何检查一个数字是浮点数还是整数 很容易检测是否浮动 但后来我偶然发现了 javascript 强制转换的情况1 0 to 1如果您使用该号码调
  • 莫里斯图未更新

    我的更新有问题morris js条形图 当页面加载时 我有以下函数 它运行良好并创建了一个漂亮的图表 document ready function if projectViewTotal length chart Morris Bar e
  • 从数据库中检索一行作为 Hibernate 中的映射

    Table Players ID name email age 1 bob null 23 该表是类的实例Player被持久化 每个实例一行 没有组合等 冬眠Session 我如何获得该行 假设 id PK 等于 1 作为 Java 地图
  • 具有波斯语/阿拉伯语字符的Python 3 print() 函数[重复]

    这个问题在这里已经有答案了 我简化了代码以便更好地理解 这是问题所在 case 1 coding utf 8 text also using u results the same print text output UnicodeEncod
  • 在 AWS Lambda 中将 DynamoDB 数据格式化为普通 JSON

    我在用着AWS Lambda扫描数据DynamoDB桌子 这就是我得到的回报 videos file S file1 mp4 id S 1 canvas S This is Canvas1 file S main mp4 id S 0 ca
  • 如何将 CSV 文件直接发送到 FTP 服务器

    我的问题是如何将 CSV 文件发送到 FTP 服务器 如您所见 以下脚本是我当前的代码 代码示例 def download outage info all request upload data download data form req
  • WordPress 致命错误:第 1832 行的 wp-includes/wp-db.php 中允许的内存大小 536870912 字节已耗尽(尝试分配 77 字节)

    我最近注意到我的 WordPress 网站有时会收到 500 内部服务器错误 我检查了日志 有很多行 例如 2016 年 10 月 3 日星期一 01 25 24 357439 fcgid 警告 pid 12840 客户端 83 27 21
  • 在父 div 内对角排列 2 个 div

    我试图在父 div 内排列 2 个 div 这样看起来父 div 被对角线分成两部分 下图将显示需要什么 这是我尝试过的代码 App js import React Component from react import App css c
  • Cube on Cube 碰撞检测算法?

    我试图找到最有效的方法来检查两个任意大小的立方体是否相互碰撞 立方体的边长不一定都相等 盒子是可能的 考虑到这些限制 我如何有效地检查它们是否发生冲突 每个盒子有 24 个顶点 谢谢 它们是轴对齐的 由于两个框都是轴对齐的 因此您可以比较它
  • 升级到 VS2010 和 Re#5 后 SQLite 相关的 nUnit 测试出现问题

    使用 ReSharper5 转换为 Visual Studio 2010 后 我的一些单元测试开始失败 更具体地说 这适用于使用 NHibernate 和 SQLite 的所有单元测试 这个问题似乎与 SQLite 有关 不涉及NHiber
  • 如何在没有边框的表单周围添加阴影?

    我试图弄清楚如何使用 WinForms 在无边框表单周围添加完整的阴影 我正在考虑在表格的四个侧面周围添加阴影 我尝试过使用 DropShadow 类 尽管它只将阴影添加到底角和右侧角 我之前在搜索中多次看到这个问题被问到 但我发现没有任何
  • 如何仅在线性布局的一侧绘制边框?

    我能够将边框绘制到线性布局 但它是在所有侧面绘制的 我想将其限制为仅在右侧 就像在 CSS 中所做的那样 border right 1px Solid red 我已经尝试过这个 但它仍然吸引各方
  • CSS 变量在 Microsoft Edge 中的工作方式是否有所不同?

    我正在开发一个网站 并针对 Firefox 和 Chrome 对其进行了优化 该项目包含一个名为base css它包含在所有页面中 并且包含一些全局设置和定义 包括我用来存储颜色值的变量列表 如下所示 root yellow 1 fff8e
  • Internet Explorer 的永恒重新加载页面

    我在 Internet Explorer 7 上使用 FB 应用程序时遇到问题 我正在使用FB前一段时间提供的这段代码 auth url http www facebook com dialog oauth client id FACEBO
  • 指令集架构的定义是什么?

    我试图弄清楚指令集架构 ISA 到底是什么 根据我所读到的内容 我有两种解释 我的第一个解释是 ISA 是所有寄存器 汇编指令和伪指令 汇编指令以及构成汇编语言的指令格式的集合 可用于对实现指令集的处理器进行编程 我的第二种解释是 ISA
  • 清除 C# 表单上所有控件的最佳方法是什么?

    我记得不久前看到有人问过类似的问题 但我进行了搜索 但找不到任何东西 我试图想出最干净的方法来将表单上的所有控件清除回默认值 例如 清除文本框 取消选中复选框 你会怎么做呢 到目前为止我想出的是这样的 public static class
  • C 宏的作用域规则

    我不是一个 C 程序员 但我假设 C 宏几乎是一种查找和替换功能 其中预处理器获取宏定义并将其放在它看到宏名称的任何位置 这是 Dragon Book 的动态范围规则及其如何应用于宏的示例 define a x 1 int x 2 void