结构体
简单的定义结构体的方法
struct student
{
char name;
int age;
float score;
};
//使用student模板创建两个结构体变量
struct student Jack,Rose;
结构体中可以存放除了函数以外的任何数据类型的数据,在创建结构体时student被称为结构体模板名称,在c语言中设计者们想让我们使用结构体就跟使用普通变量无差别,因此结构体可以执行普通变量的所有操作,在此做一个示例
#include <stdio.h>
#include <string.h>
struct student
{
char name[25];
int age;
float score;
};
void show (struct student *p);
int main(int argc, char const *argv[])
{
//定义一个结构体,后续赋值
struct student Jack;
strcpy(Jack.name , "Jack");
Jack.age = 18;
Jack.score = 80;
//定义结构体并对其中所有目标进行初始化
struct student Rose = {"Rose" , 17 ,90};
//定义结构体并对指定目标进行初始化
struct student Machel = {
.name = "Machel",
.age = 19
};
//定义Junior结构体将Machel结构体中的值赋予它
struct student Junior;
Junior = Machel;
//定义一个长度为50类型为student结构体的数组
struct student My_Class[50];
My_Class[0] = Jack;
My_Class[1] = Rose;
My_Class[2] = Machel;
My_Class[3] = Junior;
//定义一个结构体指针p,指向Machel结构体
struct student *p = &Machel;
//对于结构体指针来说可以使用箭头指定成员
p -> score = 93;
show(&Machel);
return 0;
}
void show (struct student *p)
{
printf("name: %s ,age: %d ,score: %f \n",p->name,p->age,p->score);
}
上面的例子几乎将结构体的所有操作进行了一遍,因为结构体一般来说比较大,因此我们一般在函数调用结构体时传入地址以提高效率
在单片机的内存中数据都是会根据大小对齐存放的,在32位系统中,cpu每次最少存取4个字节,以一个double型变量为例,其占8字节内存,在未对齐的情况下cpu可能需要三次存取才能将其完全取出,但是在对齐后只需要两次就可以取出,减少资源的浪费
int型数据的地址必须至少是4的整数倍,简单来讲int型数据的m值为4,这个m值就是对变量地址的要求,再结合上面的例子我们可以总结出这样的规律:
1.如果变量尺寸小于4字节,则其m值就等于变量的长度
2.如果变量的尺寸大于等于4字节则一律按照4字节进行对齐
3.如果变量的m值被手动调节过则按照调节后的为主
强调一点:一个变量的m值规定了这个变量的地址的最小倍数,同时也规定了这个变量的大小至少是这个m值的倍数。m值不是这个变量的大小。结构体本身也是一个变量,结构体变量的m值取决于其成员中m值最大的那个。以下面的结构体为例
struct node
{
short a;
char b;
double c;
}x;
ma = 2,mb = 1,mc = 4,此时结构体的m值就为4,再根据m值就可以得知结构体具体占据多少内存
共同体(联合体)
共同体的定义方式跟结构体很像,但其与结构体有根本区别,在共同体中不同的数据是共用起始地址的
union example
{
int a;
char b;
double c;
}x;
共用体的这种特性,使得他适合用来表达一些互斥的概念,比如一件衣服的颜色属性,要不就是红要不就是白,不可能既红又白。一个进程的状态,要不就是运行要不就是睡眠,不可能既运行又睡眠。像这样的情况,就可以考虑将他们放在一个共用体里面,既节省了空间,又使得互斥的特征更加明朗。
枚举
在c语言中枚举类型的作用并不大,本身枚举的类型应该是指定范围的,但是c语言中枚举类型纯粹就是整形,可以赋予任何值因此作用不大
不管如何,给出一个示例
#include <stdio.h>
//定义了一个枚举常量列表
enum spectrum {red, green, blue};
int main(void)
{
enum spectrum color; // 定义一个枚举变量
color green;
switch(color) {
case red://使用枚举常量断 color的值
printf("red\n");
break;
case green:
printf("green\n");
break;
case blue:
printf("blue\n");
break;
default:
printf("unknown color\n");
}
return 0;
}
在第4行代码中定义枚举常量是未进行初始化,因此其中数据为缺省的,会从0开始递增,所以其中几个成员的数值为0,1,2
spectrum是这个枚举常量的列表的标签,我们可以使用这个标签来定义所谓枚举变量color,之后我们就可以使用color来获取spectrum列表中常量的值