📄 c语言之typedef的问题 c-c++编程 卓越资源.htm
字号:
type=text/javascript>
</SCRIPT>
</DIV></DIV><!--header----main-->
<DIV class=main id=read>
<DIV class=area-4>
<DIV class=area-4-bot>
<DIV class="read-content left">
<DIV class=postion><A href="http://unix-cd.com/vc">卓越资源</A> > <A
href="http://unix-cd.com/vc/list.php?cid=10">电脑教程</A> > <A
href="http://unix-cd.com/vc/list.php?cid=18">软件开发</A> > <A
href="http://unix-cd.com/vc/list.php?cid=23">C/C++编程</A> </DIV>
<H1>C语言之typedef的问题 </H1>
<DIV class=dd>2007-06-23 13:22 来源: weigongwan.cublog.cn 作者:weigongwan 网友评论 <SPAN
id=comnum>0</SPAN> 条 浏览次数 <SPAN id=hits>6</SPAN> </DIV>
<DIV class=text id=content>
<DIV class=box3>
<SCRIPT type=text/javascript><!--
google_ad_client = "pub-3707276699544226";
google_ad_width = 200;
google_ad_height = 200;
google_ad_format = "200x200_as";
google_ad_type = "text_image";
google_ad_channel = "";
//-->
</SCRIPT>
<SCRIPT src="C语言之typedef的问题 C-C++编程 卓越资源.files/show_ads.js"
type=text/javascript>
</SCRIPT>
</DIV>
<TABLE style="BORDER-COLLAPSE: collapse" borderColor=#a5bd6b cellSpacing=1
cellPadding=0 width="100%" border=1>
<TBODY>
<TR>
<TD align=middle>
<TABLE style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word"
cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD align=middle>
<TABLE style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word"
cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD>
<DIV id=art style="MARGIN: 15px">
<H2
class=diaryTitle> </H2>
<P>1.
基本解释<BR><BR> typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。<BR><BR> 在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。<BR><BR> 至于typedef有什么微妙之处,请你接着看下面对几个问题的具体阐述。<BR> 2.
typedef &
结构的问题<BR><BR> 当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不允许在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明:<BR><BR>typedef
struct tagNode<BR>{<BR> char *pItem;<BR> pNode
pNext;
//此时pNode未定义好,不可以使用<BR>} *pNode;
<BR><BR> 答案与分析:<BR><BR> 1、typedef的最简单使用<BR><BR>typedef long
byte_4; <BR><BR> 给已知数据类型long起个新名字,叫byte_4。<BR><BR> 2、
typedef与结构结合使用<BR><BR>typedef struct tagMyStruct<BR>{ <BR> int
iNum;<BR> long lLength;<BR>} MyStruct;
<BR><BR> 这语句实际上完成两个操作:<BR><BR> 1) 定义一个新的结构类型<BR><BR>struct
tagMyStruct<BR>{ <BR> int iNum; <BR> long lLength; <BR>};
<BR><BR> 分析:tagMyStruct称为“tag”,即“标签”,实际上是一个临时名字,struct
关键字和tagMyStruct一起,构成了这个结构类型,不论是否有typedef,这个结构都存在。<BR><BR> 我们可以用struct
tagMyStruct varName来定义变量,但要注意,使用tagMyStruct
varName来定义变量是不对的,因为struct
和tagMyStruct合在一起才能表示一个结构类型。<BR><BR> 2)
typedef为这个新的结构起了一个名字,叫MyStruct。<BR><BR>typedef struct
tagMyStruct MyStruct; <BR><BR> 因此,MyStruct实际上相当于struct
tagMyStruct,我们可以使用MyStruct
varName来定义变量。<BR><BR> 答案与分析<BR><BR> C语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。<BR><BR> 根据我们上面的阐述可以知道:新结构建立的过程中遇到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不认识pNode。<BR><BR> 解决这个问题的方法有多种:<BR><BR> 1)、<BR><BR>typedef
struct tagNode <BR>{<BR> char *pItem;<BR> struct tagNode
*pNext;<BR>} *pNode; <BR><BR> 2)、<BR><BR>typedef struct
tagNode *pNode;<BR>struct tagNode <BR>{<BR> char
*pItem;<BR> pNode pNext;<BR>};
<BR><BR> 注意:在这个例子中,你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。<BR><BR> 3)、规范做法:<BR><BR>struct
tagNode<BR>{<BR> char *pItem;<BR> struct tagNode
*pNext;<BR>};<BR>typedef struct tagNode *pNode; <BR><BR> 3.
typedef &
#define的问题<BR><BR> 有下面两种定义pStr数据类型的方法,两者有什么不同?哪一种更好一点?<BR><BR>typedef
char *pStr;<BR>#define pStr char *;
<BR><BR> 答案与分析:<BR><BR> 通常讲,typedef要比#define要好,特别是在有指针的场合。请看例子:<BR><BR>typedef
char *pStr1;<BR>#define pStr2 char *;<BR>pStr1 s1,
s2;
//s1,s2都是char*<BR>pStr2 s3,
s4; //s3是char*
s4是char<BR><BR> 在上述的变量定义中,s1、s2、s3都被定义为char
*,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。<BR><BR> #define用法例子:
<BR><BR>#define f(x) x*x<BR>main( )<BR>{<BR> int
a=6,b=2,c;<BR> c=f(a) / f(b);<BR> printf("%d \n",c);<BR>}
<BR><BR> 以下程序的输出结果是:
36。<BR><BR> 因为如此原因,在许多C语言编程规范中提到使用#define定义时,如果定义中包含表达式,必须使用括号,则上述定义应该如下定义才对:<BR><BR>#define
f(x) (x*x) <BR><BR> 当然,如果你使用typedef就没有这样的问题。<BR><BR> 4.
typedef &
#define的另一例<BR><BR> 下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?<BR><BR>typedef
char * pStr;<BR>char string[4] = "abc";<BR>const char *p1 =
string;<BR>const pStr p2 =
string;
//这样定义的p2是常量指针 同char * const p2;</P>
<P>p1++;<BR>p2++;
<BR><BR> 答案与分析:<BR><BR> 是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const
pStr p2并不等于const char * p2。const pStr p2和const long
x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const
pStr p2的含义是:限定数据类型为char
*的变量p2为只读,因此p2++错误。<BR><BR>(注:关于const的限定内容问题,在本系列第二篇有详细讲解)。<BR><BR> #define与typedef引申谈<BR><BR> 1)
#define宏定义有一个特别的长处:可以使用 #ifdef
,#ifndef等来进行逻辑判断,还可以使用#undef来取消定义。<BR><BR> 2)
typedef也有一个特别的长处:它符合范围规则,使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。<BR><BR> 5.
typedef &
复杂的变量声明<BR><BR> 在编程实践中,尤其是看别人代码的时候,常常会遇到比较复杂的变量声明,使用typedef作简化自有其价值,比如:<BR><BR> 下面是三个变量的声明,我想使用typdef分别给它们定义一个别名,请问该如何做?<BR><BR>>1:int
*(*a[5])(int, char*);<BR>>2:void (*b[10]) (void
(*)());<BR>>3. doube(*)() (*pa)[9];
<BR><BR> 答案与分析:<BR><BR> 对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。
<BR><BR> (注:如果你对有些变量的声明语法感到难以理解,请参阅本系列第十篇的相关内容)。<BR><BR>>1:int
*(*a[5])(int, char*);
//返回值为int*的函数指针数组<BR>//pFun是我们建的一个类型别名<BR>typedef int
*(*pFun)(int, char*); <BR>//使用定义的新类型来声明对象,等价于int* (*a[5])(int,
char*);<BR>pFun a[5]; <BR><BR>>2:void (*b[10]) (void
(*)()); <FONT
color=#ff0000>//
以函数指针为参数的函数指针数组<BR></FONT>//首先为上面表达式蓝色部分声明一个新类型<BR>typedef
void (*pFunParam)();<BR>//整体声明一个新类型<BR>typedef void
(*pFun)(pFunParam);<BR>//使用定义的新类型来声明对象,等价于void (*b[10]) (void
(*)());<BR>pFun b[10];<BR><BR>>3. doube(*)()
(*pa)[9]; <FONT
color=#ff0000>//指向函数指针数组的指针<BR></FONT>//首先为上面表达式蓝色部分声明一个新类型<BR>typedef
double(*pFun)();<BR>//整体声明一个新类型<BR>typedef pFun
(*pFunParam)[9];
<BR>//使用定义的新类型来声明对象,等价于doube(*)() (*pa)[9];<BR>pFunParam
pa;</P></DIV></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></DIV>
<DIV
style="PADDING-RIGHT: 3px; PADDING-LEFT: 3px; PADDING-BOTTOM: 3px; PADDING-TOP: 3px; TEXT-ALIGN: center">上一篇:<A
title="进制间的相互转换 "
href="http://unix-cd.com/vc/www/23/2007-06/2660.html">进制间的相互转换..</A>
下一篇:<A title="C语言中的运算符及其优先级 "
href="http://unix-cd.com/vc/www/23/2007-06/2653.html">C语言中的运算符..</A> </DIV>
<H2 class=h21>相关主题:<A href="http://unix-cd.com/vc/tag.php?typedef"
target=_blank>typedef</A></H2>
<UL class=list></UL>
<DIV class=dd></DIV>
<H2 class=h21>网友评论</H2>
<DIV id=comment__c></DIV>
<SCRIPT language=JavaScript
src="C语言之typedef的问题 C-C++编程 卓越资源.files/xhr.js"></SCRIPT>
<SCRIPT language=JavaScript src="C语言之typedef的问题 C-C++编程 卓越资源.files/comment.js"
type=text/javascript></SCRIPT>
<SCRIPT language=javascript>
var tid = 2654;
var mid = 1;
var cid = 23;
var flag = 0;
function re_init(subjectid)
{
subject_id = subjectid;
init_message(5);
}
init_message(5);
</SCRIPT>
</DIV>
<DIV class="sidebar right">
<DIV class=box2>
<H2 class=green>C/C++编程 热门推荐</H2>
<DIV class="pic left"><A title=Linux上搭建C/C++IDE开发环境
href="http://unix-cd.com/vc/www/23/2007-06/193.html"><IMG height=75
alt=Linux上搭建C/C++IDE开发环境
src="C语言之typedef的问题 C-C++编程 卓越资源.files/75_75_c782c11c71.gif" width=75></A></DIV>
<UL class="list1 left">
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4797.html">C语言中数组与指针的结合(一)
</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4796.html">C++内存使用</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4795.html">类的构造</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4794.html">编译选项 </A></LI></UL>
<DIV class=clear></DIV>
<UL class=list>
<LI><A
href="http://unix-cd.com/vc/www/23/2007-06/2671.html">农历两百年算法(1901~2100)【C语言代码】
</A>
<LI><A
href="http://unix-cd.com/vc/www/23/2007-06/2672.html">农历一百年算法(1921~2021)【C语言代码】
</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2676.html">在101个数字中查找重复数字
</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2677.html">文件的逆序存储 </A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2678.html">对一个整数按位反转 </A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2679.html">去除数组中的重复数字</A>
<LI><A
href="http://unix-cd.com/vc/www/23/2007-06/2680.html">不使用大于、小于逻辑判断来得到两个数的大小</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2681.html">一个字节中的1的个数 </A>
<LI><A
href="http://unix-cd.com/vc/www/23/2007-06/2682.html">判断32位整数二进制中1的个数的算法</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2683.html">数字字符串转换成整数 </A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2684.html">最大的相同字符子串</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2686.html">将整数转换成字符串 </A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2687.html">最大公约数的求解 </A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-06/2690.html">最常见的20种VC++编译错误信息
</A>
<LI><A
href="http://unix-cd.com/vc/www/23/2007-06/2691.html">C语言标准库中的字符串分割函数</A>
</LI></UL></DIV>
<DIV align=center>
<SCRIPT type=text/javascript><!--
google_ad_client = "pub-3707276699544226";
google_ad_width = 250;
google_ad_height = 250;
google_ad_format = "250x250_as";
google_ad_type = "text_image";
google_ad_channel = "";
google_color_border = "FFFFFF";
google_color_bg = "F7FAF1";
google_color_link = "0000FF";
google_color_text = "000000";
google_color_url = "008000";
//-->
</SCRIPT>
<SCRIPT src="C语言之typedef的问题 C-C++编程 卓越资源.files/show_ads.js"
type=text/javascript>
</SCRIPT>
</DIV>
<DIV class=box2>
<H2 class=green>本类最新文章</H2>
<UL class=list>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4799.html">C中的数组与指针</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4798.html">C语言中数组与指针的结合(二)
</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4797.html">C语言中数组与指针的结合(一)
</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4796.html">C++内存使用</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4795.html">类的构造</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4794.html">编译选项 </A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4793.html">C++操作符重载</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4792.html">C++范型设计,模板</A>
<LI><A href="http://unix-cd.com/vc/www/23/2007-07/4791.html">C表达式中的求值顺序</A>
<LI><A
href="http://unix-cd.com/vc/www/23/2007-07/4790.html">C语言读取文件中每一行的前四个字符</A>
</LI></UL></DIV></DIV></DIV></DIV></DIV>
<DIV class=clear></DIV>
<SCRIPT language=javascript>
// JavaScript Document
var imgMaxWidth=450; //控制内容中图片大小
var content = document.getElementById("content");
ImgLoad(content);
function ImgLoad(obj)
{
for(var i=0;i<obj.getElementsByTagName("img").length;i++){
var o=obj.getElementsByTagName("img")[i];
if (o.width>imgMaxWidth){
if (o.style.width){
o.style.width="";
}
o.width=imgMaxWidth;
o.removeAttribute("height");
o.setAttribute("title","ctrl+鼠标滚轮缩放");
o.style.cursor="hand";
o.style.display="block";
o.vspace=5;
o.resized=1;
o.onclick=ImgClick;
o.onmousewheel=bbimg;
}
}
}
function ImgClick()
{
if (this.parentElement){
if (this.parentElement.tagName!="A"){
window.open(this.src);
}
}else{
window.open(this.src);
}
}
function bbimg()
{
if (event.ctrlKey){
var zoom=parseInt(this.style.zoom, 10)||100;
zoom+=event.wheelDelta/12;
if (zoom>0) this.style.zoom=zoom+'%';
return false;
}else{
return true;
}
}
</SCRIPT>
<!---main----foot-->
<DIV class=footer>
<UL id=footlink>
<LI><A title=Unix爱好者家园 href="http://www.unix-cd.com/unixcd12/"
target=_blank><FONT color=crimson>Unix爱好者家园</FONT></A>
<LI><A title=Unix爱好者家园博客 href="http://www.unix-cd.com/blog/"
target=_blank><FONT color=indigo>Unix爱好者家园博客</FONT></A>
<LI><A title=VeryCMS官方 href="http://www.verycms.net/" target=_self>VeryCMS</A>
</LI></UL>
<DIV>VeryCMS 3.0 鲁ICP备05000455号 <A href="mailto:sdccf@163.com"
target=_blank>联系我们</A> <BR>Powered by <A
href="http://www.phpwind.com/"><STRONG>PHPWind</STRONG></A> Code ©2003-07 <A
href="http://www.phpwind.com/"><STRONG>PHPWind.com</STRONG></A> Corporation
</DIV></DIV>
<SCRIPT language=javascript
src="C语言之typedef的问题 C-C++编程 卓越资源.files/click.aspx"></SCRIPT>
<SCRIPT language=JavaScript src="C语言之typedef的问题 C-C++编程 卓越资源.files/stat.htm"
charset=gb2312></SCRIPT>
<SCRIPT src="C语言之typedef的问题 C-C++编程 卓越资源.files/click.htm"></SCRIPT>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -