typedef的用法小总结

2023-11-11

首先是typedef历史遗留问题,经常看到很多人写结构体就写:

typedef struct _A{int a;int b;}A;

A b;

我就一直很纳闷,为什么不直接写_A b呢?

昨天查资料才知道,原来这个是因为c语言遗留下来的,在C语言中,结构体对象声明必须加关键字struct,所以按C语言语法是:

struct  _A b;

大家都知道程序员很讲究效率,编代码也是,能少些一个单词绝不多写,所以用typedef确实是可以少些一个单词。

 

其实typedef不光可以少些单词,更重要的是代码美观,和避免拙劣代码(这个后面会提到)。

typedef常用方法分为3点

 

1:typedef为已经存在的类型定义别名,以增强可读性和避免平台的底层差异。

typedef int size;

size len=strlen(str);

这样类型名在一定程度上起了提示作用。而且可以避免平台的底层实现问题。如某个嵌入式平台没有实现int类型,而是由一个integer或者double。这个是用只需将项目的typedef改一下就可以,整个项目几乎不用动(如果新的类型不引发逻辑错误的话)。

 

常见的还有定义指针的:如

typedef void* PVOID;//etc

 

2:定义数组对象

typedef int array[2][2];

array b;

这个时候b就代码int[2][2]了。具体解析在第3点之后讲

 

3:定义函数指针

typedef int(*pF)(const char*,const char*);

这就定义了pF为一个函数指针。其返回值为int,参数是两个const char*。

 

由于pF是函数指针,所以可以声明这么一个函数,函数名是Register,函数的参数是一个pF类型的函数指针,返回值也是一个pF类型的函数指针。

pF Register(pF p);

但是如果没有typedef那会怎么样呢?

 

int(*Register (int(*pF)(const char*,const char*)))(const char*,const char*);

试问人世间愿意看到这样的代码的正常人还有多少?

我来分析一下为什么是这么写的,首先Register的参数列表是( int(*pF)(const char*,const char*) ),最外层括号里面是一个函数指针参数。

然后看函数名左边是*号,说明函数返回一个指针,然后用指针的眼光看待,把函数指针从结构中抽离出来就是int(*)(const char*,const char*)了。

 

其中2,3方法中牵扯到一个typedef的识别规则,就是“右左法则”先往又看到一个括号或结尾,然后往往左看一个括号或结尾,重复此过程直到分析结束。

 

用这个方法分析2,3.先分析2:

先往右看是[2][2]说明array是一个数组,往左看知道他是int类型。这样就知道array代表整型2维数组。

再分析3:

先往又看是括号没说明什么,然后往左看是*,说明pF是指针。然后再忘又看是参数列表,说明是函数指针,再往左看是int就知道他是返回值了。

 

同时typedef的一些常出的错误:

1:

typedef char* PSTR;

const PSTR a;

此时const PSTR不代表const char*;而是代表char const*;

因为要从本质的理解const用法,const是给某个属性附加上常量属性。所以const PSTR是对字符指针加上不可变的常量属性。

就指针而言不可变是指的其指向不可变。

如果不明白的好:好好看看 const char*和char const*的区别。

 

2:

typedef在语法上是以存储关键字,所以typedef不能与auto,static,register,extern,mutable连用

如果连用:

typedef static int SINT;

编译器就是报告错误:有一个以上的存储关键字!

 

还有一些typedef经常与#define进行比较。

typedef比#define更结构化。

#define就是宏替换。而typedef是在语法级别上的代替。

所以一下代码比较:

 

typedef char* PSTR;

PSTR a,b;

 

相当于char* a;char *b;

而#define不然;请看

 

#define PSTR char *

PSTR a,b;

 

相当于char* a,b;

初学者可不要以为char *a,b;和char *a,char *b;是一回事。

C++基础知识里面有char* a,b;并没有把char* 类型给b,而是只给了char类型。所以char* a,b;中b是char类型而不是char*。

 

打完收工!

 

 

分享自己的心得,是帮助了别人,升华了自己!

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

