define 的全部使用方法
typedef的總結(jié),以下是引用的內(nèi)容(紅色部分是我自己寫的內(nèi)容)。
用途一:
定義一種類型的別名,而不只是簡(jiǎn)單的宏替換。可以用作同時(shí)聲明指針型的多個(gè)對(duì)象。比如:
char* pa, pb;//這多數(shù)不符合我們的意圖,它只聲明了一個(gè)指向字符變量的指針,
//和一個(gè)字符變量;
以下則可行:
typedef char* PCHAR;
PCHAR pa, pb;
這種用法很有用,特別是char* pa, pb的定義,初學(xué)者往往認(rèn)為是定義了兩個(gè)字符型指針,其實(shí)不是,而用typedef char* PCHAR就不會(huì)出現(xiàn)這樣的問(wèn)題,減少了錯(cuò)誤的發(fā)生。
用途二:
用在舊的C代碼中,幫助struct。以前的代碼中,聲明struct新對(duì)象時(shí),必須要帶上struct,即形式為: struct 結(jié)構(gòu)名對(duì)象名,如:
struct tagPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;
而在C++中,則可以直接寫:結(jié)構(gòu)名對(duì)象名,即:tagPOINT1 p1;
typedef struct tagPOINT
{
int x;
int y;
}POINT;
POINT p1; // 這樣就比原來(lái)的方式少寫了一個(gè)struct,比較省事,尤其在大量使用的時(shí)
候,或許,在C++中,typedef的這種用途二不是很大,但是理解了它,對(duì)掌握以前的舊代
碼還是有幫助的,畢竟我們?cè)陧?xiàng)目中有可能會(huì)遇到較早些年代遺留下來(lái)的代碼。
用途三:
用typedef來(lái)定義與平臺(tái)無(wú)關(guān)的類型。
比如定義一個(gè)叫 REAL 的浮點(diǎn)類型,在目標(biāo)平臺(tái)一上,讓它表示最高精度的類型為:
typedef long double REAL;
在不支持 long double 的平臺(tái)二上,改為:
typedef double REAL;
在連 double 都不支持的平臺(tái)三上,改為:
typedef float REAL;
也就是說(shuō),當(dāng)跨平臺(tái)時(shí),只要改下 typedef 本身就行,不用對(duì)其他源碼做任何修改。
標(biāo)準(zhǔn)庫(kù)就廣泛使用了這個(gè)技巧,比如size_t。另外,因?yàn)閠ypedef是定義了一種類型的新別名,不是簡(jiǎn)單的字符串替換,所以它比宏來(lái)得穩(wěn)健。
這個(gè)優(yōu)點(diǎn)在我們寫代碼的過(guò)程中可以減少不少代碼量哦!
用途四:
為復(fù)雜的聲明定義一個(gè)新的簡(jiǎn)單的別名。方法是:在原來(lái)的聲明里逐步用別名替換一部
分復(fù)雜聲明,如此循環(huán),把帶變量名的部分留到最后替換,得到的就是原聲明的最簡(jiǎn)化
版。舉例:
原聲明:void (*b[10]) (void (*)());
變量名為b,先替換右邊部分括號(hào)里的,pFunParam為別名一:
typedef void (*pFunParam)();
再替換左邊的變量b,pFunx為別名二:
typedef void (*pFunx)(pFunParam);
原聲明的最簡(jiǎn)化版:
pFunx b[10];
原聲明:doube(*)() (*e)[9];
變量名為e,先替換左邊部分,pFuny為別名一:
typedef double(*pFuny)();
再替換右邊的變量e,pFunParamy為別名二
typedef pFuny (*pFunParamy)[9];
原聲明的最簡(jiǎn)化版:
pFunParamy e;
理解復(fù)雜聲明可用的“右左法則”:從變量名看起,先往右,再往左,碰到一個(gè)圓括號(hào)
就調(diào)轉(zhuǎn)閱讀的方向;括號(hào)內(nèi)分析完就跳出括號(hào),還是按先右后左的順序,如此循環(huán),直
到整個(gè)聲明分析完。舉例:
int (*func)(int *p);
首先找到變量名func,外面有一對(duì)圓括號(hào),而且左邊是一個(gè)*號(hào),這說(shuō)明func是一個(gè)指針
;然后跳出這個(gè)圓括號(hào),先看右邊,又遇到圓括號(hào),這說(shuō)明(*func)是一個(gè)函數(shù),所以
func是一個(gè)指向這類函數(shù)的指針,即函數(shù)指針,這類函數(shù)具有int*類型的形參,返回值
類型是int。
int (*func[5])(int *);
func右邊是一個(gè)[]運(yùn)算符,說(shuō)明func是具有5個(gè)元素的數(shù)組;func的左邊有一個(gè)*,說(shuō)明
func的元素是指針(注意這里的*不是修飾func,而是修飾func[5]的,原因是[]運(yùn)算符
優(yōu)先級(jí)比*高,func先跟[]結(jié)合)。跳出這個(gè)括號(hào),看右邊,又遇到圓括號(hào),說(shuō)明func數(shù)
組的元素是函數(shù)類型的指針,它指向的函數(shù)具有int*類型的形參,返回值類型為int。
這種用法是比較復(fù)雜的,出現(xiàn)的頻率也不少,往往在看到這樣的用法卻不能理解,相信以上的解釋能有所幫助。
*****以上為參考部分,以下為本人領(lǐng)悟部分*****
使用示例:
1.比較一:
#include <iostream>
using namespace std;
typedef int (*A) (char, char);
int ss(char a, char b)
{
cout<<"功能1"<<endl;
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
int bb(char a, char b)
{
cout<<"功能2"<<endl;
cout<<b<<endl;
cout<<a<<endl;
return 0;
}
void main()
{
A a;
a = ss;
a('a','b');
a = bb;
a('a', 'b');
}
2.比較二:
typedef int (A) (char, char);
void main()
{
A *a;
a = ss;
a('a','b');
a = bb;
a('a','b');
}
兩個(gè)程序的結(jié)果都一樣:
功能1
a
b
功能2
b
a
*****以下是參考部分*****
參考自:http://blog.hc360.com/portal/personShowArticle.do?articleId=57527
typedef 與 #define的區(qū)別:
案例一:
通常講,typedef要比#define要好,特別是在有指針的場(chǎng)合。請(qǐng)看例子:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
在上述的變量定義中,s1、s2、s3都被定義為char *,而s4則定義成了char,不是我們
所預(yù)期的指針變量,根本原因就在于#define只是簡(jiǎn)單的字符串替換而typedef則是為一
個(gè)類型起新名字。
案例二:
下面的代碼中編譯器會(huì)報(bào)一個(gè)錯(cuò)誤,你知道是哪個(gè)語(yǔ)句錯(cuò)了嗎?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
是p2++出錯(cuò)了。這個(gè)問(wèn)題再一次提醒我們:typedef和#define不同,它不是簡(jiǎn)單的
文本替換。上述代碼中const pStr p2并不等于const char * p2。const pStr p2和
const long x本質(zhì)上沒(méi)有區(qū)別,都是對(duì)變量進(jìn)行只讀限制,只不過(guò)此處變量p2的數(shù)據(jù)類
型是我們自己定義的而不是系統(tǒng)固有類型而已。因此,const pStr p2的含義是:限定數(shù)
據(jù)類型為char *的變量p2為只讀,因此p2++錯(cuò)誤
#define的使用方法總結(jié)了一下,如下所示:(如有不足請(qǐng)批評(píng)指正)
1. 最最最簡(jiǎn)單的 define 定義
#define MAX 10,編譯器在處理這個(gè)代碼之前會(huì)對(duì)MAX進(jìn)行處理,替換為10,或許有些人認(rèn)為這樣的定義看起來(lái)和const常量很相似,但是他們還是有區(qū)別的,#define的定義其實(shí)就是簡(jiǎn)單的文本的替換,并不是作為一個(gè)量來(lái)使用
2. 用 #define 來(lái)對(duì)函數(shù)進(jìn)行“定義”
居然還能用#define來(lái)定義函數(shù),坑爹么?其實(shí)咋說(shuō)呢,就是類似的一個(gè)函數(shù)定義罷了,和真正的函數(shù)定義當(dāng)然還是有區(qū)別的了,下面進(jìn)行舉例說(shuō)明:
還是用上面的MAX的例子:
|
1 |
#define MAX(a,b) ((a) > (b) ? (a) : (b)) |
這個(gè)定義就返回兩個(gè)數(shù)中較大的那個(gè),不知道你們看到了沒(méi)看到,這個(gè)”函數(shù)“沒(méi)有類型檢查,像不像函數(shù)模板?像?不像?
其實(shí)是有點(diǎn)像的,可以作為一個(gè)普通的模板來(lái)使用罷了,他肯定沒(méi)函數(shù)模板那么安全,WHY?看下面的例子:
#define MINUS(a,b) a – b,眨眼一看,這個(gè)肯定是減法操作的define,有木有?對(duì),沒(méi)錯(cuò),就是這個(gè)意思,這個(gè)定義在一般的使用中沒(méi)問(wèn)題,但是在特定的情況下使用會(huì)出現(xiàn)問(wèn)題,如果我們要這樣去使用 的話,展開之后會(huì)是什么樣子呢?如:2 * MINUS(a,b) / 4,就像我前面所說(shuō)的那樣,宏其實(shí)就是一個(gè)簡(jiǎn)單的文本替換,所以展開時(shí)候就變?yōu)?2 * a – b / 4,和我們想要的結(jié)果是不是不一樣?是不是錯(cuò) 了?有木有?那要如何解決這個(gè)問(wèn)題呢,很簡(jiǎn)單,給原定義加一個(gè)括號(hào)就OK了,也就是#define MINUS(a,b) (a – b)
再說(shuō)一個(gè)經(jīng)常出現(xiàn)的一個(gè)錯(cuò)誤,看下面的例子:
|
1 |
#definepinint* |
本意其實(shí)都想讓a和b成為int型指針,但是實(shí)際上卻變成了int *a,b;a是int型指針,b是int型變量,咋處理捏?這個(gè)時(shí)候typedef就出來(lái)了,它說(shuō)我可以滿 足define滿足不了的要求,所以改成
|
1 |
typedef pin (int *) |
就OK了。
TIP:我們?cè)趯慶ode的時(shí)候一定要養(yǎng)成一個(gè)良好的習(xí)慣和一個(gè)良好的代碼編寫風(fēng)格,建議所有的層次都加上括號(hào)
3. define 的單行定義,舉例說(shuō)明之,屬于少見用法
|
1 |
#define A(x) ##x |
如果我們假設(shè)x=1,那么A(1)就是1,B(1)就是‘1’,C(1)就是”1“
4. define 的多行定義
#define可以進(jìn)行多行定義,雖然看起來(lái)有點(diǎn)蛋疼,但是確實(shí)是一個(gè)灰常經(jīng)典而且在設(shè)備驅(qū)動(dòng)代碼中經(jīng)常要用到的一個(gè)方法,格式如下:
|
1 |
#define MACRO(arg1,arg2) do { |
TIP:在每一行的末尾要加上,切記!
5. 定義宏和取消宏定義的方法
定義一個(gè)宏使用#define,取消一個(gè)宏定義使用#undef
6. 使用宏進(jìn)行條件編譯
格式如下:#ifdef … (#else) … #endif
如:
|
1 |
#ifdef HELLO |
7. 用define來(lái)處理頭文件被頭文件或者源文件包含的情況
由于頭文件包含可以嵌套,那么c文件有可能包含多次同一個(gè)頭文件,就會(huì)出現(xiàn)重復(fù)定義的問(wèn)題的,那么可以就通過(guò)條件編譯開關(guān)來(lái)避免重復(fù)包含,如下:
|
1 |
#ifndef _HELLO_H_ |
typedef的總結(jié)還是很不錯(cuò),由于總結(jié)的很好,我就不加修改的引用過(guò)來(lái)了,以下是引用的內(nèi)容(紅色部分是我自己寫的內(nèi)容)。
用途一:
定義一種類型的別名,而不只是簡(jiǎn)單的宏替換。可以用作同時(shí)聲明指針型的多個(gè)對(duì)象。比如:
char* pa, pb;//這多數(shù)不符合我們的意圖,它只聲明了一個(gè)指向字符變量的指針,
//和一個(gè)字符變量;
以下則可行:
typedef char* PCHAR;
PCHAR pa, pb;
這種用法很有用,特別是char* pa, pb的定義,初學(xué)者往往認(rèn)為是定義了兩個(gè)字符型指針,其實(shí)不是,而用typedef char* PCHAR就不會(huì)出現(xiàn)這樣的問(wèn)題,減少了錯(cuò)誤的發(fā)生。
用途二:
用在舊的C代碼中,幫助struct。以前的代碼中,聲明struct新對(duì)象時(shí),必須要帶上struct,即形式為: struct 結(jié)構(gòu)名對(duì)象名,如:
struct tagPOINT1
{
int x;
int y;
};
struct tagPOINT1 p1;
而在C++中,則可以直接寫:結(jié)構(gòu)名對(duì)象名,即:tagPOINT1 p1;
typedef struct tagPOINT
{
int x;
int y;
}POINT;
POINT p1; // 這樣就比原來(lái)的方式少寫了一個(gè)struct,比較省事,尤其在大量使用的時(shí)
候,或許,在C++中,typedef的這種用途二不是很大,但是理解了它,對(duì)掌握以前的舊代
碼還是有幫助的,畢竟我們?cè)陧?xiàng)目中有可能會(huì)遇到較早些年代遺留下來(lái)的代碼。
用途三:
用typedef來(lái)定義與平臺(tái)無(wú)關(guān)的類型。
比如定義一個(gè)叫 REAL 的浮點(diǎn)類型,在目標(biāo)平臺(tái)一上,讓它表示最高精度的類型為:
typedef long double REAL;
在不支持 long double 的平臺(tái)二上,改為:
typedef double REAL;
在連 double 都不支持的平臺(tái)三上,改為:
typedef float REAL;
也就是說(shuō),當(dāng)跨平臺(tái)時(shí),只要改下 typedef 本身就行,不用對(duì)其他源碼做任何修改。
標(biāo)準(zhǔn)庫(kù)就廣泛使用了這個(gè)技巧,比如size_t。另外,因?yàn)閠ypedef是定義了一種類型的新別名,不是簡(jiǎn)單的字符串替換,所以它比宏來(lái)得穩(wěn)健。
這個(gè)優(yōu)點(diǎn)在我們寫代碼的過(guò)程中可以減少不少代碼量哦!
用途四:
為復(fù)雜的聲明定義一個(gè)新的簡(jiǎn)單的別名。方法是:在原來(lái)的聲明里逐步用別名替換一部
分復(fù)雜聲明,如此循環(huán),把帶變量名的部分留到最后替換,得到的就是原聲明的最簡(jiǎn)化
版。舉例:
原聲明:void (*b[10]) (void (*)());
變量名為b,先替換右邊部分括號(hào)里的,pFunParam為別名一:
typedef void (*pFunParam)();
再替換左邊的變量b,pFunx為別名二:
typedef void (*pFunx)(pFunParam);
原聲明的最簡(jiǎn)化版:
pFunx b[10];
原聲明:doube(*)() (*e)[9];
變量名為e,先替換左邊部分,pFuny為別名一:
typedef double(*pFuny)();
再替換右邊的變量e,pFunParamy為別名二
typedef pFuny (*pFunParamy)[9];
原聲明的最簡(jiǎn)化版:
pFunParamy e;
理解復(fù)雜聲明可用的“右左法則”:從變量名看起,先往右,再往左,碰到一個(gè)圓括號(hào)
就調(diào)轉(zhuǎn)閱讀的方向;括號(hào)內(nèi)分析完就跳出括號(hào),還是按先右后左的順序,如此循環(huán),直
到整個(gè)聲明分析完。舉例:
int (*func)(int *p);
首先找到變量名func,外面有一對(duì)圓括號(hào),而且左邊是一個(gè)*號(hào),這說(shuō)明func是一個(gè)指針
;然后跳出這個(gè)圓括號(hào),先看右邊,又遇到圓括號(hào),這說(shuō)明(*func)是一個(gè)函數(shù),所以
func是一個(gè)指向這類函數(shù)的指針,即函數(shù)指針,這類函數(shù)具有int*類型的形參,返回值
類型是int。
int (*func[5])(int *);
func右邊是一個(gè)[]運(yùn)算符,說(shuō)明func是具有5個(gè)元素的數(shù)組;func的左邊有一個(gè)*,說(shuō)明
func的元素是指針(注意這里的*不是修飾func,而是修飾func[5]的,原因是[]運(yùn)算符
優(yōu)先級(jí)比*高,func先跟[]結(jié)合)。跳出這個(gè)括號(hào),看右邊,又遇到圓括號(hào),說(shuō)明func數(shù)
組的元素是函數(shù)類型的指針,它指向的函數(shù)具有int*類型的形參,返回值類型為int。
這種用法是比較復(fù)雜的,出現(xiàn)的頻率也不少,往往在看到這樣的用法卻不能理解,相信以上的解釋能有所幫助。
*****以上為參考部分,以下為本人領(lǐng)悟部分*****
使用示例:
1.比較一:
#include <iostream>
using namespace std;
typedef int (*A) (char, char);
int ss(char a, char b)
{
cout<<"功能1"<<endl;
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
int bb(char a, char b)
{
cout<<"功能2"<<endl;
cout<<b<<endl;
cout<<a<<endl;
return 0;
}
void main()
{
A a;
a = ss;
a('a','b');
a = bb;
a('a', 'b');
}
2.比較二:
typedef int (A) (char, char);
void main()
{
A *a;
a = ss;
a('a','b');
a = bb;
a('a','b');
}
兩個(gè)程序的結(jié)果都一樣:
功能1
a
b
功能2
b
a
*****以下是參考部分*****
參考自:http://blog.hc360.com/portal/personShowArticle.do?articleId=57527
typedef 與 #define的區(qū)別:
案例一:
通常講,typedef要比#define要好,特別是在有指針的場(chǎng)合。請(qǐng)看例子:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
在上述的變量定義中,s1、s2、s3都被定義為char *,而s4則定義成了char,不是我們
所預(yù)期的指針變量,根本原因就在于#define只是簡(jiǎn)單的字符串替換而typedef則是為一
個(gè)類型起新名字。
案例二:
下面的代碼中編譯器會(huì)報(bào)一個(gè)錯(cuò)誤,你知道是哪個(gè)語(yǔ)句錯(cuò)了嗎?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
是p2++出錯(cuò)了。這個(gè)問(wèn)題再一次提醒我們:typedef和#define不同,它不是簡(jiǎn)單的
文本替換。上述代碼中const pStr p2并不等于const char * p2。const pStr p2和
const long x本質(zhì)上沒(méi)有區(qū)別,都是對(duì)變量進(jìn)行只讀限制,只不過(guò)此處變量p2的數(shù)據(jù)類
型是我們自己定義的而不是系統(tǒng)固有類型而已。因此,const pStr p2的含義是:限定數(shù)
據(jù)類型為char *的變量p2為只讀,因此p2++錯(cuò)誤
總結(jié)
以上是生活随笔為你收集整理的define 的全部使用方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php的webservice的soaph
- 下一篇: 云图说|图解DGC:基于华为智能数据湖解