关于#define、typedef、using
一、#define
#define 指令将标识符定义一个宏,编译器会将所有的标识符替换为相应的内容。宏定义不是说明或者语句,在行末尾不必添加分号;要终止宏定义可以使用#udef;宏名在源程序中被括号括起来后再编译时不会替换;宏定义可以嵌套。
1、宏展开:定义常量、定义函数
#define <标识符> [<替换列表>]
#define <标识符>([参数列表],...) <替换列表>
利用#define来定义常量,程序在编译的时候会将相同的字符进行替换,当替换列表中含有多个字符的时候,最好的将替换列表用圆括号括起来。也可以定义一些简单的函数,但因为只是简单的替换,有时后会发生一些错误,谨慎使用,在替换列表中的各个参数最好使用圆括号括起来。
#define maxnum 1000
#define add(a,b) (a+b);//此处要打括号,不然执行A*add(a,b)*C 会变成 A*a+b*C
通过#define (windows、debug),可以选择需要编译的代码,这在跨平台或者调试的时候有很好的帮助。
#ifdef windows
...
#else
...
#endif
#ifdef debug
...
...
#endif
在引入头文件的过程中,由于头文件往往会互相包含,因此容易出现重复包含定义的问题。
#ifndef _HEADFILE_
#define _HEADFILE_
...
...
#endif
5、与特殊字符构成更多替换功能(##,#,#@,...)
二、typedef
typedef <类型> <别名>;
typedef 顾名思义就是类型的别名,也就是类型的另一个名字。对于有些复杂的类型名称,使用typedef后可以精简程序书写,减少拼写错误。
1、简单内置类型别名
typedef unsigned int Uint;
//a,b类型相同
usigned int a;
Uint b;
2、复合类型的别名
//两种方式效果一样
typedef int* p;
typedef int *p;
//下面两种方式等价,但对于代码的理解方便程度不同。a为一个指向整型的指针,b为一个整型。
int* a, b;
int *a,b;
//下面这一种方式则不存在上述问题,a、b的类型均是指向整型的指针
p a,b;
3、自定义类型的别名
//结构体、类、数组、链表、树等别名
//结构体
typedef struct{int x; int y;} Point;
typedef srtruct point{int x; int y;} Point;
//类
typedef class{private: int x; public: int y;} MyClass
//数组
typedef int MyArray [10];//别名是放在中间
MyArray nums;//等价于 int nums[10];
4、函数指针的别名
typedef <return_type> (*<Aliases>)([<para1_type>],[<para2_type>],...)
bool LengthCopmare(const int &, const int &);
typedef (*pf)(const int &, const int &);
pf = LengthCopmare;//可以使用pf调用函数LengthCopmare
pf = &LengthCopmare;//等价
三、using
using [<别名>] = <类型等>
1、引入命名空间
using namespace std;
改变成员权限
3、类型、模板别名
using D = double;
using FunctionPtr = bool (*)(const int &, cont int &);//函数指针