C语言--结构体和枚举

                             C语言--结构体和枚举

* 在前面我们已经介绍了C语言中的数组,用法跟其他语言差不多。当一个整体由多个数据构成时,我们可以用数组来表示这个整体,但是数组有个特点:内部的每一个元素都必须是相同类型的数据。
* 在实际应用中,我们通常需要由不同类型的数据来构成一个整体,比如学生这个整体可以由姓名、年龄、身高等数据构成,这些数据都具有不同的类型,姓名可以是字符串类型,年龄可以是整型,身高可以是浮点型。
* 为此,C语言专门提供了一种构造类型来解决上述问题,这就是结构体,它允许内部的元素是不同类型的

一、数组和结构体的对比

数组:只能有多个同一类型的数据构成

结构体:可以有多个不同类型的数据构成

1>、结构体定义格式:

struct 结构体名{
     
     类型名1 成员名1;
     
     类型名2 成员名2;
     
     ……
     
     类型名n 成员名n;   
     
 };
struct是关键字,是结构体类型的标志

通过结构体例子,看一下定义

#include<stdio.h>
int main()
{
//1.定义结构体类型 (并不分配存储空间)   格式:struct 类型 {};
	struct Person
	{ //里面的3个变量可以说是结构体的成员或属性
	int age;
	char *name;//char name[10];
	double height;
	};
//2.根据结构体类型,定义结构体变量,并赋值(分配存储空间  大小为最大成员字节的倍数(补齐算法)))
     //	struct Person p ={21,"Jack",1.78};
	//struct Person p2 = {.age = 34, .name = "lonsv", .height = 1.65};
    struct Person p3;
	p3.age = 25;
	p3.name = "tom";
	p3.height = 1.87;

	/*这是一种错误的格式
	srtuct Person p4;
     p4 = {21,"alice",1.75};
	结构体赋值方式和数组相似,只能在初始化时进行赋值
	
	*/

p3.age = 23;//对初始值进行修改
p3.name = "rose";//对初始值进行修改
printf("age = %d,name = %s,height = %f\n", p3.age, p3.name, p3.height);
return 0;
}

二、下面看一下结构体内存的分配情况:
#include <stdio.h>
int main()
{
struct Date
{
	int year;
        int month;
	int day;
};
//执行完后如图1
struct Date d1= {2011,4,10};struct Date d2= {2012,12,9};
//执行完后如图2
d2 = d1;
//只会对d2修改,对d1没任何影响
d2.year = 1998;
printf("%d-%d--%d\n",d1.year, d1.month, d1.day);
}


 
 
 

                                                             图 1

                                                            图 2

三、结构体定义的3种形式:

定义结构体变量的3中形式:

1>先定义类型,在定义变量(分开定义)

struct Student
{
	int age;
        int name;
};
struct Student stu;

2>定义类型的同时定义变量

struct Student
{
	int age;
        int name;
} stu;

3>定义类型的同时定义变量 (省略类型名称)

struct 
{
	int age;
        int name;
} stu;

具体实例如下:

#include <stdio.h>
int main()
{
/*第一种形式
struct Student
{
	int age;
        int name;
};
struct Student stu;
struct Student stu2;

*/
/*第二种形式:定义类型的同时定义变量
这句代码做了两件事:
1.定义结构体类型
2.利用新定义好的类型来定义结构体变量
struct Student
{
	int age;
        int name;
} stu;
struct Student stu2;
*/
/*第三种形式:缺点不能重用
//这个可以这样用,因为不存在结构体名称,不存在重复定义
struct 
{
	int age;
        int name;
} stu;
struct 
{
	int age;
        int name;
} stu2;

*/
/*这是一种错误的定义,类型重复定义
struct Student
{
	int age;
        int name;
};
struct Date d1= {2011,4,10};
struct Student
{
	int age;
        int name;
};
struct Date d1= {2011,4,10};
*/
}

四、结构体的初始化

将各成员的初值,按顺序地放在一对大括号{}中,并用逗号分隔,一一对应赋值。
比如初始化Student结构体变量stu

struct Student {
     char *name;
     int age;
 };
 
 struct Student stu = {"MJ", 27};
只能在定义变量的同时进行初始化赋值,初始化赋值和变量的定义不能分开,下面的做法是错误的:

struct Student stu;
stu = {"MJ", 27};

五、结构体的作用域:

从定义类型的那一行开始,一直到代码块结束

void test()
{
//这时运行会报错,因为此时Date该没有被定义,不能使用
struct Date d1;
}
struct Date
{
    int year;
    int day
};
int main()
{
return 0;
}
那么为了让结构体在全局都能用,应该把结构体定义在代码行最前端(类似于全局变量),注意:再调用结构体时,会现在本块内部进行查找,如果内部能满足,则不调用外部的

