C语言typedef关键字—伟大的缝纫师

关于马甲的笑话。有这样一个笑话:一个猎人在河边抓捕一条蛇,蛇逃进了水里。过一会,一个乌龟爬到岸边。猎人一把抓住这个乌龟,大声的说道:小样,别你为你穿了个马甲我就不认识你了!

typedef 关键字是个伟大的缝纫师,擅长做马甲,任何东西穿上这个马甲就立马变样。它可以把狼变成一头羊,也能把羊变成一头狼。甚至还可以把长着翅膀的鸟人变成天使,同样也能把美丽的天使变成鸟人。所以,你千万不要得罪它,一定要掌握它的脾气,不然哪天我把你当鸟人,你可别怪我。^_^。

一、历史的误会——也许应该是typerename。

很多人认为typedef 是定义新的数据类型,这可能与这个关键字有关。本来嘛,type 是数据类型的意思;def(ine)是定义的意思,合起来就是定义数据类型啦。不过很遗憾,这种理解是不正确的。也许这个关键字该被替换为“typerename”或是别的词。 typedef 的真正意思是给一个已经存在的数据类型(注意:是类型不是变量)取一个别名,而非定义一个新的数据类型。比如:华美绝伦的芍药,就有个别名---“将离”。中国古代男女交往,往往以芍药相赠,表达惜别之情,送芍药就意味着即将分离。所以文人墨客就给芍药取了个意味深长的别名-----“将离”。这个新的名字就表达了那种依依不舍的惜别之情…这样新的名字与原来的名字相比,就更能表达出想要表达的意思。

在实际项目中,为了方便,可能很多数据类型(尤其是结构体之类的自定义数据类型)需要我们重新取一个适用实际情况的别名。这时候typedef 就可以帮助我们。例如:
typedef struct student
{
   //code
}Stu_st,*Stu_pst;//命名规则请参考本章前面部分

A),struct student stu1;和Stu_st stu1;没有区别。
B),struct student *stu2;和Stu_pst stu2;和Stu_st *stu2;没有区别。

这个地方很多初学者迷惑,B)的两个定义为什么相等呢?其实很好理解。我们把“struct student { /*code*/}”看成一个整体,typedef 就是给“struct student {/*code*/}”取了个别名叫“Stu_st”;同时给“struct student { /*code*/} *”取了个别名叫“Stu_pst”。只不过这两个名字同时取而已,好比你给你家小狗取了个别名叫“大黄”,同时你妹妹给小狗带了小帽子,然后给它取了个别名叫“小可爱”。^_^。

好,下面再把typedef 与const 放在一起看看:
C),const Stu_pst stu3;
D),Stu_pst const stu4;

大多数初学者认为C)里const 修饰的是stu3 指向的对象;D)里const 修饰的是stu4这个指针。很遗憾,C)里const 修饰的并不是stu3 指向的对象。那const 这时候到底修饰的是什么呢?我们在讲解const int i 的时候说过const 放在类型名“int”前后都行;而const int *p 与int * const p 则完全不一样。 也就是说,我们看const 修饰谁都时候完全可以将数据类型名视而不见,当它不存在。反过来再看“const Stu_pst stu3”,Stu_pst 是“struct student { /*code*/} *”的别名, “struct student {/*code*/} *”是一个整体。 对于编译器来说,只认为Stu_pst 是一个类型名,所以在解析的时候很自然的把“Stu_pst”这个数据类型名忽略掉。

现在知道const 到底修饰的是什么了吧?^_^。

二、typedef 与#define 的区别

噢,上帝!这真要命!别急,要命的还在后面呢。看如下例子:
E) #define INT32 int
       unsigned INT32 i = 10;
F)typedef int int32;
      unsigned int32 j = 10;

其中F)编译出错,为什么呢?E)不会出错,这很好理解, 因为在预编译的时候INT32被替换为int,而unsigned int i = 10;语句是正确的。但是,很可惜,用typedef 取的别名不支持这种类型扩展。另外,想想typedef static int int32 行不行?为什么?

下面再看一个与#define 宏有关的例子:
G)  #define PCHAR char*
      PCHAR p3,p4;
H)typedef char* pchar;
       pchar p1,p2;

两组代码编译都没有问题, 但是,这里的p4 却不是指针,仅仅是一个char 类型的字符。这种错误很容易被忽略,所以用#define 的时候要慎之又慎。关于#define 当然还有很多话题需要讨论,请看预处理那一章。当然关于typedef 的讨论也还没有结束,在指针与数组那一章,我们还要继续讨论。

三、#define a int[10]与typedef int a[10];

留两个问题:

1)#define a int[10]
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

2) typedef int a[10];
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

3) #define a int*[10]
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

4)   typedef int * a[10];
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

5) #define *a int[10]
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

6)   typedef int (* a)[10];
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

7) #define *a * int[10]
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

8)  typedef int * (* a)[10];
A),a[10] a[10];
B),a[10] a;
C),int a[10];
D),int a;
E),a b[10];
F),a b;
G),a* b[10];
H),a* b;

请判断这里面哪些定义正确,哪些定义不正确。另外,int[10]和a[10]到底该怎么用?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450523.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将网桥的配置写进去/etc/sysconfig/network-scripts/ifcfg-xxx

有时候需要使用网桥命令比如brctl设置一些网桥的属性,而这些方式能否同样写进去配置文件使其永久开机生效。 答案是不行的,也同样找过Ubuntu的,其实Ubuntu可以实现,参考:http://manpages.ubuntu.com/manpages/cosmic/m…

phpstorm如何回滚。并取消本地提交

