[C语言]菜鸟的一些理解-结构体,共用体,枚举,位域

结构体

时间真快!!假期就要过去了。这是我最难过的一个国庆,

感谢时间快,又不希望它过得这么快。

前面学的数组,一旦定义了就只能存储定义的数据类型的数据了。

但是我们现实中每组数据不一定是由同一种数据类型组成。

比如:一个人的信息是由  姓名 年龄 职业 等组成。

这就不可能用数组的存储了。

C语言中提供了一种类型,结构体来解决这类问题,结构体可以将不同的数据类型封装在一起。我们再对其进行引用。我们可以根据实际情况来构造不同的类型。

简单的来理解:结构体就是我们自己定义的一个可以存储不同数据类型的数组。

声明结构体类型,其声明如下:

要用到  struct 这个关键字

struct  结构体名

{

数据类型结构体成员1

数据类型结构体成员2

};注意:这个分号省略。

定义结构体变量。

声明了结构体类型后,便可以使用该类型来定义结构体变量。

定义结构体变量有三种方式:

① 声明结构体类型后,再定义结构体变量。

struct 结构体名

{

数据类型结构体成员1

数据类型结构体成员2

}

struct 结构体名 变量名1,变量名2

注意:struct 不可省略。

②不声明结构体类型,直接定义结构体变量。

struct 

{

数据类型结构体成员1

数据类型结构体成员2

}变量名1,变量名2

③ 使用typedef 得到简化的结构体类型名,再定义结构体变量

由于结构体数据类型的名字由标识符合结构体名两部分组成,书写起来名字较长,因此,常常使用 typedef 来简化。其用法如下:

typedef struct 结构体名

{
数据类型结构体成员1

数据类型结构体成员2

数据类型结构体成员n

}stru

就可以通过stru来定义结构体变量了。

stru s1s2

结构体变量的初始化和赋值

代码如下

struct s

{

char str[100];

int i;

};

struct s s1 = {“Hello”,8};

也可以单独赋值

strcpy(str,”Hello”);//这里为什么要这样赋值呢?我也没有搞懂。

s1.i = 8;

访问结构体成员

访问结构体成员要用到成员操作符( )就是一点。成员操作是二元操作符,操作符前面的是结构体变量,后面是结果体成员。

1.

#include <stdio.h>
#include <string.h>

typedef struct student
{
	char name[100];//姓名
	int age;//年龄
}Stu;
	
