21天学C++(二一)进一步掌握的内容

完整目录、平台简介、安装环境及版本:参考《21天学C++ 概览》

二一、进一步掌握的内容

21.1 预处理和预编译

21.1.1 #include:运行编译时,预处理器先运行

预处理器查找预处理指令,即以”#”开头的指令,用来改变源代码的文本,生成新的源文件(临时文件);

#include指示预处理器查找其后文件并将文件写入该位置;

21.1.2 #define:定义字符串替换,如#define BIG 512

只是预处理器在任何看到BIG的地方用字符串512替换;
如int myArray[BIG];预处理器长生的中间文件是int  myArray[512];

使用define可以替换常熟,但由于define直接替换不做类型检查,所以关键字const比denfine有优势;

21.1.3 编译器预定义了大量有用的宏,如_DATE_、_TIME_等两条下划线

21.1.4 #ifdef      #ifndef    #endif

   #ifdef DemoVersion
      ...;
   #endif
#ifdef DemoVersion
      ...;
   #else
      ...;
   #endif
 #ifndef SW_VERSION
      ....;
   #endif
 #ifndef SW_VERSION
      ....;
   #else
      ....;
   #endif
#define DemoVersion
#define SW_VERSION 5
#include <iostream>

using std::endl;
using std::cout;

int main()
{
#ifdef DemoVersion
	cout << "DemoVersion defined." << endl;
#else
	cout << "DemoVersion not defined." << endl;
#endif

#ifndef SW_VERSION
	cout << "SW_VERSION not defined!" << endl;
#else
	cout << "SW_VERSION defined as: "
		<< SW_VERSION << endl;
#endif

#ifdef WINDOWS_VERSION
	cout << "WINDOWS_VERSION defined!" << endl;
#else
	cout << "WINDOWS_VERSION was not defined." << endl;
#endif

	cout << "Done."  << endl;
	return 0;
}

执行结果如下:

DemoVersion defined.
SW_VERSION defined as: 5
WINDOWS_VERSION was not defined.
Done.
请按任意键继续. . .

21.1.5 避免头文件重复包含

#ifndef _FILE_H
#define _FILE_H
     //file.h文件内容
#endfi

第一次调用时,没有定义头文件宏,接着定义并包含头文件。第二次调用时,由于第一次已经定义了头文件宏,所以直接跳转到#endif

#ifndef _FILE1_H
#define _FILE1_H

#include <iostream>
using namespace std;

void file1(){
	cout<<"file1  "<<endl;
}

#endif
#ifndef _FILE2_H
#define _FILE2_H

#include <iostream>
#include "file1.h"
using namespace std;

void file2(){
	cout<<"file2  ";
	file1();
}
#endif
#include <iostream>
using namespace std;
#include "file1.h"
#include "file2.h"

int main(){
	cout<<"main "<<endl;
	file2();
	file1();
	return 0;
}

执行结果如下:

main
file2  file1
file1
请按任意键继续. . .

21.2 宏函数

#define可以创建宏函数,直接进行替换

#define TWICE(X) ((X)*2)   //倍数
#define MAX(x,y) ((x)>(y)?(x):(y))  //取两个值的最大值
#define MIN(x,y) ((x)<(y)?(x):(y))    //取两个值的最小值

#define宏函数为总要用括号

括号可以避免不必要的副作用,特别是在传递复杂表达式的情况下

#define 存在最大的问题就是类型安全问题

#include <iostream>
using namespace std;

#define CUBE(a) ( (a) * (a) * (a) )
#define THREE(a) a * a * a

int main()
{
	long x = 5;
	long y = CUBE(x);
	long z = THREE(x);

	cout << "y: " << y << endl;
	cout << "z: " << z << endl;

	long a = 5, b = 7;
	y = CUBE(a+b);
	z = THREE(a+b);

	cout << "y: " << y << endl;
	cout << "z: " << z << endl;
	return 0;
}

执行结果如下:

y: 125
z: 125
y: 1728
z: 82
请按任意键继续. . .

21.3 内联函数inline

经常声明内联函数而不是宏

代码替换,不会发生函数调用的系统开销

#include <iostream>
using namespace std;

inline unsigned long Square(unsigned long a) { return a * a; }
inline unsigned long Cube(unsigned long a)
{ return a * a * a; }
int main()
{
	unsigned long x=1 ;
	for (;;)
	{
		cout << "Enter a number (0 to quit): ";
		cin >> x;
		if (x == 0)
			break;
		cout << "You entered: " << x;
		cout << ".  Square(" << x << "): ";
		cout  << Square(x);
		cout<< ". Cube(" << x << "): ";
		cout << Cube(x) << "." << endl;
	}
	return 0;
}

执行结果如下:

Enter a number (0 to quit): 3
You entered: 3.  Square(3): 9. Cube(3): 27.
Enter a number (0 to quit): 2
You entered: 2.  Square(2): 4. Cube(2): 8.
Enter a number (0 to quit): 0
请按任意键继续. . .

21.4 assert()

assert()

  • 参数值为TRUE时,返回TRUE;
  • 参数值为FALSE时,则执行某种操作;如终止程序或抛出异常;
  • 开发过程中很有帮助,只有在DEBUG模式下起作用;
  • 开发过程中很有帮助,在RELEASE产品形成时不会有性能损失,也不会增加可执行文件的大小;

assert()与异常

  • assert不能处理运行时的错误条件,如错误数据、内存不足、不能打开文件等;
  • assert只能捕捉编程错误,即如果assert提示了,则说明代码中有一个bug;
  • 在正式发布的版本中assert会自动隐藏,不能指望assert处理运行时问题,因为assert已经不存在了;

assert()副作用

  • 当向进行值测试时,如ASSERT(x==5);本来是想测试是否等于5,结果成一个难发现的BUG;
#define DEBUG
#include <iostream>
using namespace std;

#ifndef DEBUG
#define ASSERT(x)
#else
#define ASSERT(x) \
	if (! (x)) \
{ \
	cout << "ERROR!! Assert " << #x << " failed" << endl; \
	cout << " on line " << __LINE__  << endl; \
	cout << " in file " << __FILE__ << endl;  \
}
#endif

int main()
{
	int x = 5;
	cout << "First assert: " << endl;
	ASSERT(x==5);
	cout << "\nSecond assert: " << endl;
	ASSERT(x != 5);
	cout << "\nDone." << endl;
	return 0;
}

执行结果如下:

First assert:

Second assert:
ERROR!! Assert x != 5 failed
 on line 24
 in file e:\study\source\c++\21005_assert\main.cpp

Done.
请按任意键继续. . .

21.5 打印中间值DEBUG

除了assert外,如果想打印指针、变量、字符串的当前值

#include <iostream>
using namespace std;
#define DEBUG

#ifndef DEBUG
#define PRINT(x)
#else
#define PRINT(x) \
	cout << #x << ":\t" << x << endl;
#endif

enum BOOL { FALSE, TRUE } ;

int main()
{
	int x = 5;
	long y = 73898l;
	PRINT(x);
	for (int i = 0; i < x; i++)
	{
		PRINT(i);
	}

	PRINT (y);
	PRINT("Hi.");
	int *px = &x;
	PRINT(px);
	PRINT (*px);
	return 0;
}

执行结果如下:

x:      5
i:      0
i:      1
i:      2
i:      3
i:      4
y:      73898
"Hi.":  Hi.
px:     012FFBBC
*px:    5
请按任意键继续. . .

发表回复