1、现在我提交到本地 当前git版本为4b53dca9 上一版本为965cdf14 2、现在执行回滚操作,取消本地提交 版本复制到这里,点击reset就会回滚了 如需使用git命令操作,请参考链接https://blog.csdn.net/qq_35774849/article/details/107313193

windows server 2008 R2 x64 基础知识(2)

一、防火墙设置 1.windows防火墙的种类: 1)工作组网络环境 2)域网络环境 2.防火墙的配置 1)打开管理工具:win->管理工具->高级安全windows防火墙 2)管理配置: (1)防火墙的数据流类型 a.入站流量:外部访问内部分流量 b…

SOA 说明,解析

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 一直对SOA这个概念不甚明了,再度记录下: 一、是一个面向服务的架构,是一种思想、规则。而不是一个确…

Windows API 第二篇 SHGetSpecialFolderPath

BOOL SHGetSpecialFolderPath( HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate ); 参数解释: hwndOwner:Handle to the owner wind…

面向对象—的__new__()方法详解

[Python] Python 之 __new__() 方法与实例化 __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__() 负责将类的实例化,而在 __init__() 启动之前&#…

git使用回滚,清除暂缓区,解决冲突(持续更新)

1、git restore --staged <文件> 清除暂缓区文件名 2、git reset --hard <版本号> 回滚到上一版本 如看PHPstrom如何操作请参考https://blog.csdn.net/qq_35774849/article/details/107312658 3、解决冲突 &#xff08;1&#xff09;使用默认的解决冲突 打开…

14.安全

1.基本概念 安全问题的产生&#xff1a; 互联网作为商业交易的工具快速发展&#xff0c;越来越多的公司提供网络交易服务。很多商业活动在网上进行当前&#xff0c;成千上万的网民在网上进行各种活动的同时&#xff0c;也在网上传递其个人信息每天在网上发生各种各样的商业活动…

C语言enum关键字

很多初学者对枚举(enum)感到迷惑&#xff0c;或者认为没什么用&#xff0c;其实枚举(enum)是个很有用的数据类型。一、枚举类型的使用方法 一般的定义方式如下&#xff1a;enum enum_type_name{ENUM_CONST_1,ENUM_CONST_2,...ENUM_CONST_n} enum_variable_name;注意&#xff1a…

Dubbo 需求、架构、使用Demo

只是整理下方便自己记录 内容全部来自官网&#xff1a;http://dubbo.io/books/dubbo-user-book/preface/usage.html 一、需求 在大规模服务化之前&#xff0c;应用可能只是通过 RMI 或 Hessian 等工具&#xff0c;简单的暴露和引用远程服务&#xff0c;通过配置服务的URL地址进…

Ubuntu安装之python开发

Ubuntu安装之python开发 什么&#xff1f;&#xff1f;Ubuntu(乌班图)开发&#xff1f;不会用&#xff1f;&#xff1f;怎么进行python开发&#xff1f;&#xff1f;&#xff1f; 乌班图操作系统下载地址&#xff1a;http://releases.ubuntu.com/18.04/ubuntu-18.04.1-desktop-…

vimdiff和vim-fugitive安装,使用教程

1、vimdiff的安装 在终端执行 git config --global merge.tool vimdiff git config --global merge.conflictstyle diff3 git config --global mergetool.prompt false git config --global diff.tool vimdiff git config --global difftool.prompt false git config --…

在 PowerPoint 2016 中嵌入网页

之前在智图这个网站上做了一张地图&#xff0c;在嵌入 PPT 里面的时候碰到了一些问题&#xff0c;现在把找到的解决方法写下来。 PPT 里面自带的 WebBrowser 控件可以实现网页浏览的功能。在“开发工具”选项卡下的“其他控件”中找到“Microsoft Web Browser”&#xff0c;在画…

js 正则表达式 整合

正则表达式:断言 取字符串区间: /(?<[" star "]).*(?[" end "])/// 简单封装 Vue.prototype.strMatch (str,star,end) > { let regs new RegExp("(?<[" star "]).*(?[" end "])"); let req str…

dubbo 注册中心zookeeper 手册

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 zookeeper 注册中心 Zookeeper 是 Apacahe Hadoop 的子项目&#xff0c;是一个树型的目录服务&#xff0c;支持变更推送&#xff0c;适…

数组 深入详解

再论C语言数组 C语言处理数组的方式是它广受欢迎的原因之一。C语言对数组的处理是非常有效的&#xff0c;其原因有以下三点&#xff1a;第一&#xff0c;除少数翻译器出于谨慎会作一些繁琐的规定外&#xff0c;C语言的数组下标是在一个很低的层次上处理的。但这个优点也有一个反…

oracle ins-30131错误

打开cmd 但是在我的环境没效果&#xff0c;而我已知临时目录没有问题。那么在命令行进入安装软件目录&#xff0c;通过命令行启动安装程序&#xff0c;设置 ignorePrereq 检查&#xff0c;此时数据库软件可以启动安装&#xff0c;是否会出现错误&#xff0c;就看忽略的检查是否…

iOS开发UI篇—简单介绍静态单元格的使用

一、实现效果与说明 说明&#xff1a;观察上面的展示效果&#xff0c;可以发现整个界面是由一个tableview来展示的&#xff0c;上面的数据都是固定的&#xff0c;且几乎不会改变。 要完成上面的效果&#xff0c;有几种方法&#xff1a; &#xff08;1&#xff09;可以直接利用代…

展示内容

今天课上展示了软件 评价为过于简单 还需另寻他法转载于:https://www.cnblogs.com/wmqlzm/p/10041683.html

dubbo ,dubbo-provider、dubbo-consumer 配置参数说明

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 dubbo:consumer 服务消费者缺省值配置。配置类&#xff1a; com.alibaba.dubbo.config.ConsumerConfig 。同时该标签为 <dubbo:refer…