int main(void)
{

	Stu s1 = {"小明",22};
	Stu s2 = s1;//结构体变量之间可以相互辅助。当然要同一个结构体类型。
	Stu s3; 
	
	printf("s1.name = %s
",s1.name);
	printf("s1.age = %d
",s1.age);
	
	printf("s2.name = %s
",s2.name);
	printf("s2.age = %d
",s2.age);
	
	strcpy(s3.name,"小敏");
	s3.age = 20;
	
	printf("s3.name = %s
",s3.name);
	printf("s3.age = %d
",s3.age); 
	
	return 0;
}


结构体数组

定义结构体数组

其定义方式跟定义结构体变量一样,有三种方式,只不过定义数组要加[]

结构体数组的初始化和赋值

2

#include <stdio.h>
#include <stdlib.h>

	typedef struct student
	{
		char name[100];//姓名
		int age;//年龄
		char gender;//性别
	}Stu;
	
int main(void)
{
	int i = 0;
	Stu st[4] = {{"raul",22,'M'},
		{"joe",23,'W'},
		{"philip",21,'M'},
		{"alan",20,'M'}
	};
	
	/*其数组容量可以大不可小。超过的容量没有赋值,编译器会自动初始化为0
	  也可不写,编译器会根据元素的个数来决定。*/
 	printf("姓名	年龄	性别
"); 
 	for(i = 0;i < 4; ++i)
 		printf("%s	%d	%c
",st[i].name,st[i].age,st[i].gender);
 		
	return 0;
}

结果:

姓名    年龄    性别

raul     22      M

joe      23      W

philip   21      M

alan     20      M

指向堆空间的结构体指针

3

#include <stdio.h>
#include <stdlib.h>

typedef struct 
{
	char name[100];
	int age;
	char gender;
}Stu;

int main(void)
{
	Stu *p = NULL;
	p = (Stu *) malloc ( sizeof(Stu) );
	if(NULL == p)
	{
		printf("
");
		exit(1);
	}
	
	printf("请输入姓名:");
	gets(p->name);
	
	printf("请输入年龄和性别:");
	scanf("%d %c",&p->age,&p->gender); 
	
	printf("姓名	年龄	性别
");
	printf("%s	%d	%c
",p->name,p->age,p->gender);
	return 0;
}

指向结构体数组元素的指针

4

#include <stdio.h>
#include <stdlib.h>

typedef struct 
{
	char name[200];
	int age;
	char gender;
}Stu;

int main(void)
{
	Stu st[4]={{"raul",22,'M'},
	{"joe",23,'W'},
	{"philip",21,'M'},
	{"alan",20,'M'}
	};
	Stu *p = st;
	
	for(p = st;p < st + 4;++p)
	{
		printf("%s	",p->name);
		printf("%d	",p->age);
		printf("%c
",p->gender);
	}
	return 0;
}

 

注:指针变量名->成员名 编译时内部自动转化为 (*指针变量名).成员名。这是规定,没有为什么?

 

共用体

共用体(union)是C语言中的另一中高级数据结构,为什么叫共用体,因为共用体的几个不同类型的成员共享一块内存空间。

共用体类型的定义

union 共用体名

{

数据类型 成员名;

数据类型成员名1

..........................

};记住这里分号跟结构体一样不可省略。

定义共用体变量(有三种方式跟结构体一样)

第一种

union data(也可以省略共用体名)

{

int a;

char c;

}ut,ut1;

第二种

union data

{

int a;

char c;

};

union data ut;

第三种

typedef union data

{

int a;

char c;

}t_un;

t_un ut;

使用t_un来定义共用体变量

共用体成员的赋值

由于共用体实际上只有一个有效成员,因此,无法想结构体那样赋值,共用体只能为其赋一个值,如下

typedef union data

{

int a;

char c;

}t_un;

t_un tu = {1,’a’}//错误

t_un tu = {1};//正确

证明共用成员共享一块内存空间

#include <stdio.h>

typedef union data
{
	int x;
	char c;
	float f;
}ty_u;

int main(void)
{
	ty_u ud;
	ud.x = 1;
	printf("x=%d c=%c f=%f
",ud.x,ud.c,ud.f);
	
	ud.c = 'a';
	printf("x=%d c=%c f=%f
",ud.x,ud.c,ud.f);
	
	ud.f = 8.1;
	printf("x=%d c=%c f=%f
",ud.x,ud.c,ud.f);
	
	printf("输出共用体成员的地址:
");
	printf("x=%p
c=%p
f=%p
",&ud.x,&ud.c,&ud.f); 
	return 0;
}	

输入同一个内存空间。


枚举

使用枚举变量需要注意以下几点:

① 枚举成员值以此增加1

定义枚举类型时,可以对枚举成员显示赋值,其后的枚举成员同样在改值的基础上加1,如下:

enum en

{A = 1, B,C,D = 8,E,F};

由于A赋值为则后面是B = 2 C = 3  由于D赋值为E = 9,F = 10;

② 只能使用整型数值初始化

如下赋值是错误的

enum en

{A = 0.1,B,C,D,E,F};

建议整型以外的值,用const 定义  或define 

③ 不使用只有一个枚举成员的枚举类型。

没有必要这么麻烦吧,直接使用const 

位域

位域属于结构体,它允许在结构体内以位作为单位将其空间划分为多个区域,并将其分配给结构体的各个成员。在程序中可以通过操作位域的各个成员来操作其中的区域。利用位域可以使用较少的字节数来存储信息,其形式如下:

struct 结构体名

{

unsigned 位域成员名1:常量1

unsigned 位域成员名2:常量2

..................................................

/*定义其他结构体成员*/

数据类型 成员名;

........................

};

1.位域成员的类型只能为int 和 unsigned 

2.位域成员声明中最后的常量值指定了该区域所占的位数,且该数组不能大于其数据类型所   

  占的位数。

3.位域成员和结构体成员可以交叉定义

4.位域成员访问方式与结构体成员访问方式完全一样


原文地址:https://www.cnblogs.com/phisy/p/3363706.html