全面学习C语言【六】:结构类型(enum枚举、struct结构、union联合)

十二、结构类型

🎈enum / 枚举

在定义几个独立的const常量时 可以使用枚举
枚举是一种用户定义的数据类型 关键字是enum 用于以更方便的方式定义多个可以排列的名字

语法:enum 枚举类型的名字 {名字1,名字2 ... 名字n};

比如:

const int ONEVALUE=0;
const int TWOVALUE=1;
const int THREEVALUE=2;

可以改为:

enum MYVALUE {ONE,TWO,THREE};
// 在这里ONE默认就是0 TWO默认就是1 THREE默认就是2

枚举类型的名字并不经常使用 而是直接使用大括号内定义的名字
这些名字它们就是常量符号 类型为int 值依次从0至n递增

枚举的意义 就是给一些排列的常量起名字
比如 enum MYVALUE{ONE,TWO,THREE} 的意思就是声明一种数据类型名为MYVALUE
可以将其当作一种数据类型来使用 但使用时必须带上enum关键字
比如void f(enum MYVALUE m)enum MYVALUE m=TWO
由于其本质就是int 因此可以作为int来输入输出(%d)

用的时候 可以在最后加上一个计数器 用于表示枚举量共有多少:

enum MYVALUE{ONE,TWO,THREE,countVALUE}

在声明枚举量的时候 还可以指定值:

enum MYVALUE{ONE=2,TWO,THREE=6}
// 此时ONE是2 TWO是3 THREE是6 没有4和5了

然而 枚举实际上很少用…

🎈struct / 结构

若需要同时表达多个数据 或 表达出一个整体(比如一个人有姓名性别年龄之类的)
此时 需要用到结构
结构就是复合的数据类型 在其中可以有很多各种类型的成员 用一个变量来表示这些数据
(结构其实就像Java中的封装思想 将多个属性封装成了一个类)

简单例子:

#include <stdio.h>

// 声明一个类型为student的结构 里面有name属性和age属性
struct student
{
	char* name;
	int age;
};

int main(int argc,char const *argv[])
{
	struct student student1;
	
	student1.name="陈涛";
	student1.age=18;
	
	printf("%s\n",student1.name);
	printf("%i\n",student1.age);
	
	return 0;
}

和本地变量一样 在函数内部声明的结构类型只能在函数内部使用
因此 通常是在函数外部声明结构类型 这样即可被多个函数使用了

声明结构变量(在Java中是创建对象)的时候 前面要加上struct关键字 代表这是一个结构而不是自带的类型

struct dog
{
	char* name;
	int age;
}
struct dog dog1,dog2;

还有另一种方法来声明无名结构 (有点类似于JS的匿名函数…)
只是想要两个变量 而不关注其名字

struct
{
	char* name;
	int age;
} dog1,dog2;

还可以既声明结构名字又声明结构变量

struct dog
{
	char* name;
	int age;
} dog1,dog2;
🚩结构初始化

直接用花括号来赋初始值
会按花括号内的值的顺序来依次赋值

struct student student1={"陈涛",18};
	
printf("%s\n",student1.name); // 陈涛
printf("%i\n",student1.age); // 18

还可以给具体的值赋值:
在属性值前面加上一个点.即可
若未给整数赋值 则自动为0
若为给字符串复制 则自动为NULL

#include <stdio.h>

struct student
{
	char* name;
	int age;
};

int main(int argc,char const *argv[])
{
	struct student student1={.age=18};
	
	printf("name = %s\n",student1.name); // name = (null)
	printf("age = %i\n",student1.age); // age = 18
	
	return 0;
}
🚩结构运算

可以对整个结构赋值地址 也可以传递给函数作为参数
比如:

struct dog
{
	char* name;
	int age;
};

int main(int argc,char const *argv[])
{
	struct dog d1,d2;
	d1=(struct dog){"汪汪",2}; // 强制类型转换
	d1.age=3;
	
	d2=d1;
}
🚩结构指针

