动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ C/C++教程 ]的信息



本月文章推荐
.a simple menu programme.
.用MasterPage 代替 PageBase.
.用C++ Builder创建组合框.
.C/C++程序员应聘常见面试题深入剖.
.拼图游戏.
.也谈TTreeView、TListView用法.
.关于全排列算法,大家请指导!.
.JAVA与C++::关于JNI中文字符串操.
.C++的错误和异常处理分析.
.C语言嵌入系统编程修炼-性能优化.
.具体而微的绘图程式-c++ Borland.
.C语言初学者入门讲座 第二讲 数据.
.高质量C++/C编程指南 --&nb.
.详述C++语言的VxD与外界通讯的所.
.c++经典.
.C语言库函数(G类字母).
.设置壁纸方法.
.C语言初学者入门讲座 第二讲 数据.
.C++ Builder 初学问与答(十五).
.C语言的特点.

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

发表日期:2008-3-8 |


  1. 基本解释

  typedef为C语言的要害字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(strUCt等)。

  在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。

  至于typedef有什么微妙之处,请你接着看下面对几个问题的具体阐述。   2. typedef &结构的问题

  当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不答应在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明:

typedef struct tagNode
{
 char *pItem;
 pNode pNext;
} *pNode;
  答案与分析

  1、typedef的最简单使用

typedef long byte_4;
  给已知数据类型long起个新名字,叫byte_4。

  2、 typedef与结构结合使用

typedef struct tagMyStruct
{
 int iNum;
 long lLength;
} MyStruct;
  这语句实际上完成两个操作:

  1) 定义一个新的结构类型

struct tagMyStruct
{
 int iNum;
 long lLength;
};
  分析:tagMyStruct称为“tag”,即“标签”,实际上是一个临时名字,struct 要害字和tagMyStruct一起,构成了这个结构类型,不论是否有typedef,这个结构都存在。

  我们可以用struct tagMyStruct varName来定义变量,但要注重,使用tagMyStruct varName来定义变量是不对的,因为struct 和tagMyStruct合在一起才能表示一个结构类型。

  2) typedef为这个新的结构起了一个名字,叫MyStruct。

typedef struct tagMyStruct MyStruct;
  因此,MyStruct实际上相当于struct tagMyStruct,我们可以使用MyStruct varName来定义变量。

  答案与分析

  C语言当然答应在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。

  根据我们上面的阐述可以知道:新结构建立的过程中碰到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不熟悉pNode。

  解决这个问题的方法有多种:

  1)、

typedef struct tagNode
{
 char *pItem;
 struct tagNode *pNext;
} *pNode;
  2)、

typedef struct tagNode *pNode;
struct tagNode
{
 char *pItem;
 pNode pNext;
};
  注重:在这个例子中,你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。

  3)、规范做法:

struct tagNode
{
 char *pItem;
 struct tagNode *pNext;
};
typedef struct tagNode *pNode;   3. typedef & #define的问题

  有下面两种定义pStr数据类型的方法,两者有什么不同?哪一种更好一点?

typedef char *pStr;
#define pStr char *;
  答案与分析

  通常讲,typedef要比#define要好,非凡是在有指针的场合。请看例子:

typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
  在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。

  #define用法例子:

#define f(x) x*x
main( )
{
 int a=6,b=2,c;
 c=f(a) / f(b);
 printf("%d \n",c);
}
  以下程序的输出结果是: 36。

  因为如此原因,在许多C语言编程规范中提到使用#define定义时,假如定义中包含表达式,必须使用括号,则上述定义应该如下定义才对:


#define f(x) (x*x)
  当然,假如你使用typedef就没有这样的问题。

  4. typedef & #define的另一例

  下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?

typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
  答案与分析

  是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。

(注:关于const的限定内容问题,在本系列第二篇有具体讲解)。

  #define与typedef引申谈

  1) #define宏定义有一个非凡的优点:可以使用 #ifdef ,#ifndef等来进行逻辑判定,还可以使用#undef来取消定义。

  2) typedef也有一个非凡的优点:它符合范围规则,使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。

  5. typedef & 复杂的变量声明

  在编程实践中,尤其是看别人代码的时候,经常会碰到比较复杂的变量声明,使用typedef作简化自有其价值,比如:

  下面是三个变量的声明,我想使用typdef分别给它们定义一个别名,请问该如何做?

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

  对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把要害字typedef加在该语句的开头就行了。

  (注:假如你对有些变量的声明语法感到难以理解,请参阅本系列第十篇的相关内容)。

>1:int *(*a[5])(int, char*);
//pFun是我们建的一个类型别名
typedef int *(*pFun)(int, char*);
//使用定义的新类型来声明对象,等价于int* (*a[5])(int, char*);
pFun a[5];

>2:void (*b[10]) (void (*)());
//首先为上面表达式蓝色部分声明一个新类型
typedef void (*pFunParam)();
//整体声明一个新类型
typedef void (*pFun)(pFunParam);
//使用定义的新类型来声明对象,等价于void (*b[10]) (void (*)());
pFun b[10];

>3. doube(*)() (*pa)[9];
//首先为上面表达式蓝色部分声明一个新类型
typedef double(*pFun)();
//整体声明一个新类型
typedef pFun (*pFunParam)[9];
//使用定义的新类型来声明对象,等价于doube(*)() (*pa)[9];
pFunParam pa;
上一篇:C语言初学者的十八颗“地雷” 人气:245
下一篇:实例讲解 - C 语言的循环结构 人气:403
浏览全部C/C++的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-24 Sablog-X v2.0 预览版
2008-7-24 帝国备份王EmpireBak 2008 正式版
2008-7-24 网趣网上购物系统时尚版 v8.2
2008-7-24 纵横B2B电子商务系统XYECS!B2B v
2008-7-24 e路小说小偷 v1.2.0723
2008-7-24 凌风美女图片站程序 v2.2
2008-7-24 TOM15电影收索程序
2008-7-24 清风信息自动采集生成系统 v1.0
2008-7-24 QQ邮箱编辑器 v1.0 (小小菜刀ASP
2008-7-19 UltraEdit 简体中文增强版 14.10
2008-7-19 CentOS 5.2 i386 LiveCD
2008-7-19 Snapture多功能相机 v1.4
2008-7-19 iAcces中文输入法 v1.0Build016
2008-7-19 Cookbook烹饪秘籍 v2.5
2008-7-19 苹果专用DVD转换工具 v1.1.59汉化
2008-7-19 Modem修复软件ZiPhone修改版04.0
2008-7-19 AgileMessenger即时通讯工具美化
2008-7-19 Sketches画图软件 v0.7b6破解版


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号