有关带参数的宏定义的问题

img


c语言中字符串不是带有双引号吗,为什么这里没有?这里按理来说下面的红色指向的那个应该有双引号啊。

形式
#define 宏名 字符串
(1)宏名是作为标识符,命名规则与变量相同。字符串则可以是数字、表达式、语句、函数等。

(2)字符串为简单的字符序列,不同于C语言中的字符串,不需要加双引号。

(3)程序中反复使用的表达式就可以使用宏定义

注意
(1)实质:只替换,不计算

(2)用宏名来表示一个字符串,在宏展开时又以该字符串替换宏名。出现错误,只能在编译已被宏展开后的源程序时发现。

(3)必须写在函数之外,其作用域为宏定义开始到程序结束。

(4)代码中被引号引起来的,不会被替换。

(5)宏名可以大小写任意。

(6) 不是说明和语句,不需要分号结尾。

带参数
#define add(a,b) a>b?a,b

只是替换不需要写明类型,形参加的空格,就会变成add (a,b)a>b?a,b

在预处理的时候就被处理掉了,不会参与编译,也不会占用内存

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7452691
  • 你也可以参考下这篇文章:C语言-将数组中的数按颠倒的顺序重新存放。在操作时,只能借助一个临时存储单元而不得另外开辟数组。
  • 同时,你还可以查看手册:c语言-内存模型与数据竞争 中的内容
  • 除此之外, 这篇博客: C语言既有高级语言又有低级语言的特点,但为什么它不是低级语言呢?中的 理解 C 语言 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    低级语言的一个关键属性是程序员可以很容易地理解语言的抽象机如何映射到底层物理机。在 PDP-11 上肯定是这样的,因为每个 C 语言表达式都映射到一至两个指令。类似地,编译器将局部变量直接降到栈槽,并将原始类型映射成 PDP-11 可以直接操作的元素。

    从那时起,为了维护人们对 C 语言可以很容易映射到底层硬件并能够提供快速执行的代码的印象,C 语言的实现变得越来越复杂。2015 年的一份针对 C 语言程序员、编译器开发者和标准委员会成员的调查指出了几个有关 C 语言可理解性的问题。例如,C 语言的实现可以填充结构体(不是数组),以确保所有字段都能够对齐目标。如果将结构体归零,然后设置一些字段,那么填充位是否都为零?根据调查结果,36%的人表示会是零,29%的人表示不知道。事实上,根据编译器(和优化级别)的不同,它可能是也可能不是。

    这是一个相当简单的例子,但很大一部分程序员的理解要么是错的,要么不确定。当你在使用指针时,C 语言的语义就会变得更加混乱。BCPL 模型非常简单:值就是单词。每个单词就是某些数据或某些数据的地址。内存是通过地址进行索引的扁平存储单元阵列。

    相比之下,C 语言模型允许在各种目标平台上实现,包括分段式架构(指针可能是分段 ID 和偏移量),甚至是基于垃圾回收机制的虚拟机。C 语言规范十分谨慎地限制对指针的操作,以避免此类系统出现问题。人们对 C 语言缺陷报告 260 的反应就包括了指针起源(provenance)的概念。

    然而,“起源”这个词根本没有出现在 C11 规范中,所以完全由编译器来决定它的含义。例如,GCC(GNU 编译器集合)和 Clang 在对指针进行强制转换是否保留起源这个问题上存在不同的理解。编译器可以自由决定指向不同 malloc 结果或栈分配的两个指针总是不相等,即使指针的按位比较操作可能显示它们描述的是相同的地址。

    这些误解本质上不是纯粹的学术问题。例如,我们已经从有符号整数溢出(C 语言的未定义行为)和一些代码中找到了安全漏洞。对于后者,在进行空值检查之前取消引用指针是在告诉编译器指针不能为空,因为取消引用空指针在 C 语言中是未定义行为,因此可以假定这种情况不会发生(https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-1897)。

    因此,我们很难说程序员可以准确理解 C 语言程序将如何映射到底层架构。

     

  • 您还可以看一下 李飞老师的C语言开发之数据结构与算法一课程中的 链表实现栈小节, 巩固相关知识点

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^