在CS编程学习中,宏定义在C系开发中有着占有举足轻重的作用,在减少工作量的同时,代码可读性大大增加。如果想成为一个能写出漂亮优雅代码的开发者,宏定义绝对是必不可少的技能。但是宏代码也存在一定的缺陷,使用宏代码最大的缺点是易于出错,预处理器在复制宏代码时常常产生意想不到的边际效应。下面由洋蜜蜂CS辅导tutor来简述替代宏代码的一些应用。
宏不遵守C ++范围和类型规则。这通常是微妙而不那么微妙的问题的原因。因此,C ++提供了更好地适应C ++其余部分的替代方法,例如内联函数,模板和命名空间。
考虑:
#include“someheader.h”
struct S {
int alpha;
int beta;
};
如果有人(不明智地)编写了一个名为“alpha”的宏或一个名为“beta”的宏,这可能无法编译或(更糟)编译成意外的东西。例如,“someheader.h”可能包含:
#define alpha'a'#
define beta b [2]
诸如在ALLCAPS中具有宏(并且仅具有宏)的约定有帮助,但是没有针对宏的语言级保护。例如,成员名称在结构范围内的事实没有帮助:宏在编译器正确看到它之前作为字符流操作程序。顺便说一句,这是C和C ++程序开发环境和工具不成熟的一个主要原因:人和编译器看到不同的东西。
不幸的是,你不能假设其他程序员始终避免你认为“真正愚蠢”的东西。例如,有人最近向我报告说他们遇到了一个包含goto的宏。我已经看到了这一点,并且听到的论点可能 - 在一个微弱的时刻 - 似乎是有道理的。例如:
#define前缀get_ready(); int ret__
#define返回(i)ret __ = i; do_something(); goto exit
#define suffix exit:cleanup(); return ret__
int f()
{
prefix;
// ...
返回(10);
// ...
返回(x ++);
// ...
suffix;
}
想象一下,作为维护程序员被提出来; 将宏隐藏在标题中 - 这并不罕见 - 使得这种“魔法”难以发现。
最常见的一个细微问题是函数式宏不遵守函数参数传递的规则。例如:
#define square(x)(x * x)
void f(double d,int i)
{
square(d); // fine
square(i ++); // ouch:mean(i ++ * i ++)
square(d + 1); // ouch:mean(d + 1 * d + 1); 也就是(d + d + 1)
// ...
}
通过在“调用”或宏定义中添加括号来解决“d + 1”问题:
#define square(x)((x)*(x))/ *更好* /
但是,i ++(可能是非预期的)双重评估的问题仍然存在。
是的,我知道有些东西称为宏,不会遇到C / C ++预处理器宏的问题。我建议使用C ++语言中的工具,例如内联函数,模板,构造函数(用于初始化),析构函数(用于清理),异常(用于退出上下文)等。
以上是洋蜜蜂CS辅导tutor的一些编程建议,大家可以根据实际情况进行选择不同处理方法,恰如其分地使用它们。虽然这会使我们编程时多费一些心思,少了一些痛快,但这才是编程的艺术。
洋蜜蜂辅导机构争当海外留学的引导者,创新式辅导模式与海外名校师资,旨在为学生学有所成,提供各方位的服务,包括CS课程辅导,选课咨询,写作辅导等服务。
更多课程资讯,详情可点开洋蜜蜂官网即可获得更多,如果有CS课程辅导需求,可以咨询24小时在线客服微信:yuff996,洋蜜蜂助你度过学习难关。