日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

水滴石穿C语言之typedef的问题

發(fā)布時(shí)間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 水滴石穿C语言之typedef的问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  1. 基本解釋

  typedef為C語(yǔ)言的關(guān)鍵字,作用是為一種數(shù)據(jù)類型定義一個(gè)新名字。這里的數(shù)據(jù)類型包括內(nèi)部數(shù)據(jù)類型(int,char等)和自定義的數(shù)據(jù)類型(struct等)。

  在編程中使用typedef目的一般有兩個(gè),一個(gè)是給變量一個(gè)易記且意義明確的新名字,另一個(gè)是簡(jiǎn)化一些比較復(fù)雜的類型聲明。

  至于typedef有什么微妙之處,請(qǐng)你接著看下面對(duì)幾個(gè)問題的具體闡述。

?
?


  2. typedef & 結(jié)構(gòu)的問題

  當(dāng)用下面的代碼定義一個(gè)結(jié)構(gòu)時(shí),編譯器報(bào)了一個(gè)錯(cuò)誤,為什么呢?莫非C語(yǔ)言不允許在結(jié)構(gòu)中包含指向它自己的指針嗎?請(qǐng)你先猜想一下,然后看下文說明:

typedef struct tagNode
{
 char *pItem;
 pNode pNext;
} *pNode;?

  答案與分析:

  1、typedef的最簡(jiǎn)單使用

typedef long byte_4;

  給已知數(shù)據(jù)類型long起個(gè)新名字,叫byte_4。

  2、 typedef與結(jié)構(gòu)結(jié)合使用

typedef struct tagMyStruct
{
 int iNum;
 long lLength;
} MyStruct;

  這語(yǔ)句實(shí)際上完成兩個(gè)操作:

  1) 定義一個(gè)新的結(jié)構(gòu)類型

struct tagMyStruct
{
 int iNum;
 long lLength;
};

  分析:tagMyStruct稱為“tag”,即“標(biāo)簽”,實(shí)際上是一個(gè)臨時(shí)名字,struct 關(guān)鍵字和tagMyStruct一起,構(gòu)成了這個(gè)結(jié)構(gòu)類型,不論是否有typedef,這個(gè)結(jié)構(gòu)都存在。

  我們可以用struct tagMyStruct varName來定義變量,但要注意,使用tagMyStruct varName來定義變量是不對(duì)的,因?yàn)閟truct 和tagMyStruct合在一起才能表示一個(gè)結(jié)構(gòu)類型。

  2) typedef為這個(gè)新的結(jié)構(gòu)起了一個(gè)名字,叫MyStruct。

typedef struct tagMyStruct MyStruct;

  因此,MyStruct實(shí)際上相當(dāng)于struct tagMyStruct,我們可以使用MyStruct varName來定義變量。

  答案與分析

  C語(yǔ)言當(dāng)然允許在結(jié)構(gòu)中包含指向它自己的指針,我們可以在建立鏈表等數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)上看到無(wú)數(shù)這樣的例子,上述代碼的根本問題在于typedef的應(yīng)用。

  根據(jù)我們上面的闡述可以知道:新結(jié)構(gòu)建立的過程中遇到了pNext域的聲明,類型是pNode,要知道pNode表示的是類型的新名字,那么在類型本身還沒有建立完成的時(shí)候,這個(gè)類型的新名字也還不存在,也就是說這個(gè)時(shí)候編譯器根本不認(rèn)識(shí)pNode。

  解決這個(gè)問題的方法有多種:

  1)、

typedef struct tagNode
{
 char *pItem;
 struct tagNode *pNext;
} *pNode;

  2)、

typedef struct tagNode *pNode;
struct tagNode
{
 char *pItem;
 pNode pNext;
};

  注意:在這個(gè)例子中,你用typedef給一個(gè)還未完全聲明的類型起新名字。C語(yǔ)言編譯器支持這種做法。

  3)、規(guī)范做法:

struct tagNode
{
 char *pItem;
 struct tagNode *pNext;
};
typedef struct tagNode *pNode;

  3. typedef & #define的問題

  有下面兩種定義pStr數(shù)據(jù)類型的方法,兩者有什么不同?哪一種更好一點(diǎn)?