typedef的用法小总结 的相关文章

  • 简单的C问题

    作为我正在进行的项目的一部分 我必须开始学习 C 我已经开始解决其中的 欧拉 问题 并且遇到了麻烦 我必须找到 1000 以下的所有 3 或 5 的倍数之和 有人可以帮助我吗 谢谢 include
  • 数据结构的优化存储以实现快速查找和持久化

    Scenario 我有以下方法 public void AddItemSecurity int itemId int userIds public int GetValidItemIds int userId 最初我正在考虑表单上的存储 i
  • 为什么在 OpenCV 中访问该矩阵时出现内存错误?

    我只是想写入给定大小的矩阵 当我在 Valgrind 中运行该程序时 出现内存错误 如下所示 主要 cpp include
  • 不能使用函数名称距离

    以下代码可以正常编译 include
  • 如何在Qt中更快地读取数据?

    Qt读取数据库比C 慢吗 我想我错过了一些东西 为了比较阅读速度 我在 Qt 中编写了以下内容 QElapsedTimer t t start int count 0 QString cs Driver SQL Server Server
  • 有没有办法让我的程序用更少的代码运行?

    我为学校作业编写了以下代码 它编译并打印所有正确的消息 但出于我自己的好奇心 我想知道我的代码是否可以缩短并且仍然有效 我尝试了 signal 而不是 sigaction 但我听说 sigaction 比 signal 更受青睐 此外 此任
  • 如何自定义 ASP.Net Core 模型绑定错误?

    我只想从我的 Web API Asp net Core 2 1 返回标准化的错误响应 但我似乎不知道如何处理模型绑定错误 该项目刚刚从 ASP NET Core Web 应用程序 gt API 模板创建 我有一个简单的操作定义为 Route
  • 使用 pthread_cond_signal 优雅地终止线程被证明是有问题的

    我需要发射一堆线程 并希望优雅地将它们拉下来 我正在尝试使用pthread cond signal pthread cond wait实现这一目标 但遇到了问题 这是我的代码 首先是thread main static void thrma
  • 对无符号 8 位整数进行左移操作 [重复]

    这个问题在这里已经有答案了 我试图理解 C C 中的移位运算符 但它们给我带来了困难 我有一个无符号 8 位整数 初始化为一个值 例如 1 uint8 t x 1 根据我的理解 它在内存中的表示方式如下 0 0 0 0 0 0 0 1 现在
  • 在 C++ 中初始化指针

    可以在声明时将指针分配给值吗 像这样的东西 int p 1000 是的 您可以在声明时初始化指向值的指针 但是您不能这样做 int p 1000 是个地址运算符 并且您不能将其应用于常量 尽管如果可以 那会很有趣 尝试使用另一个变量 int
  • DataContractJsonSerializer 包含元素类型子类型的通用列表

    我要使用DataContractJsonSerializer用于 JSON 序列化 反序列化 我在 JSON 数组中有两种对象类型 并希望将它们都反序列化为相应的对象类型 具有以下类定义 DataContract public class
  • 如何在 C 预处理器中可靠地检测 Mac OS X、iOS、Linux、Windows? [复制]

    这个问题在这里已经有答案了 如果有一些跨平台 C C 代码需要在 Mac OS X iOS Linux Windows 上编译 我如何在预处理器过程中可靠地检测到它们 大多数编译器都使用预定义的宏 您可以找到列表here http sour
  • Xamarin.Android JmDNS 绑定问题

    我开始研究 Xamarin Android 的 JmDNS 绑定 我设法构建了绑定 但无法从代码中引用它 https github com ytn3rd monodroid bindings tree master JmDNS https
  • 来自资源中 ImageSource 的 System.Drawing.Image

    我的问题与这个非常相似 wpf图像资源以及运行时在wpf控件中更改图像 https stackoverflow com questions 940592 wpf image resources and changing image in w
  • C 中函数“fgets”的参数太少

    每当我编译这个错误时 我都会收到该错误 但我不知道为什么 我直接从书上抄袭这个 有人可以帮忙吗 include
  • 您的 C++ 程序中是否仍然存在内存分配失败问题 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在为公司写一些指导方针 我需要回答一些棘手的问题 这一项是相当困难的 解决方案可以是 根本不跟踪 确保使用 new 分配对象 这会在分配失败
  • 使用 QTestLib 时抑制 qDebug

    我正在向 Qt 中的项目添加单元测试 并希望使用 QTestLib 我已经设置了测试并且它们运行良好 问题是在项目中我们重写了 qDebug 以输出到我们自己的日志文件 这在运行应用程序时效果很好 问题是当我测试类时 它有时会开始记录 然后
  • 如何在您的网站中连接两个人

    有一款名为 Verbosity 的游戏 这是一款有目的的游戏 位于此链接上www gwap com 在游戏中 他们随机连接两个玩家互相玩 游戏是玩家1应该向他的搭档 玩家2 描述一个单词 而玩家2应该猜测这个单词 我正在尝试建立一个网站来执
  • 使用 Crypto++ 和 .NET 的 CFB 模式下的 TripleDES

    我正在尝试使用 TripleDES 使用 C 应用程序获得相同的结果 该应用程序具有Crypto https www cryptopp com 和 NET应用程序使用三重DESCryptoServiceProvider https msdn
  • 应用非限定名称查找而不是依赖于参数的名称查找

    考虑标准 sec 3 4 1 3 中的一个示例 typedef int f namespace N struct A friend void f A operator int void g A a int i f a f is the ty

随机推荐