声明结构体的几种方法

  • Post author:
  • Post category:其他





前言

在C语言中,常常使用数组存储若干个同种类型的数据,若想存储不同类型的数据,就要用到结构体了,结构体是一些值的集合,这些值称为它的成员,下面叙述声明结构体的误区:

1struct{
     int a;
     char b;
}ss;
2struct{
int a;
char b;
}st;

声明1创建了一个名为ss的变量,声明2创建了一个名为st的变量,它们都包含两个成员:int型的a和char型的b。需要注意,虽然ss和st的成员完全相同,但是这样声明会被编译器处理为两种不同的数据类型,不能相互赋值,示例如下:

#include <stdio.h>
struct {
	int a;
	char b;
}st;
struct 
{
	int a;
	char b;
}ss;
int main(void)
{
	scanf("%d %c", &ss.a, &ss.b);
	printf("ss的值分别为:%d %c\n", ss.a, ss.b);
	st = ss;
	return 0;
}

会报如下类型不匹配的错误:

在这里插入图片描述



标签

如果想创建同一种类型的结构体变量,需要用到标签,示例如下:

struct hhh{
int a;
char b;
}

这种方法并没有创建任何变量,而是把标签和成员列表绑定在一起,标签的作用就是标识了一种类型,以后使用相同标签声明的变量就是同一种类型的结构体变量。定义变量示例如下:

struct hhh ss,st;

此时ss和st就是同一种类型的变量了,就可以相互赋值,示例如下:

#include <stdio.h>
struct hhh{
	int a;
	char b;
};
struct hhh ss, st;
int main(void)
{
	scanf("%d %c", &ss.a,&ss.b);
	printf("ss的值分别为:%d %c\n", ss.a, ss.b);
	st = ss;
	printf("st的值分别为:%d %c\n", st.a, st.b);
	return 0;
}

运行结果如下:

在这里插入图片描述



typedef

使用typedef是另外一种创建相同类型的结构体变量的方法,示例如下:

typedef struct{
int a;
char b;
}hhh;

该方法和标签方法的区别是hhh是一个类型名,而不是标签,因此定义变量的方法就不同了,定义变量示例如下:

hhh ss,st;



结构体的自引用



方法一

在使用C/C++编写链表程序时,会经常用到结构体的自引用,也就是一个结构体的成员包含该类型的结构体变量,一个错误用法如下:

struct hhh{
int data;
struct hhh next;
}

上述方法是错误的,因为next是一个结构体变量,但是”struct hhh”类型的长度不确定,结构体变量next内部也是相同结构,因此编译器会一直递归寻找该类型的长度,却没有终点。

struct hhh{
int data;
struct hhh *next;
}

这种方法是正确的,和上述程序的区别是next是指针变量,指针变量的长度是一个确定的值,在32位系统下,任何类型的指针变量都是4个字节,因此该结构体的长度是确定的,next存储的是一个该类型变量的地址。



方法二

也可使用typedef方法完成结构体的自引用,首先展示一个错误用法,示例如下:

typedef struct{
int data;
ss *next;
}ss;

这种方法是错误的,因为类型名ss在该结构体声明的末尾才定义,却在结构体内部使用了,此时ss还没定义,自然会报错了,正确用法的实例如下:

typedef struct hhh{
int data;
struct hhh *next;
}ss,*st;

这种方法将typedef和标签结合起来,结构体内部使用标签声明变量,该方法声明了ss类型的结构体和指向ss类型的指针st,形式简单,经常用于链表的编程。



版权声明:本文为qq_39686950原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。