【C++】常用技巧

static int* (*const p[])();

p是一个函数指针静态常量数组,即p是静态成员变量,p的成员是函数指针且不能修改p的数组成员指向。p的成员函数指针指向的是空入参、返回值是int指针的函数。

i += !!i

若i为0,则!i为1;若i为非0,则!i为1。所以,若i为0,!!i为0;若i为非0,则!!i为1。
所以,此表达式的含义是当i为0或无效(NULL)时,i不变;若i当前值有效(非0)时,则加1(指向下一个)。

枚举位运算

首先复习一下位运算符:

运算符含义示例说明
&位ANDx&y当且仅当x=y=1时,结果为1,否则为0
|位ORx|y当且仅当x=y=0时,结果为0,否则为1
^位XORx^y当x=y时,结果为0;当x≠y时,结果为1
~位NOT~x当x=1时,结果为0;当x=0时,结果为1
<<向左位移x<<yx的每位向左移动y位
>>向右位移x>>yx的每位向右移动y位

对于表达式x<<y,其中若x=1,则表达式为1<<i。该表达式表示 2 i 2^{i} 2i:
1<<0 ⟹ \Longrightarrow 0001 ⟶ \longrightarrow 0001
1<<1 ⟹ \Longrightarrow 0001 ⟶ \longrightarrow 0010
1<<2 ⟹ \Longrightarrow 0001 ⟶ \longrightarrow 0100
1<<3 ⟹ \Longrightarrow 0001 ⟶ \longrightarrow 1000

下面说明两个常见的枚举位表示及运算:

enum Enum1 : unsigned
{
	First			= 1 << 0,		//0001
	Second			= 1 << 1,		//0010
	Third			= 1 << 2,		//0100
	Fourth			= 1 << 3,		//1000
}

//unsigned也可以是Enum1类型。下面为位或运算,如果将Enum1枚举的每项看作标识符,则i可以同时表示First和Third。
unsigned i = (First | Third);	// 0001 | 0100 = 0101

//移除标识。下例表达式将会把Third从i中移除。
unsigned newi = i & ~Third;  //i & ~Third
i = newi;

//判断i是否标识某个标识符
//i & First => true, 0101 & 0001 = 0001
//i & Third => true, 0101 & 0100 = 0100
if(i & First) {}

//判断i中是否包含任意或所有某个标识符集合。
Enum1 i = (First | Third | Fourth);
Enum i1 = (First | Second);
Enum i2 = (First | Third);
Enum i3 = (First | Second);

//判断i中是否包含i1中的某项。i1中的Second项虽然不在i中,但是i却包含First项,所以此处为true。
if((i & i1) != 0) {}
//判断i中是否包含i2的所有项。因为i中既包含First和Third,所以为true。
if((i & i2) == i2) {}
//因为i中不包含i3中的Second项,所以为false。
if((i & i3) == i3){}

直接使用十六进制表示枚举值:

enum Enum2
{
	None			= 0x00000000u,
	First			= 0x00000001u,
	Second			= 0x00000002u,
	Third			= 0x00000004u,
	Fourth			= 0x00000008u,
	Fifth			= 0x00000010u,
	Sixth			= 0x00000020u,
	Seventh			= 0x00000040u,
	Eighth			= 0x00000080u,
	Ninth			= 0x00000100u,
	...
}
//枚举值使用十六进制显式表示

结构体指针转换

不同类型的结构体指针可以进行任意转换,因为指针只是指向内存中的某一地址。对于结构体指针,它就是指向结构体在内存中的起始地址。所以,可以不同结构体指针间可以进行转换。下面给一个应用中的例子:

enum EStructType
{
	Int,
	Double,
	Object
}

struct FTypeBase
{
	EStructType Type;
}

struct FInt
{
	EStructType Type;
	int Index;
}

struct FDouble
{
	EStructType Type;
	double Number;
}

struct FObject
{
	EStructType Type,
	Object* Obj;
}
static FInt NewInt = {Int, 88};
static FDouble NewDouble = {Double, 0.88};
static FObject NewObject = {Object, new Object()};
//把不同类型的结构体对象获取它们的结构体指针保存到数组,这样就可以统一保存和调用。
static FTypeBase* TypeBaseArray[] = 
{
(FTypeBase*)&NewInt,	//NewInt结构体指针保存到数组
(FTypeBase*)&NewDouble,
(FTypeBase*)&NewObject
};
//根据Type判断结构体类型,然后转换会对应的结构体指针
if(TypeBaseArray[0]->Type == Int)
{
	FInt* CastInt = (FInt*)TypeBaseArray[0];
	int Index = CastInt->Index;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值