欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

struct结构体的多种声明方式

程序员文章站 2022-07-10 09:23:08
...

结构体声明

方法1

在声明结构体时,必须列出它包含的所有成员
语法结构 struct tag { member-list} variable-list;

struct {
		int a ;
		float b;
		double c;
		short d;
		
}x;

这个声明创建名为X的变量,它包含四个成员。


struct {
		int a ;
		float b;
		double c;
		short d;
		
}y[20],*z;

这个声明创建名为y和Z的指针变量,y是一个数组,它包含20个结构。Z是一个指针,指向这类型的结构。

这两个声明是截然不同的类型,即使他们的成员列表完全相同,因此 z = &x是非法的


方法2

/*标签 类似于面包形状模板,它给定了制作出来的面包的形状,但是它没有制作出面包*/ 
struct  SIMPLE {
		int a ;
		float b;
		double c;
		short d;
		
};
/*利用上述的标签(面包模板),制作出一个面包(SIMPLE 类型的结构体)*/
struct SIMPLE x;
struct SIMPLE y[20],*z;

标签标识了一种模式,用于声明未来的变量,但是无论标签还是模式
本身都不是变量,这个和方法1的最大区别—x,y,z是同一种类型的结构体变量


方法3

最常用的使用技巧typedef 创建一种新的类型
typedef struct{
		int		a;
		char 	b;
		float	c;
		
} Simple;

这个技巧和声明一个结构体标签的效果几乎相同,区别在于Simple现在是类型名
而不是个结构标签,

struct Simple x;
struct Simple y[20],*z;

结构体的访问

声明结构体
struct Simple x,*z; //声明一个 结构体变量x,和一个指向结构体变量的指针。

访问变量x的结构体成员
x.a;
x.b;
x.c;

访问指针Z
z->a;
z->b;
z->c;

结构体的自引用

结构体的自引用就是在一个结构体内部包含这个结构体本身。
struct SELP_REF1{
		int 	a;
		struct SELP_REF1 b;
		int 	c;
} //非法

这个方法是非法的,成员b是另一个完整的结构体,其内部还将包含它自己的成员b.
第二个成员又是另外一个完整的结构体,它还包含自己的成员b。这样永无止境循环。

struct SELP_REF1{
		int 	a;
		struct SELP_REF1 *b;
		int 	c;
}//合法

区别在于b现在是一个指针不是一个结构体,编译器在结构的长度确定之前就知道指针的长度,所以这种类型的自引用是合法的。

如果你觉得一个结构内部包含一个指向该结构体本身的指针有些奇怪,请记住它事实上指向的是同一种类型的不同结构体。更加高级的数据结构,如链表和树,都是使用这种技巧实现的每个结构指向链表的下一个元素或树的下一个分支。

警告

typedef struct {
		int 	a;
		SELP_REF3	*b;
		int 	c;
}SELP_REF3;

这个声明的目的是为这个结构体创建类型名 SELP_REF3。但是,它失败了
类型名直到声明的末尾才定义,所以在结构声明的内部它尚未定义。

解决方案是定义一个结构体标签来声明b,

typedef struct SELP_REF3_TAG {
		int 	a;
		struct SELP_REF3_TAG *b;
		int		c;
}SELP_REF3;

联合体的初始化

联合体可以被初始化,但这个初始化必须是第一个成员的类型,而且它必须位于一个花括号内

union {
	int		a;
	char   	b;
	float 	c[5];
}x = {5};
把 x.a 初始化为5

我们不能把这个初始化的类量初始化为 字符型,浮点型,只能是第一个成员的类型。如果被初始化为其他类型,则进行强制转换(如果可以转换),再赋值给x.a。

本文参考《C和指针》这个本书写的。

相关标签: struct