1.typedef关键字
typedef的功能是 给类型起别名
//使用别名和原名都可以定义变量
为什么类型有名字,还要起别名?
1.有些类型名字比较长,且有多个单词组成,用着比较麻烦
如:unsigned long long int a;
此时就可以给他起个别名 typedef unsigned long long int ulli;
以后使用 ulli a; 就和 unsigned long long int a; 是等价的了
2.我们后面要学习的枚举、结构体、共用体等定义变量时都需要用两个单词
使用别名可以简化成一个单词。
2.enum枚举关键字
枚举是一个基本类型,枚举是数据的有限罗列。
枚举是用来防止“魔鬼数字”的。
所谓的魔鬼数字,就是通过数字本身无法表达含义的数字,代码中出现,会影响阅读。
(1)定义枚举类型的格式
enum 枚举类型名{
成员1,
成员2,
...
成员n
};
注意:
1.enum和枚举类型名共同构成了一个类型,定义变量时:
enum 枚举类型名 枚举变量名;
2.枚举的成员之间用 逗号 分隔
3.如果成员1没有初始值,默认值是0
4.枚举成员的值是依次递增1的
5.如果某个成员被赋了初值,那么后面的成员,在该值的基础上依次递增1
6.枚举类型的大小,取决于枚举成员中的最大值,如果没有成员超过4字节
那么枚举变量的大小就是4字节,有成员超过4字节时,那么枚举变量的大小就是8字节
----一般情况下,我们认为枚举变量默认是4字节的。
7.枚举定义好之后,成员就都是常量了。
8.如果枚举成员名和局部变量名冲突了,采用局部优先原则
3.struct结构体
结构体是一个构造类型,结构体里面既可以是相同数据类型的集合
也可以是不同数据类型的集合。
一般情况下,结构体多用来管理不同类型的数据。
(1)定义结构体类型的格式
struct 结构体类型名{
数据类型1 成员1;
数据类型2 成员2;
...
数据类型n 成员n;
};
注意:
1.结构体的用法和枚举类似,但是又略有不同
2.结构体的成员之间用 分号 分隔
3.结构体的成员都是变量
4.结构体的成员在内存上是连续的(涉及到内存对齐的问题)
5.结构体变量之间可以直接相互赋值
(2)定义结构体变量
struct 结构体类型名 结构体变量名; //定义结构体变量
struct 结构体类型名 *结构体指针名; //定义结构体指针
例子:
struct Test{
int m;
char n;
};
变量版: 变量名.成员名
struct Test t1;
t1.m = 10;
t1.n = 'H';
变量版: 指针名->成员名
struct Test *p1;
p1 = &t1;
p1->m = 20;
p1->n = 'Q';
struct Test *p2 = (struct Test *)malloc(sizeof(struct Test));
p2->m = 1234;
p2->n = 'Y';
综合例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义结构体类型
struct Student{
int id;
char name[32];
int score;
};
int main(int argc, const char *argv[])
{
//定义结构体便量
struct Student s1;
//结构体变量访问成员
s1.id = 1001;
strcpy(s1.name, "zhangsan");
s1.score = 98;
printf("%d %s %d\n", s1.id, s1.name, s1.score);//1001 zhangsan 98
//每个结构体变量都有自己的成员 是独立的
struct Student s2;
s2.id = 1002;
strcpy(s2.name, "lisi");
s2.score = 100;
printf("%d %s %d\n", s2.id, s2.name, s2.score);//1002 lisi 100
//定义结构体指针
struct Student *p1 = &s2;
//结构体指针访问成员
printf("%d %s %d\n", p1->id, p1->name, p1->score);//1002 lisi 100
struct Student *p2 = (struct Student *)malloc(sizeof(struct Student));
if(NULL == p2){
printf("内存分配失败\n");
return -1;
}
p2->id = 1003;
strcpy(p2->name, "wangwu");
p2->score = 60;
printf("%d %s %d\n", p2->id, p2->name, p2->score);//1003 wangwu 60
free(p2);
p2 = NULL;
return 0;
}
4.union共用体
1.定义共用体类型和使用共用体定义变量的方式,都和结构体一样,
只不过把关键字 struct 换成 union 即可。
2.共用体的成员共用同一块内存空间
3.共用体的成员首地址是一样的
4.共用体的大小取决于成员的最大值
union 共用体类型名{
数据类型1 成员1;
数据类型2 成员2;
...
数据类型n 成员n;
};
#include <stdio.h>
#include <string.h>
union Test{
char a;
short b;
int c;
};
int main(int argc, const char *argv[])
{
union Test t;
memset(&t, 0, sizeof(t));
//共用体的成员共用同一块内存空间
//使用时一般不会同时使用两个成员 因为给一个成员
//其他成员也会随之发生变化
t.a = 10;
printf("t.c = %d\n", t.c);//10
printf("t.b = %d\n", t.b);//10
//验证共用同一块内存空间--一样的
printf("&t.a = %p\n", &t.a);
printf("&t.b = %p\n", &t.b);
printf("&t.c = %p\n", &t.c);
return 0;
}