和数组不同 结构变量的名字并不是结构变量的地址
因此 若要取结构变量的地址 必须使用&运算符

struct dog
{
	char* name;
	int age;
};

int main(int argc,char const *argv[])
{
	struct student student1;
	
	struct student *pStudent=&student1;
	printf("%p",&pStudent); // 0061FEC4
}
🚩结构与函数

结构可以传给函数作参数

int calcDog(struct dog d);

当作为函数的参数传入的时候 此时是在函数内新建了一个相同类型的结构变量 然后复制传入的结构的值

函数也可以返回一个结构作为返回值

#include <stdio.h>

struct student
{
	char name;
	int age;
};

struct student getStruct(void);

int main(int argc,char const *argv[])
{
	struct student s1;
	s1=getStruct();
	
	printf("%s\n",&s1.name);
	printf("%d\n",s1.age);
	
	return 0;
}

struct student getStruct(void)
{
	struct student s;
	scanf("%s",&s.name);
	scanf("%d",&s.age);
	
	return s;
}
🚩指向结构的指针 -> 箭头符号

通常是传递结构的指针 而不是直接传递结构进函数
因为传递结构是拷贝的过程 在函数内创建新的一模一样的结构是比较耗费空间和时间的

在C中 可以使用(*p).xxx来表示结构指针中的某个成员

当然 还有更好的方法 那就是箭头符号
->箭头符号 (arrow) 来表示指针所指的结构变量中的成员

#include <stdio.h>

struct student
{
	char *name;
	int age;
} s1;

int main(int argc,char const *argv[])
{
	struct student *p=&s1;
	
	(*p).name="张涛";
	printf("%s\n",(*p).name); // 张涛
	
	// 箭头符号
	p->age=22;
	printf("%d",p->age); // 22
	
	return 0;
}
🚩结构数组

结构可以定义成数组的形式:

struct student students[3];

也可以赋初始值:

#include <stdio.h>

struct student
{
	char *name;
	int age;
};

int main(int argc,char const *argv[])
{
	struct student students[]={
		{"陈涛",18},
		{"张涛",22},
		{"王涛",16}
	};
	
	printf("%s",students[1].name); // 张涛
	
	return 0;
}
🚩结构中的结构

在结构可以 不仅可以有基础类型 还可以有结构
但是被包括的结构 必须定义在用到该结构的结构上面

比如:

#include <stdio.h>

struct dog
{
	char *name;
	int age;
};

struct student
{
	char *name;
	int age;
	struct dog dog;
};

int main(int argc,char const *argv[])
{
	struct dog d={"汪汪",2};
	struct student s={"陈涛",18,d};
	
	printf("%s",s.dog.name); // 汪汪 
	
	return 0;
}
自定义数据类型 / typedef

在C中 提供了typedef声明一个已有的数据类型的新名字

格式

typedef 旧类型名 新类型名

比如:

typedef int Myint; // 使得Myint成为int的别名typedef *char[10] strings; // 使得strings成为*char[10]的别名

这样 即可使用新名字来定义或参数声明了

Myint a,b;
Myint numbers[10];

这样 可以使自定义的结构也改为一个新名字 这样就无需每次使用结构都在前面加上struct关键字了

typedef struct student
{
	char *name;
	int age;
} Mystudent;

Mystudent s={"陈涛",18,d};

也可以不提供结构的名字:

typedef struct
{
	char *name;
	int age;
} Mystudent;

Mystudent s={"陈涛",18,d};

🎈union / 联合

使用union关键字来定义一个联合

union student
{
	char c;
	int i;
};

只不过和结构的区别是 联合里面的每一个成员都使用同一个内存空间 而不是分开的
同一时间只有一个成员是有效的 且union的大小是其最大的成员

联合通常的用处是得到整数内部的各个字节
可以利用union的这种共用的特性 作为文件读写的中间媒介


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值