1.剛接觸MFC時會看到很多陌生的資料類型,關鍵字.一開始會特別反感,不適應.比如UINT,DWORD.不過你右擊一點它們選擇跳轉到定義.就會發現有這樣的定義:
typedef unsigned int UINT; typedef unsigned long DWORD;
另外還有一些宏比如ON_COMMAND,跳轉到定義是這樣的:
#define ON_COMMAND(id, memberFxn) \
{ WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
static_cast<AFX_PMSG> (memberFxn) },
2.另外有時在一個類的定義之前會發現這樣的語句:
#ifndef _MAINFRM_H
#define _MAINFRM_H
下面我們就來分析下typedef和define的用法:
一.typedef用來定義類型別名,define用來替換
typedef應該是typedefine的縮寫.顧名思義就是類型定義.於是我們可以把它理解為重新定義一個新類型.只不過是基於原有的類型.另外也可以理解為某個類型的別名.這有點像Oracle中的同義字.比如上面提到的UINT,我們可以認為它是一個新的類型,和類型unsigned int一樣.這樣我們定義一個非負整數時有兩種等價的方式了:
unsigned int num;或UINT num;它們可以互相替換.UINT用起來自然方便一點,簡潔一點.但凡事有利有弊.新添加個UINT我們又得花時間去熟悉它記住它.
define就僅涉及到替換某一段字元,不涉及到類型.
舉個例子:
#include<iostream>
typedef int INT; //注意typedef不能用來替換一般的字元.比如typedef 123 N;是錯誤的
#define N 123
#define out(x) std::cout<<x
void main()
{
INT num = N; //等同於int num = N;
char* str = "hello world";
out(str); //輸出hello world
out(num); //輸出123
}
但是雖然define是僅替換,但如果替換的字元恰巧是類型定義的關鍵字,那就跟typedef差不多了.比如#define UINT int 和typedef int UINT;達到的效果一樣.但是只是效果一樣,但意義不一樣的.比如這種情況
typedef int* int_ptr1;
#define int_ptr2 int*
int_ptr1 a,b; //a和b都是int*類型的指標
int_ptr2 c,d; //c是int*類型的指標.而d就是int了
這看起來有點暈乎的啊.不過不用去管它們的區別.只要你在涉及到類型的地方用typedef,只涉及到替換的情況用#define好了.這樣就不用管這樣的煩心事了啊
補充:明白了typedef 和#define的區別後但用有時可能會把他們混淆,分不清誰是誰了.我們可以這樣來記憶.
1.typedef裡面有個type那肯定是和類型有關的.另外我們平時定義一個類型時會在後面加個分號;所以用typedef時也記得在後面加個分號
2.#define裡面有個fine,那就是好.好在哪裡呢.符合思維習慣.我們平時定義某個東東時習慣這樣的順序,比如你是個王八蛋.你在前面,定義你的詞在後面.#define也是這樣.
比如#define 你 "是個王八蛋" 那麼你就代表著王八蛋.另外#define定義後面不用分號(你運行它會成功的,平時我們都習慣用英語字母做標識符,其實用漢字也一樣可以用來
做變數名函數名的,只不過會有些警告)
而typedef不好,它倒過來了.比如typedef int INT; //INT代表int但它跑後面去了,而不是typedef INT int;
二.define保證標頭檔被編譯一次
假如有三個標頭檔one.h ,two.h, three.h
在two.h中有include "one.h"
在three.h中有include "one.h" include "two.h"
編譯three.h的時候先編譯one.h,然後編譯two.h,由於two.h裡面引用了one.h這裡one.h又會被重複編譯一次.這樣就會出錯,說類類型重複定義
我們在one.h中這樣寫就可以防止這種錯誤
#ifndef _one_h //_one_h這名字是隨便取的,只要別重複,並且跟#define中的一樣就行了.
#define _one_h
//#pragma once //這是我注釋掉的.在VS中你建立一個類時它自動給你添加它.實現的功能和#define一樣.防止重複編譯
//不過#pragma是編譯器相關的.如果你不用vs用其他的有可能會出錯.所以最好還是用#define.它是通用的.
class one
{
one(void);
~one(void);
};
#endif
三.用#define做一些條件判斷
我們在程式運行時去動態做一些判斷,符合某些條件哪些代碼執行,不符合就不執行.例如是debug還是release,是32位的平台還是64位的平台.我們可以用#define來做判斷
舉例:
#include "stdafx.h"
#include <iostream>
using namespace std;
void main()
{
#ifdef _WIN32 //也可以這樣寫#if defined(_WIN32),等價的
cout<<"your computer is 32-bit"<<endl;
#else
cout<<"your computer is 64-bit"<<endl; //我的是64位的,所以執行這段代碼
#endif
}
其中的_WIN32是編譯器裡早定義好的.比如你在VS裡工具列裡選了Win32那麼預設就#define _WIN32了.如果選x64就對應_WIN64,選Debug對應_DEBUG
當然你也可以自己定義.
#include "stdafx.h"
#include <iostream>
using namespace std;
#define SELECT
void main()
{
#ifdef SELECT
cout<<"part one are running"<<endl; //執行這一段代碼
#else
cout<<"part tow are running"<<endl; //如果注釋掉#define SELECT則執行這一段
#endif
}