c 语言的 宏 是自动根据值来确定类型的??
#define str "虽然没有声明类型,但是我就是一串字符串"
// 虽然没有声明类型,但我就是一个 int 类型的值
#define numForInt 10
int main(void) {
char res[100] = "hello boy ";
// 字符串拼接
// 他不会允许:strcat_s(res , sizeof res , numForInt)
// 很显然,虽然 numForInt 没有声明数据类型
// 但程序就把他当做成 int 类型了
strcat_s(res , sizeof res , str);
system("pause");
return 0;
}
这边没搞清楚 宏 的实际应用价值是什么??我感觉他和 变量 的作用是一样的..,而且相比变量感觉由于没有声明数据类型,在使用上更加不方便...
请问 宏 的实际应用价值是什么??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
宏是不带类型信息的, 只是preprocessor的一个文本替换的, 与之相对的c++的模板则带有类型信息.
原理
简单的说, 就是文本替换, 只不过基于文本替换可以玩出来些花样.
实际应用价值
性能 能省去函数调用的开销, 实现真正意义上的inline.
实现泛型与重载 c是不支持这俩货的, 一定层面, 宏可以实现其功能, 很经典的一个例子:
#define max(a,b) ((a)<(b)?(b):(a))
, 可以传int, float等等, 你可以理解为支持了重载, 也可以理解为支持了泛型, 虽然很丑陋233. 再举个不那么常见的:这样就直接定义了多个类型的pair. 也是对泛型的模拟.
就是不方便呀, 而且不只是缺乏类型, 更重要的是它的scope是dynamic scope, 而不是大家所熟知的lexical scope, 前者的name lookup是在调用处寻找, 而后者则是在定义处. 这有时候会造成混乱.
什么时候可以用?
什么时候不该用?
能不用的时候就别用
Update
回复OP的疑问: 你给的这两个链接的说法都不对. inline这个keyword和语义inline本身无关, 你添加了inline其实不会对编译器有什么影响. 编译器有自己的判断. c的inline是c99开始出现的, 貌似是学c++的. c语言的odr(或者说c其实是没有odr的, 这里只是代指那套规则)我不是很熟悉, 不过在c++里面inline关键词的作用就是屏蔽odr检查. 和inline的语义(内联)没有任何关系. 泛型的话也别看百度百科, 里面问题一大堆. 多搜英文资料. 或者写写c++的模板就知道了. 上面那个pair应该还是很容易看出泛型在c里面的应用的. 不只是primitive type, 其实你自己的结构体也可以这样很轻松的做出搞出来pair.
宏只是简单的源代码文本替换。就是源代码中所有使用到该宏的地方都被直接替换为宏定义的内容。这在编译前的预处理阶段搞定的。后面的编译器是看不见宏的。
宏的实际应用价值就是轻松执行替换啊。
还有就是广泛应用于预编译分支控制。就是用在
#if #ifdef #ifndef
等等后面。==多谢赞同,再补充==
有时候建议使用const变量而不是使用宏来定义这些常量。因为宏真的只是最简单的几乎等于文本替换,没有类型,使用不当的还可能对使用处的代码造成别的干扰。比如运算符优先级等等。
也因为宏仅仅是文本替换,宏后面甚至可以定义大段大段的代码,比如GTest等使用的各种宏来简化代码,在宏里塞个类定义函数定义什么的。
有兴趣可以了解更多的宏使用技巧和注意事项。
首先类型在你说的“值”那里已经确定下来了。在你的代码中
"虽然没有声明类型,但是我就是一串字符串"和10,这些是字面常量。真正有类型的是他们,不是str,numForInt 这些符号。要说有什么实际应用的价值的话,我没学太深,我只知道宏可以用来定义符号常量,和常变量(const)不同,他不用再占用多一个某个类型对应大小的空间,如果代码中很多地方都用到这个常量,只需要在定义它的地方修改一次就可以了
链接:宏的讲解
这里有很多的用法讲解,我常用的情景是多处使用某个特定值的时候,我选择使用宏。这样修改的时候,只需要修改一处就能作用到所有需要使用到它的地方,方便修改。