typedef char *pStr;
#define pStr char *;?

  答案與分析:

  通常講,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è)類型起新名字。

  #define用法例子:

#define f(x) x*x
main( )
{
 int a=6,b=2,c;
 c=f(a) / f(b);
 printf("%d /n",c);
}

  以下程序的輸出結(jié)果是: 36。

  因?yàn)槿绱嗽?#xff0c;在許多C語(yǔ)言編程規(guī)范中提到使用#define定義時(shí),如果定義中包含表達(dá)式,必須使用括號(hào),則上述定義應(yīng)該如下定義才對(duì):

#define f(x) (x*x)

  當(dāng)然,如果你使用typedef就沒有這樣的問題。

  4. typedef & #define的另一例

  下面的代碼中編譯器會(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è)問題再一次提醒我們:typedef和#define不同,它不是簡(jiǎn)單的文本替換。上述代碼中const pStr p2并不等于const char * p2。const pStr p2和const long x本質(zhì)上沒有區(qū)別,都是對(duì)變量進(jìn)行只讀限制,只不過此處變量p2的數(shù)據(jù)類型是我們自己定義的而不是系統(tǒng)固有類型而已。因此,const pStr p2的含義是:限定數(shù)據(jù)類型為char *的變量p2為只讀,因此p2++錯(cuò)誤。

(注:關(guān)于const的限定內(nèi)容問題,在本系列第二篇有詳細(xì)講解)。

  #define與typedef引申談

  1) #define宏定義有一個(gè)特別的長(zhǎng)處:可以使用 #ifdef ,#ifndef等來進(jìn)行邏輯判斷,還可以使用#undef來取消定義。

  2) typedef也有一個(gè)特別的長(zhǎng)處:它符合范圍規(guī)則,使用typedef定義的變量類型其作用范圍限制在所定義的函數(shù)或者文件內(nèi)(取決于此變量定義的位置),而宏定義則沒有這種特性。

  5. typedef & 復(fù)雜的變量聲明

  在編程實(shí)踐中,尤其是看別人代碼的時(shí)候,常常會(huì)遇到比較復(fù)雜的變量聲明,使用typedef作簡(jiǎn)化自有其價(jià)值,比如:

  下面是三個(gè)變量的聲明,我想使用typdef分別給它們定義一個(gè)別名,請(qǐng)問該如何做?

>1:int *(*a[5])(int, char*);
>2:void (*b[10]) (void (*)());
>3. doube(*)() (*pa)[9];

  答案與分析:

  對(duì)復(fù)雜變量建立一個(gè)類型別名的方法很簡(jiǎn)單,你只要在傳統(tǒng)的變量聲明表達(dá)式里用類型名替代變量名,然后把關(guān)鍵字typedef加在該語(yǔ)句的開頭就行了。

  (注:如果你對(duì)有些變量的聲明語(yǔ)法感到難以理解,請(qǐng)參閱本系列第十篇的相關(guān)內(nèi)容)。

>1:int *(*a[5])(int, char*);
//pFun是我們建的一個(gè)類型別名
typedef int *(*pFun)(int, char*);
//使用定義的新類型來聲明對(duì)象,等價(jià)于int* (*a[5])(int, char*);
pFun a[5];

>2:void (*b[10]) (void (*)());
//首先為上面表達(dá)式藍(lán)色部分聲明一個(gè)新類型
typedef void (*pFunParam)();
//整體聲明一個(gè)新類型
typedef void (*pFun)(pFunParam);
//使用定義的新類型來聲明對(duì)象,等價(jià)于void (*b[10]) (void (*)());
pFun b[10];

>3. doube(*)() (*pa)[9];
//首先為上面表達(dá)式藍(lán)色部分聲明一個(gè)新類型
typedef double(*pFun)();
//整體聲明一個(gè)新類型
typedef pFun (*pFunParam)[9];
//使用定義的新類型來聲明對(duì)象,等價(jià)于doube(*)() (*pa)[9];
pFunParam pa;?

總結(jié)

以上是生活随笔為你收集整理的水滴石穿C语言之typedef的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。