1.数据类型分类
- 基本类型
- 整数型
短整型:shot(两个字节)
整型:int(四个字节)
长整型:long(八个字节)
长长整型:longlong - 浮点型
单精度:float(四个字节)
双精度 :double(八个字节) - 字符型:char (一个字节)
- 指针类型
数据类型*:int*,char*,float*等
void*:任意数据类型指针 - 空类型
void:没有返回值或没有形参(不能定义变量) - 自定义类型/构造类型
结构体类型:struct
共用体类型(联合体):union
枚举类型:enum
注意:整数型和字符型分有符号signed和无符号unsigned,默认是有符号的,有符号可以省略关键字signed
2.结构体
1.结构体的定义
- 定义:自定义数据类型的一种,关键字struct,结构体类型的变量可以存储多个不同数据类型的数据。
- 定义格式:
struct 结构体名 { 数据类型1 成员名称1; 数据类型2 成员名称2; 数据类型3 成员名称3; ...... }
注意:结构体中定义的变量,我们称之为成员变量。
-
格式说明:
-
结构体名:合法的标识符,建议单词的首字母大写
-
数据类型:C语言支持的所有类型
-
成员名称:合法的标识符,就是变量的命名标准
-
数据类型n 成员名称n:类似于定义变量,定义了结构体中的成员
-
-
注意:
-
结构体在定义的时候,成员不能赋值
-
-
举例
struct Cat { int age = 5;//错误 double height;// 正确 }
-
常见的定义格式:
-
方式一:常规定义(只定义类型)——推荐
struct Student { int num;//学号 char name[20];//姓名 char sex;//性别 int age;//年龄 char address[100];//家庭住址 }
- 方式二:定义匿名结构体(常用于其他结构体的成员使用)
struct Dog { char *name;//姓名 int age;//年龄 struct// 此时这个结构体是匿名的 { int year;//年 int month;//月 int day;//日 }brithday; }
-
注意:定义匿名结构体的同时必须定义结构体变量,否则编译报错,结构体可以作为另一个结构体的成员。
总结:
- 结构体可以定义在局部位置,也可以定义在全局变量;
- 全局位置的结构体名和局部位置的结构体可以相同,就近原则(和普通变量同理)
- 结构体类型的使用:
利用结构体类型定义变量,定义数组;结构体类型的使用与基本数据类型的使用类似。
2.定义结构体变量的定义
- 三种形式定义结构体变量:
结构体变量也称为结构体的实力。
- 第一种
- 先定义结构体
- 然后使用struct 结构体名 变量名;
//先定义结构体(先定义结构体这个数据类型) struct A { int a; char b; }; //定义结构体变量 struct A x; struct A y;
-
常见的定义格式:
-
第二种
-
在定义匿名结构体的同时,定义结构体变量
//定义结构体的同时定义结构变量 struct A { int a; char b; }x,y; struct A z;
此时定义了一个结构体A,x和y是这个结构体类型的变量。
-
-
第三种:不推荐
-
在定义匿名结构体的同时,定义结构体变量:
struct { int a; char b; }x,y; struct { int a; char b; } z;
此时定义了一个没有名字的结构体(称为匿名结构体);x,y是这个匿名结构体类型的变量:
-
-
匿名结构体:.......弊大于利(尽量少用)
-
优点:少写一个结构体名称
-
缺点:只能使用一次:定义的结构体类型的同时就必须定义变量
-
应用场景:
-
当结构体的类型只需要使用一次,并且定义类型的同时定义变量。
-
作为其他结构体的成员使用
-
-
-
定义结构体的同时,定义结构体的变量初始化
struct Cat { int age; char color[20]; }cat;
-
结构体成员部分的初始化时,大括号不能省略。
-
如果赋值没有歧义,编译和运行就没有问题
-
如果赋值推导有歧义,编译就会报错
-
结构体的成员,没有默认值,是不确定的数
-
案例:
/** * 结构体变量的定义 */ #include <stdio.h> // 先定义结构体,再定义结构体变量 void fun1() { // 先定义结构体 struct A { int a; char b; }; // 再定义结构体变量 struct A x; struct A y; } // 定义结构体的同时定义结构体变量 void fun2() { struct A { int a; char b; } x,y; struct A z; } // 定义匿名结构体的同时定义结构体变量 void fun3() { struct { int a; char b; } x,y; struct { int a; char b; } z; } int main() { fun1(); fun2(); fun3(); return 0; }
-
3.结构体的使用
- 结构体变量访问结构体成员
- 格式:
结构体变量名.成员名
可以通过访问给成员赋值(存数据)
可以通过访问获取成员的值(取数据) - 结构体变量未初始化,结构体的成员值随机(不确定)
- 格式:
- 结构体变量在定义时,可以初始化
- 建议用大括号表明数据的范围
- 结构体成员初始化时,可以部分初始化,部分初始化时一定压迫带大括号标明数据范围
- 案例:
/** * 结构体变量的初始化 */ #include <stdio.h> /* 全局的结构体(数据类型) */ struct Dog { char *name;// 姓名 int age;// 年龄 char sex;// M:公,W:母 }; /* 先定义,再初始化 */ void fun1() { // 定义一个结构体 // struct Dog // { // char *name;// 姓名 // int age;// 年龄 // char sex;// M:公,W:母 // }; // 定义结构体变量 struct Dog dog; // 给结构体变量的成员赋值 dog.name = "旺财"; dog.age = 5; // 访问结构体变量的成员 printf("%s,%d,%c\n",dog.name,dog.age,dog.sex); } /* 定义的同时初始化 */ void fun2() { // 定义结构体变量并初始化 struct Dog dog = {"招财",23,'M'}; // 修改成员的值 dog.name = "进宝"; // 访问结构体变量的成员 printf("%s,%d,%c\n",dog.name,dog.age,dog.sex); } int main() { fun1(); fun2(); return 0; }
结构体数组的定义
- 什么时候需要结构体数组?
- 比如我们需要管理一个学生对象,只需要定义一个struct Student majie;
- 假如:我们管理多个学生对象,此时就需要一个结构体的数组 struct Student student[64];。
- 三种形式定义结构体数组
- 第一种:先定义结构体类型,然后定义结构体变量,再将变量存储到结构体数组中
// 定义一个学生类型的结构体 struct Student { char *name; int age; float scores[3];// 三门课程的成绩 }; // 定义一个学生类型的结构体 struct Student { char *name; int age; float scores[3];// 三门课程的成绩 };
- 第二种:定义结构体类型,然后定义结构体数组初始化
// 定义一个学生类型的结构体 struct Student { int id; char *name; int age; float scores[3];// 三门课程的成绩 }; // 定义结构体数组并初始化 struct Student students[3] = { {1,"张三",23,{67.5,89.0,90.0}},// 注意:这里赋值的顺序需要跟成员在结构体中的顺序一致 {2,"李四",21,{77.0,80.0,85.0}} };
- 第三种:定义结构体类型同时定义结构体数组并初始化
// 定义一个学生类型的结构体 struct Student { int id; char *name; int age; float scores[3];// 三门课程的成绩 } students[3] = { {1,"张三",23,{67.5,89.0,90.0}},// 注意:这里赋值的顺序需要跟成员在结构体中的顺序一致 {2,"李四",21,{77.0,80.0,85.0}} };
- 第四种:定义结构体类型同时定义结构提数组,然后通过索引给结构体成员赋值
// 定义一个学生类型的结构体 struct Student { int id; char *name; int age; float scores[3];// 三门课程的成绩 } sts[3]; sts[0].id = 1; sts[0].name = "张三"; sts[0].age = 12; sts[0].scores[0] = 98;
- 第一种:先定义结构体类型,然后定义结构体变量,再将变量存储到结构体数组中
- 小贴士:
结构提数组名访问结构体成员:
格式:结构体数组名->成员名