#define用法
1、简单宏定义
#define <宏名> <字符串>
例: #define PI 3.1415926
(与const定义常量的区别)
2、带参数的宏定义
#define <宏名>(形参表) <字符串>
在字符串中含有各个形参。
带参宏调用的一般形式为:
宏名(实参表);
例:#define MAX(a,b) ((a) > (b) ? (a) : (b))
以下来自 http://blog.chinaunix.net/uid-29067889-id-3819834.html
宏其实就是一个简单的文本替换
例子如下 :
#define Add(a,b)
a+b
但是如果遇到如 : c * Add(a,b) * d
的情况时,本意是a+b然後去和c,d相乘,但是因為使用了define(就是一个简单的文本替换),所以式子变成了:
c*a
+ b*d
应该定义为:#define Add(a,b) (a+b)
另外舉一個例子 :
#define pin (int*)
pin a,b;
本意是a和b都是int型指针,但是实际上变成了int*
a,b;
a是int型指针,而b是int型变量.
這是应该使用typedef来代替define,这样a和b就都是int型指针了。
应该定义为 typedef int* pin;
我们在写code的时候一定要养成一个良好的习惯和一个良好的代码编写风格,建议所有的层次都加上括号
3、define的多行定义
windows消息处理使用比较多,例如:
#define MSG_WM_CREATE(func) \
if (uMsg == WM_CREATE) \
{
\
SetMsgHandled(TRUE); \
lResult =
(LRESULT)func((LPCREATESTRUCT)lParam); \
if(IsMsgHandled())
\
return TRUE; \
}
4、定义宏和取消宏定义
定义一个宏使用#define,取消一个宏定义使用#undef
5、使用宏进行条件编译
格式如下:#ifdef ...
(#else) ... #endif
如:
#ifdef HELLO
#define WORLD 1
#else
#define WORLD 0
#endif
const用法
内容来自 http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html
已经很详尽了,我整理一下,便于自己理解的
1、用const声明的变量虽然增加了分配空间,但是可以保证类型安全。
2、将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率的原因,而不是想让调用函数能够修改对象的值。同理,将指针参数声明为const,函数将不修改由这个参数所指的对象。
3、修饰函数返回值,可以阻止用户修改返回值。返回值也要相应的付给一个常量或常指针。
4、
常量与指针
int main() { // your code goes here int i = 100; const int *p = &i; // p为常量指针,即p指向的值不能变 int* const q = &i; // q为指针常量,即q的值不能变 cout << i << endl; // 100 cout << *p << endl; // 100 cout << *q << endl; // 100 i = 300; cout << *p << endl; // 300,由于p指向i的地址,更改i的值可改变p指向的值 cout << *q << endl; // 300 int j = 200; //*p = j; // 编译出错,常量指针p指向的值不能变 p = &j; // p为常量指针,指针可变 //q = &j; // 编译出错,指针常量q的值不能变 *q = j; // q为指针常量,q指向的值可变 cout << j << endl; cout << *p << endl; cout << *q << endl; return 0; }
常量与引用
int main() { // your code goes here int i = 100; const int& m = i; // 正确 //int& const n = i; // 错误,const不能修饰int& //m = 100; // 错误,m为只读,不能改变 return 0; }
常量函数
class Test { private: int x; mutable int y; public: Test() { x = 100; y = 200; } int TestFun1() const { return x; } int TestFun1() { return ++x; } int TestFun2() const { return 100; } int TestFun3() const { // x++; // 编译错误,带有const限定符的函数内不能变更值 return ++y; // mutable修饰的变量,在const限定符的函数内可变更 } int TestFun4() { return ++x; } int TestFun5() const { Test* pThis = (Test*)this; ++(pThis->x); // 根据this指针重新定义了一个指向同一块内存地址的指针 // 通过这个新定义的指针,我们仍然可以修改对象的状态 return x; } void TestFun6(const Test& a, Test& b) { int m = a.TestFun1(); //a.TestFun4(); // 编译错误,const类型变量只能调用const类型函数 int n = b.TestFun1(); b.TestFun4(); cout << m << endl; // 100,重载函数,const变量调用const函数 cout << n << endl; // 101,重载函数,普通变量调用普通函数 } }; int main() { // your code goes here Test t, u; cout << t.TestFun1() << endl; // 100 cout << t.TestFun2() << endl; // 100 cout << t.TestFun3() << endl; // 201 cout << t.TestFun4() << endl; // 101 cout << t.TestFun5() << endl; // 102 t.TestFun6(u, u); return 0; }
typedef用法
整理来自 http://niehan.blog.techweb.com.cn/archives/325.html
1、定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。
char* pa, pb; // 本意是声明两个char*类型,实际是pa为char*类型,pb为char类型
那么修改为:
typedef char* PCHAR;
PCHAR pa, pb;
也可以:
char *pa, *pb;
2、 struct定义
// C/C++代码中都可以这样定义 typedef struct tagPOINT { int x; int y; }POINT; POINT p1; // 这样就比原来的方式少写了一个struct,比较省事,尤其在大量使用的时候 struct POINT { int x; int y; }; POINT p1; // C++中可以直接定义 struct POINT p1; // C中需要带struct定义
3、用typedef来定义与平台无关的类型。
#ifdef _MSC_VER typedef __int64 Int64; #if _MSC_VER <= 1200 // MS VC6 typedef __int64 UInt64; // MS VC6 does not support unsigned __int64 to double conversion #else typedef unsigned __int64 UInt64; #endif #else typedef long long Int64; typedef unsigned long long UInt64;
4、为复杂的声明定义一个新的简单的别名。方法是:在原来的声明里逐步用别名替换一部分复杂声明,如此循环,把带变量名的部分留到最后替换,得到的就是原声明的最简化版。
先说说函数指针
函数指针的定义
参考自 http://learn.akae.cn/media/ch23s08.html
typedef int (*Func)(int); // 定义函数类型 int func(int a); // 函数声明 int func(int a) { return a; } int main() { // your code goes here int (*pFunc)(int); // 声明函数指针 pFunc = func; int a = (*pFunc)(3); int b = pFunc(3); cout << a << endl; cout << b << endl; int (*pFunc2)(int); pFunc2 = &func; int c = (*pFunc2)(3); int d = pFunc2(3); cout << c << endl; cout << d << endl; Func pFunc3 = func; int e = pFunc3(3); cout << e << endl; return 0; }
a,b,c,d的值都为3。
分析一下变量pFunc的类型声明 int (*pFunc)(int);
pFunc首先跟*
号结合在一起,因此是一个指针。(*pFunc)
外面是一个函数原型的格式,参数是int
,返回值是int
,所以pFunc是指向这种函数的指针。而func
的参数是int
,返回值是int
,正好是这种函数,因此pFunc可以指向func
。
注意,func
是一种函数类型,而函数类型和数组类型类似,做右值使用时自动转换成函数指针类型,所以可以直接赋给pFunc,当然也可以写成pFunc = &func;
,把函数func
先取地址再赋给pFunc
,就不需要自动类型转换了。
可以直接通过函数指针调用函数,如pFunc(3)
,也可以先用*pFunc
取出它所指的函数类型,再调用函数,即(*pFunc)(3)
。
可以这么理解:函数调用运算符()
要求操作数是函数指针,所以pFunc(3)
是最直接的写法,而func(3)
或(*pFunc)(3)
则是把函数类型自动转换成函数指针然后做函数调用。
函数指针做为参数和返回值
参考自 http://hipercomer.blog.51cto.com/4415661/792301
typedef int (*Func)(int a); typedef int Func2(int a); int func(int a) { return a; } // TestFunc1函数,返回值类型为 int (*)(int) int (*TestFunc1())(int a) { return func; } // 上面的函数也可以写成这样,返回值类型为Func Func TestFunc2() { return func; } // TestFunc1函数的参数为Func类型,返回值是int (*)(int) // 其实这两种类型是一样的 int (*TestFunc1(Func pParam))(int a) { return pParam; } // 函数可以返回void类型、标量类型、结构体、联合体, // 但不能返回函数类型,也不能返回数组类型 //Func2 TestFunc3() //{ // return func; //} // 函数TestFunc3返回一个Func2*类型的函数指针 Func2* TestFunc3() { return func; } int main() { Func pa = TestFunc1(); cout << pa(3) << endl; Func pb = TestFunc1(pa); cout<< pb(4) << endl; Func pc = TestFunc2(); cout << pc(5) << endl; Func2* pd = TestFunc3(); cout << (*pd)(6) << endl; return 0; }
再整理
typedef float (*Func1)(float, float); typedef void (*Func2)(Func1, float, float); namespace test { float sum(float a, float b) { return a+b; } float minus(float a, float b) { return a-b; } float multiply(float a, float b) { return a*b; } float divide(float a, float b) { return a/b; } // 函数指针作为参数 // 也可以写成 void test1(Func1 pFunc, float a, float b) void test1(float (*pFunc)(float,float), float a, float b) { cout << pFunc(a, b) << endl; } void test2(float (*pFunc)(float,float), float a, float b) { cout << "test only" << endl; } // 函数指针作为返回值 // 也可以写成 Func1 test3(char cb) float (*test3(char cb))(float, float) { switch(cb) { case ‘+‘: return sum; case ‘-‘: return minus; case ‘*‘: return multiply; case ‘/‘: return divide; } return NULL; } // 函数指针既作为参数,又作为返回值 // 也可以写成 Func1 test4(Func1 pFunc) float (*test4(float (*pFunc)(float,float)))(float, float) { return pFunc; } } int main() { cout << "定义函数指针数组" << endl; float (*a[])(float, float) = {test::sum, test::minus, test::multiply, test::divide}; int n = sizeof(a)/sizeof(a[0]); for (int i = 0; i < n; ++i) { cout << a[i](8,2) << endl; } cout << "use typedef" << endl; Func1 b[] = {test::sum, test::minus, test::multiply, test::divide}; n = sizeof(b)/sizeof(b[0]); for (int i = 0; i < n; ++i) { cout << b[i](8,2) << endl; } cout << "定义函数指针数组,有一个参数为函数指针" << endl; void (*c[])(Func1, float, float) = {test::test1, test::test2}; for (int i = 0; i < 2; ++i) { for (int j = 0; j < n; ++j) { c[i](b[j], 12, 2); } } cout << "use typedef" << endl; Func2 d[2] = {test::test1, test::test2}; for (int i = 0; i < 2; ++i) { for (int j = 0; j < n; ++j) { d[i](b[j], 12, 2); } } cout << "函数指针作为返回值" << endl; cout << test::test3(‘+‘)(14, 2) << endl; cout << test::test3(‘-‘)(14, 2) << endl; cout << test::test3(‘*‘)(14, 2) << endl; cout << test::test3(‘/‘)(14, 2) << endl; return 0; }
#define const typedef,布布扣,bubuko.com
原文:http://www.cnblogs.com/oem01/p/3586719.html