这里定义的叫ElemType的结构体是什么意思?是typedef的另一种写法么?

  • IP 虚拟人(IP Virtual Human,IVH)运用了语音交互、数字模型生成等多项 AI 技术,让 IP 虚拟人的口型与发音一致、表情及动作自然拟人。IP 虚拟人支持 AI 合成虚拟形象播报视频和实时语音交互两大类使用场景,其中虚拟形象播报能力支持输入文本生成 AI 合成的音视频文件,广泛运用于媒体、教育、会展服务等场景;语音交互场景支持与用户进行实时语音互动,广泛运用于客服、助理等场景。

}

typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异。它本身是一种存储类的关键字,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中;
typedef 中文解释:声明类型

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

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

1、创建平台无关的数据类型,隐藏笨拙且难以理解的语法

已知数据类型long起个新名字byte_4

2、掩饰复合类型,如指针和数组
下面这样重复定义有 81 个字符元素的数组:

定义,Line类型即代表了具有81个元素的字符数组,使用方法如下:

这语句实际上完成两个操作:
(1)定义一个新的结构类型

和tagMyStruct合在一起才能表示一个结构类型。
(2)typedef为这个新的结构起了一个名字,叫MyStruct。

4、下面的代码定义一个结构时,编译器报了一个错误,莫非C语言不允许在结构中包含指向它自己的指针吗?

C语言当然允许在结构中包含指向它自己的指针,上述代码的根本问题在于typedef的应用。新结构建立的过程中遇到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不认识pNode。
解决这个问题的方法有多种:

注意:在这个例子中,typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法,但是不推荐这种写法。

#define只是简单的字符串替换而typedef则是为一个类型起新名字。
一般来说,typedef要比#define要好,特别是在有指针的场合。

在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是所预期的指针变量。要达到所预期的效果,上例中define语句必须写成 pStr2 s3, *s4; 这样才能正常执行。

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

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

10、 #define宏定义有一个特别的长处:可以使用 #ifdef ,#ifndef等来进行逻辑判断,还可以使用#undef来取消定义。

在C或C++语言中,“宏”分为有参数和无参数两种。
(1)无参宏的宏名后不带参数。

其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。

注意:宏定义不是说明或语句,在行末不必加分号,如加上分号则连分号也一起置换。
宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#undef命令

(2)c语言允许宏带有参数。
在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为:

11、 typedef 行为有点像 #define 宏,用其实际类型替代同义字。不同点是 typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。

这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。如果要使用下列形式的函数声明,那么上述这个 typedef 是不可或缺的:

Register() 的参数是一个 PF 类型的回调函数,返回某个函数的地址,其署名与先前注册的名字相同。做下面展示一下如果不用 typedef,我们是如何实现这个声明的:

很少有程序员理解它是什么意思,更不用说这种费解的代码所带来的出错风险了。显然,这里使用 typedef 不是一种特权,而是一种必需。持怀疑态度的人可能会问:“OK,有人还会写这样的代码吗?”,快速浏览一下揭示 signal()函数的头文件 ,一个有同样接口的函数。

注意这里Register被定义为一个函数而不是函数指针,如果要定义为函数指针应该这样写:

12、ypedef 另外一个重要的用途,那就是定义机器无关的类型
定义一个叫 REAL 的浮点类型,在目标机器上它可以获得最高的精度:

并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:

你不用对源代码做任何修改,便可以在每一种平台上编译这个使用 REAL 类型的应用程序。
标准库广泛地使用 typedef 来创建这样的平台无关类型

定义了一个类型别名bitnode,实际上指的就是struct node这个完整类型.typedef定义的类型别名在作用域内和被定义的原类型语义上等价,都是表示同一个类型的名称。这里typedef之后bitnode可以和struct node互相代替。

}
C++中指针和引用都是一个地址,区别在于:
1,指针可以为空(NULL),引用必须为一个实际地址。因此定义指针无需给初值,而引用定义是必须同时初始化。
2,引用一经定义就不能再改变,指针则可以重新赋值、进行指针运算。因此引用是中代表同一个变量,而指针则可随时只想不同的变量。
3,指针可以定义为常数,而引用必须为变量的地址。
4,引用主要用于从函数传回参数值,同时避免指针溢出的危险。
在void InitList(Sqlist &L)中&L表示传给函数的是实际参数的地址,函数内所作的任何改变都是对该参数的直接改变。如果把“&”,则表示传给函数的是实际参数的值,或者说是它的一个副本。函数结束时,副本就被丢弃了,所以任何变化都不会影响实际参数本身。
}

我要回帖

更多关于 结构体指针是什么意思 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信