——Java培训、Android培训、iOS培训、.Net培训、期待与您交流!——
结构体
结构体是一种可以由不同类型的元素构成的数据类型,结构体内部的元素也就是组成部分,一般称为成员。
结构体的定义
结构体类型的定义
struct 结构体名
{
类型1 成员名1;
类型2 成员名2;
类型3 成员名3;
类型n 成员名n;
}
例:定义一个人(年龄/身高/姓名)
struct Person
{ // 里面的3个变量,可以称为是结构体的成员或者属性
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
结构体变量的定义
方法1:定义结构体类型的同时定义变量
struct Person
{
int age; // 年龄
double height; // 身高
char *name; // 姓名
} p;
方法2:先定义结构体类型,再定义变量
struct Person
{
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
struct Person p;
方法3:直接定义结构体变量,忽略类型名
struct
{
int age; // 年龄
double height; // 身高
char *name; // 姓名
} p;
注意事项
1、结构体类型不能重复定义
//结构体类型不能重复定义
struct Student
{
int age;
};
struct Student
{
double height;
};
2、不允许对结构体本身递归定义
// 如下做法是错误的
struct Student {
int age;
struct Student stu;
};
3、结构体内可以包含别的结构体
struct Date {
int year;
int month;
int day;
};
struct Student {
char *name;
struct Date birthday;
};
4、内存分配
定义结构体类型,只是说明了该类型的组成情况,并没有给它分配存储空间;
只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量;
// 1.定义结构体类型(并不会分配存储空间)
struct Date
{
int year;
int month;
int day;
};
// 2.定义结构体变量(真正分配存储空间)
struct Date d1 = {2011, 4, 10};
struct Date d2 = {2012, 8, 9};
5、结构体变量占用的内存空间
补齐算法(对齐算法):结构体所占用的存储空间必须是最大成员字节数的倍数
struct Student
{
int age;// 4个字节
char *name; // 8个字节
};
struct Student stu;
int s = sizeof(stu);
printf("%d",s);
运行结果:
16
6、结构体类型的作用域
1> 定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾)
2> 定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代码块结束)
结构体的初始化
1、将各成员的初值,按顺序地放在一对大括号{}中,并用逗号分隔,一一对应赋值。
struct Person p = {20, 1.55, "jack"};
p.age = 30;
p.name = "rose";
printf("age=%d, name=%s, height=%f\n", p.age, p.name, p.height);
运行结果:
age=30, name=rose, height=1.550000
2、不按顺序赋值
struct Person p2 = {.height = 1.78, .name="jim", .age=30};
3、只能在定义变量的同时进行初始化赋值
// 错误写法
struct Person p2;
p2 = {30, 1.67, "jake"};
4、相同类型的结构体变量之间可以进行整体赋值
struct Student {
char *name;
int age;
};
struct Student stu1 = {"MJ", 27};
// 将stu1直接赋值给stu2
struct Student stu2 = stu1;
printf("age is %d", stu2.age);
运行结果:
age is 27
结构体数组
结构体数组的定义
例如定义一个变量名为p的结构体数组,数组元素个数是3
方法1:定义结构体类型的同时定义变量
struct Person
{
int age; // 年龄
double height; // 身高
char *name; // 姓名
} p[3];
方法2:先定义结构体类型,再定义变量
struct Person
{
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
struct Person p[3];
方法3:直接定义结构体变量,忽略类型名
struct
{
int age; // 年龄
double height; // 身高
char *name; // 姓名
} p[3];
结构体数组的初始化
1、将各成员的初值,按顺序地放在一对大括号{}中,并用逗号分隔,一一对应赋值。
struct Person p[3] =
{
{20,1.55,"jack"},
{21,1.60,"dave"},
{22,1.70,"jim"}
};
指向结构体的指针
1、结构体指针变量的定义方式
每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量
结构体指针变量的定义形式:struct 结构体名称 *指针变量名
2、访问结构体成员的方式
结构体变量名.成员名
(*指针变量名).成员名
指针变量名->成员名
结构体作为函数参数
如果结构体作为函数参数,只是将实参结构体所有成员的值对应地赋值给了形参结构体的所有成员
因此,修改函数内部结构体的成员不会影响外面的实参结构体
#include <stdio.h>
struct Student
{
int age;
int no;
};
// 不会影响外面的实参结构体
void test(struct Student s)
{
s.age = 30;
s.no = 2;
}
// 会影响外面的实参结构体
void test2(struct Student *p)
{
p->age = 15;
p->no = 2;
}
// 指针指向的内存地址发生变化,未影响实参
void test3(struct Student *p)
{
struct Student stu2 = {15, 2};
p = &stu2;
p->age = 16;
p->no = 3;
}
int main()
{
struct Student stu = {28, 1};
test(stu);
printf("age=%d, no=%d\n", stu.age, stu.no);
test2(&stu);
printf("age=%d, no=%d\n", stu.age, stu.no);
test3(&stu);
printf("age=%d, no=%d\n", stu.age, stu.no);
return 0;
}
运行结果:
age=28, no=1
age=15, no=2
age=15, no=2
枚举
枚举是C语言中的一种基本数据类型,并不是构造
类型,它可以用于声明一组常数。
当一个变量有几个固定的可能取值时,可以将这个变量定义为枚举类型。比如,你可以用一个枚举类型的变量来表示季节,因为季节只有4种可能的取值:春天、夏天、秋天、冬天。
枚举类型定义格式
一般形式为:enum 枚举名 {枚举元素1,枚举元素2,……};
例:四季
enum Season
{
spring = 1,
summer,
autumn,
winter
};
枚举变量的定义
有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;
枚举使用的注意
1> C语言编译器会将枚举元素(spring、summer等)作为整型常量处理,称为枚举常量。
2> 枚举元素的值取决于定义时各枚举元素排列的先后顺序。默认情况下,第一个枚举元素的值为0,第二个为1,依次顺序加1。
例:enum Season {spring, summer, autumn, winter};
也就是说spring的值为0,summer的值为1,autumn的值为2,winter的值为3
3> 也可以在定义枚举类型时改变枚举元素的值
enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加1。也就说spring的值为0,summer的值为3,autumn的值为4,winter的值为5
枚举变量的基本操作
1、赋值
可以给枚举变量赋枚举常量或者整型值
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);
}