<pre name="code" class="cpp">struct Date
{
    int year;
    int day
};
void test()
{
struct Date d1;
}
int main()
{<pre name="code" class="cpp">struct Date
{
    int year;
};
struct Date d;//这时调用的是main方法内部的结构体Date,所以他的类型只有一个int
return 0;
}
 

六、结构体数组:对多个类型输出

例如这个排名

应该采用结构体数组:格式 :类型  名称[];(类似于普通数组 int a[];),下面是一个例子:

//结构体数组
#include <stdio.h>
struct Record
{
    int no;//排名
    char *name;//名称
	int record;//分值
};
int main()
{
	int i;
	//定义结构体数组并赋初始值
	struct Record r[3] = 
	{{1, "jack", 5000},{2, "Jim" ,500},{3, "jake", 300}};
    //aaaaa r[0].record = 3000;//对数组值进行修改
	for ( i = 0; i < 3; i++)//通过遍历对数组进行输出
	printf("%d\t%s\t%d\t\n",r[i].no, r[i].name, r[i].record);
}
输出结果如图:

七、指向结构体的指针

1.格式:struct 结构体类型 *p;     (类似于int *p)

    p = &结构体名称;

2.利用指针访问结构体成员

   1>. (*p).成员名称

   2>. p->成员名称

  3> 结构体变量名.成员名称

具体实例如下:

int main()
{
    struct Student
	{
		char *name;
     	int age;
	};
	//结构体变量
	struct Student stu = {"star", 21};
	//指针变量p将来指向 struct Student 类型的数据
	 struct Student *p;
	 //指针变量p指向stu变量的地址
	 p = &stu;
	 p->age = 23;//对结构体的属性值进行修改
//	 printf("姓名:%s\t年龄:%d\n",stu.name, stu.age);第一种
//	 printf("姓名:%s\t年龄:%d\n",(*p).name, (*p).age);第二种
	 //第三种,也是最常用的一种
	 printf("姓名:%s\t年龄:%d\n",p->name, p->age);
}
八、结构体的嵌套

struct 大结构体名称{  struct 小结构体名称 大结构体属性 };

#include <stdio.h>
//结构体的嵌套
struct Date 
{
int year;
int month;
int day;
};
int main()
{
struct Student
{
int no;//学号
struct Date birthday;//出生日期
struct Date ruxueDate;//入学日期
//struct Student stu;//这是错误的,结构体不能包含自己
};
//赋值时结构体要用大括号括起来
struct Student stu = {3012, {1992, 5, 21}, {2013, 9, 10}};
//访问时是通过,大结构体名称.大结构体属性.小结构体属性
printf("生日是:%d-- %d-- %d\n",stu.birthday.year, stu.birthday.month, stu.birthday.day);
}

九、枚举:当变量有几个固定的取值时用枚举

枚举是C语言中的一种基本数据类型,并不是构造类型,它可以用于声明一组常数。当一个变量有几个固定的可能取值时,可以将这个变量定义为枚举类型。比如,你可以用一个枚举类型的变量来表示季节,因为季节只有4种可能的取值:春天、夏天、秋天、冬天

枚举类型定义:enum 枚举名称{a,b,c};注意:中间是逗号” ,“ 不是分号“ ;” 
调用时:enum 枚举名称 变量 = 枚举内容;

枚举类型是默认顺序,从0开始依次累加,也可以自定义开始序号

#include <stdio.h>
int main()
{
//枚举类型定义:enum 枚举名称{a,b,c};
enum Season
{
 spring,
 summer,
 autumn,
 winter
};
//调用时:enum 枚举名称 变量 = 枚举内容;
enum Season s = spring;//枚举类型是默认顺序,从0开始依次累加,也可以自定义开始序号
printf("%d\n",s);
return 0;
}

有3种方式定义枚举变量

1.先定义枚举类型,再定义枚举变量

enum Season {spring, summer, autumn, winter};
enum Season s;
2.定义枚举类型的同时定义枚举变量
enum Season {spring, summer, autumn, winter} s;
3.省略枚举名称,直接定义枚举变量

enum {spring, summer, autumn, winter} s;
枚举变量的基本操作

赋值:可以给枚举变量赋枚举常量或者整型值

enum Season {spring, summer, autumn, winter} s;

s = spring; // 等价于 s = 0;

s = 3; // 等价于 s = winter;
2.遍历枚举元素
enum Season {spring, summer, autumn, winter} s;

// 遍历枚举元素
for (s = spring; s <= winter; s++) {
    printf("枚举元素:%d \n", s);
}
输出结果:



 
 






  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿三先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值