工作中的学习

2016/08/01 有目标的学习确实效果不错

Posted by WangXiaoDong on August 1, 2016

时间:2016年8月1日 天气:晴:sunny:


Author:冬之晓:neutral_face:
Email: 347916416@qq.com
MyAppearance: MyAppearance

    今天,开始进行上周五收到的任务,要求给程序添加几个控件和实现的网络传输数据
的逻辑。研究了一下,感觉有目标的学习确实效果不错。一天下来学到了好多知识
,感觉程序学起来真的是很有意思,而且自己还有好多知识没有掌握!特别是以前我一
直只关注C++的基本语法和数据处理,实际上真正的项目中也需要网络编程、界面编程、
多线程编程、数据库编程等好多内容。因此未来这一段时间需要我仔细研究一下这些知
识!

条款02:尽量以const,enum,inline替换#define

尽量以const, enum, inline替换#define的意思是: 宁可以编译器替换预处理器。 为什么要用const代替宏? 原因太多, 我不一一列举。 看程序:

  • 为啥用const代替宏呢?
#include <iostream>
using namespace std;

#define PI 3.14

int main()
{
	cout << PI << endl;

	return 0;
}       

其中PI是一个宏, 不是一个变量, 所以预编译器提前处理了它, 编译器对它完全没有感知,无法调试。 所以, 宏容易引起错误, 且不便于调试。

  • 为什么要以enum带代替宏呢? 看看下面这个糟糕的程序吧:
#include <iostream>
using namespace std;

#define RED 0
#define BLACK 1
#define GREEN 2
#define YELLOW 3

int main()
{
	return 0;
}       

看看, 逻辑没个逻辑, 而且啰嗦, 还不如写成:

#include <iostream>
using namespace std;

enum
{
	RED,
	BLACK,
	GREEN,
	YELLOW
};

int main()
{
	return 0;
}
  • 为何用inline代替宏呢?看下面例子:
    #define square(a) a * a
    在main函数中调用时,可能会这样square(3),计算的是3的平方,这是OK的,但如果换成是square(1+2),计算的还是3的平方吗?注意这时编译器解释成1 + 2 * 1 + 2,这样2 * 1的优先级高一些,所以先做了,这就出问题了。

好的,这是常见的错误,有些程序员可能认为多加括号就行,比如:

#define square(a) (a) * (a)

这的确可以避免上面所说的优先级的问题,但万一调用时是这样写的呢?

int main()
{
    int v = 3;
    squre(++v);
}

本意是想求4的平方,但编译器会翻译成(++v)*(++v),这样v就被加了两次,这个结果肯定不是你想要的!

一句话,带参的宏很容易出问题,特别是针对复合操作(一句话做了不止一件事情)时,bug频出。

解决这个问题的方法是:用函数替换!因为函数调用时,若实参是表达式,总是会先计算这个表达式的值,再去进行调用的,不会出现宏展开时的bug。

还要注意类专属常量可以使用一下两种方法:

  • static(静态) const(常) T(类型) variable(变量名) = Num(变量值);的方法
  • enum(枚举) { variable(变量名) = Num(变量值) };的方法

请记住:

  • 对单纯常量,最好以const对象或enums替换#defines。
  • 对于形似函数的宏,最好改用inline函数替换#defines。