c/c++ 奇技淫巧(一些c语言的技巧)
一. 变长数组 严格说来,变长数组的实现在c++中并不是一件麻烦的事情。Stl中的vector本身就是一个变长数组,并且有自动管理内存的能力。 Struct MutableLenArray { Int count; Char* p; }; P = new Char[Count]; 没什么问题,但是C语言的使用者有个最大的自豪就在于对于效率、空间使用的掌控。他们会有这样的疑问,如果count=0,那么p就没必要了,白白占了4(64位系统为8)个字节的空间,简直浪费。 Struct MutableLenArray { Int count; Char p[0]; }; 和上面的结构使用方法一致,但是我们可以用sizeof尝试读取其大小,发现竟然只有count字段的长度4字节,p没有被分配空间。完美! 二. 宏的妙用 1. #和 “#”符号把一个符号直接转换为字符串,例如: #define TO_STRING(x) #x const char *str = TO_STRING( test ); str的内容就是”test “,也就是说#会把其后的符号 直接加上双引号。 ##符号会连接两个符号,从而产生新的符号(词法层次),例如: #define SIGN( x ) INT_##x int SIGN( 1 ); 宏被展开后将成为:int INT_1; 2. 变参宏 #define LOG( format,... ) printf( format,__VA_ARGS__ ) LOG( "%s %d",str,count ); VA_ARGS是系统预定义宏,被自动替换为参数列表。 3. 宏参数的prescan prescan的定义:当一个宏参数被放进宏体时,这个宏参数会首先被全部展开(有例外,见下文)。当展开后的宏参数被放进宏体时, 预处理器对新展开的宏体进行第二次扫描,并继续展开。例如: #define PARAM( x ) x #define ADDPARAM( x ) INT_##x PARAM( ADDPARAM( 1 ) ); 因为ADDPARAM( 1 ) 是作为PARAM的宏参数,所以先将ADDPARAM( 1 )展开为INT_1,然后再将INT_1放进PARAM。 #define PARAM( x ) #x #define ADDPARAM( x ) INT_##x PARAM( ADDPARAM( 1 ) ); 将被展开为”ADDPARAM( 1 )”。 所以此时要得到“INT_1”的结果,必须加入一个中间宏: #define PARAM(x) PARAM1(x) #define PARAM1( x ) #x PARAM( ADDPARAM( 1 ) );此时的结果将会是“INT_1”。根据prescan原则,当ADDPARAM(1)传入,会展开得到INT_1,然后将INT_1带入PARAM1宏,最终得到“INT_1”的结果。 4. 接口宏 以下部分,摘自网上博客,仅作声明。 // .h File class Element { void Tick (); }; // .cpp File void Element ::Tick () { // todo } 由于Tick的标识在两个地方都出现了,因此如果我们需要改变这个方法的参数的时候(改变函数名、返回类型或者加const),我们需要改变两个地方。 class Animal { public: virtual std :: string GetName () const = 0 ; virtual Vector3f GetPosition () const = 0; virtual Vector3f GetVelocity () const = 0; }; 同时,这个基类拥有三个派生类――Monkey,Tiger,Lion。 #define INTERFACE_ANIMAL(terminal) public: virtual std::string GetName() const ##terminal virtual IntVector GetPosition() const ##terminal virtual IntVector GetVelocity() const ##terminal #define BASE_ANIMAL INTERFACE_ANIMAL(=0;) #define DERIVED_ANIMAL INTERFACE_ANIMAL(;) 值得一提的是,##符号代表的是连接,符号代表的是把下一行的连起来。 // Animal.h class Animal { BASE_ANIMAL ; }; // Monkey.h class Monkey : public Animal { DERIVED_ANIMAL ; }; // Lion.h class Lion : public Animal { DERIVED_ANIMAL ; }; // Tiger.h class Tiger : public Animal { DERIVED_ANIMAL ; }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |