目录
1.结构体
1.1含义格式
(1)定义:可理解为自定义的数据类型,是由一批数组组合而成的结构型数据,里面的每一个数据都是结构体的“成员”。
(2)格式:
struct 结构体名字
{
成员1 ;
成员2 ;
......
};
(3)书写位置:
- 里面:局部位置,只能在本函数中使用。
- 外面:全局位置,在所有函数中使用(常用)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
struct girlfriend
{
char name[100];
int age;
char gender;
double height;
};
int main()
{
struct girlfriend gf1;
strcpy(gf1.name, "小征");
gf1.age = 19;
gf1.gender = 'F';
gf1.height = 1.72;
printf("你女朋友的名字为:%s\n", gf1.name); //你女朋友的名字为:小征
printf("你女朋友的年龄为:%d\n", gf1.age); //你女朋友的年龄为:19
printf("你女朋友的性别为:%c\n", gf1.gender); //你女朋友的性别为:F
printf("你女朋友的身高为:%.2lf\n", gf1.height);//你女朋友的身高为:1.72
printf("\n");
struct girlfriend gf2;
strcpy(gf2.name, "小辉");
gf2.age = 18;
gf2.gender = 'F';
gf2.height = 1.69;
printf("你女朋友的名字为:%s\n", gf2.name); //你女朋友的名字为:小辉
printf("你女朋友的年龄为:%d\n", gf2.age); //你女朋友的年龄为:18
printf("你女朋友的性别为:%c\n", gf2.gender); //你女朋友的性别为:F
printf("你女朋友的身高为:%.2lf\n", gf2.height);//你女朋友的身高为:1.69
return 0;
}
eg:定义一个结构体表示学生,学生属性有姓名和年龄。要求:把3个学生信息放入到数组中,并遍历数组。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct student
{
char name[100];
int age;
};
int main()
{
struct student stu1 = { "小雷",18 };
struct student stu2 = { "小文",20 };
struct student stu3 = { "小鑫",19 };
struct student stuarr[3] = { stu1,stu2,stu3 };
for (int i = 0; i < 3; i++)
{
struct student temp = stuarr[i];
printf("学生的信息为:姓名:%s 年龄:%d\n",temp.name,temp.age);
}
//学生的信息为:姓名:小雷 年龄:18
//学生的信息为:姓名:小文 年龄:20
//学生的信息为:姓名:小鑫 年龄:19
return 0;
}
1.2 起别名
格式
typedef struct GirlFriend(可写可不写)
{
成员1 ;
成员2 ;
......
}别名 ;
eg:定义一个结构体表示游戏人物,属性有:姓名,攻击力,防御力和血量。要求:把三个游戏人物放入数组中,并且遍历数组。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef struct ultraman
{
char name[100];
int attack;
int defense;
int blood;
}m;
int main()
{
m taro = { "泰罗",100,90,500 };
m dijia = { "迪迦",90,100,450 };
m sailuo = { "赛罗",300,200,800 };
m arr[3] = { taro,dijia,sailuo };
for (int i = 0; i < 3; i++)
{
m temp = arr[i];
printf("奥特曼名称:%s,攻击力:%d,防御力:%d,血量:%d\n",
temp.name, temp.attack, temp.defense, temp.blood);
}
//奥特曼名称:泰罗,攻击力:100,防御力:90, 血量:500
//奥特曼名称:迪迦,攻击力:90, 防御力:100,血量:450
//奥特曼名称:赛罗,攻击力:300,防御力:200,血量:800
return 0;
}
1.3 结构体作为函数参数
函数中可以传递结构体——传递结构体中的数据值和地址值
eg:定义一个结构体表示学生,学生属性:姓名,年龄。要求:定义一个函数,修改学生中的数据
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
typedef struct student
{
char name[100];
int age;
}s;
void method(s* p);// 函数声明
int main()
{
s stu;// 使用结构体,定义一个学生
strcpy(stu.name, "aaa");// 赋初始值
stu.age = 0;
printf("学生初始数据为: %s, %d\n", stu.name, stu.age);
method(&stu);// 调用函数修改学生中的数据
printf("学生的信息修改为: %s, %d\n", stu.name, stu.age);// 输出打印
return 0;
}
// 直接接受 stu 的内存地址,通过内存地址就可以修改 stu 中的数据了
// 指针 p 里面记录的是 main 函数中 stu 的内存地址(stu:学生)
void method(s* p)
{
printf("接受到 main 函数中学生初始数据为: %s, %d\n", (*p).name, (*p).age);
printf("请输入修改学生的名字\n"); // 修改
scanf("%s", (*p).name);
printf("请输入修改学生的年龄\n");
scanf("%d", &((*p).age));
printf("在 method 函数中修改后学生信息为: %s, %d\n", (*p).name, (*p).age);
}
1.4 结构体嵌套
如结构体中成员的类型是其他的结构体,就用到了结构体嵌套
定义一个结构体表示学生student,要求:名字,年龄,性别,身高和联系方式。联系方式message也是一个结构体,要求:手机号和电子邮箱
#define _CRT_SECURE_NO_WARNINGS
//定义一个结构体表示学生student,要求:名字,年龄,性别,身高和联系方式
//联系方式message也是一个结构体,要求:手机号和电子邮箱
#include <stdio.h>
#include<string.h>
typedef struct message
{
char phone[12];
char mail[100];
}a;
typedef struct student
{
char name[100];
int age;
char gender;
double height;
struct message msg;
}b;
int main()
{
b stu;//定义学生类型变量
//给里面每一个成员进行赋值
strcpy(stu.name, "灰灰");
stu.age = 23;
stu.gender = 'M';
stu.height = 1.75;
strcpy(stu.msg.phone, "13145215200");
strcpy(stu.msg.mail, "123456@qq.com");
//输出打印
printf("学生的信息: \n");
printf("姓名为: %s\n", stu.name);
printf("年龄为: %d\n", stu.age);
printf("性别为: %c\n", stu.gender);
printf("身高为: %.2lf\n", stu.height);
printf("手机号为: %s\n", stu.msg.phone);
printf("电子邮箱为: %s\n", stu.msg.mail);
printf("----------------------------------------------\n");
//批量进行赋值
struct student stu2 = { "雷文",19,'M',1.78,{"19216810283","472842@qq.com"} };
//输出打印
printf("学生的信息: \n");
printf("姓名为: %s\n", stu2.name);
printf("年龄为: %d\n", stu2.age);
printf("性别为: %c\n", stu2.gender);
printf("身高为: %.2lf\n", stu2.height);
printf("手机号为: %s\n", stu2.msg.phone);
printf("电子邮箱为: %s\n", stu2.msg.mail);
return 0;
}
1.5 内存对条
- C语言中确定变量位置:只能放在自己类型整数倍的内存地址上。
- C语言中最后一个补位:结构体的总大小,是最大类型的整数倍。
投票选举→现在需要选择景区ABCD其中一个,有80人投票。要求:①学生投票,随机模拟②如果景点投票一样,A优先B,B优先C,C优先D
#define _CRT_SECURE_NO_WARNINGS
/* 投票选举→现在需要选择景区ABCD其中一个,有80人投票
要求①学生投票,随机模拟②如果景点投票一样,A优先B,B优先C,C优先D */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct pot
{
char name[100];
int count;
};
int main()
{
struct pot arr[4] = { {"A",0},{"B",0},{"C",0},{"D",0} };// 定义数组存储 4 个 pot 类型变量
// 模拟 80 名同学的投票
srand(time(NULL));
for (int i = 0; i < 80; i++)
{// choose 变量有 2 个含义:①表示用户投票②表示 arr 索引,通过这个索引可以获取景点名字和投票数
int choose = rand() % 4;
arr[choose].count++;
}
int max = arr[0].count;// 找最大值
for (int i = 1; i < 4; i++)
{
if (arr[i].count > max)
{
max = arr[i].count;
}
}
char* finalWinner = arr[0].name;// 处理票数相同的情况,按照 A 优先 B,B 优先 C,C 优先 D 的规则
for (int i = 1; i < 4; i++)
{
if (arr[i].count == max)
{
if (strcmp(arr[i].name, finalWinner) < 0)
{
finalWinner = arr[i].name;
}
}
}
printf("投票最多的景点为:%s,共计 %d 张票\n", finalWinner, max);// 输出最终获胜者
for (int i = 0; i < 4; i++)// 遍历
{
printf("%s %d\n", arr[i].name, arr[i].count);
}
return 0;
}
//投票最多的景点为:A,共计 26 张票
//A 19
//B 17
//C 26
//D 18
2.共用体
(1)定义
一种数据可能有多种类型
(2)格式
(与结构体相反)
union money
{ double mond ;
int moni ;
char mons ;} ;
union money m ;
m.moneyi = 100 ;
printf ( " %d\n ", n.moneyi );
(3)特点
- 共用体也叫联合体,共用体。
- 所有的变量都使用同一个内存空间。
- 所占的内存(细节:以最大成员长度为准!总大小一定是最大成员的单个整数倍)大小=最大成员的长度(也受内存对齐影响)。
- 每次只能给一个变量进行赋值,因为第二次赋值时会覆盖原有的数据。
(4)与结构体区别
①定义
- 结构体表一种事物中包含多个属性
- 共用体表一个属性有多种类型
②存储方式
- 结构体:各存各的
- 共用体:存一起,多次存会覆盖
③内存占用
- 结构体:各个变量的总和(受内存对齐影响)
- 共用体:最大类型(受内存对齐影响)
(5)例题
①需求:金融项目中,钱有可能是整数,小数,字符串,请定义对应共同体
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef union moneytype
{
int moneyi;
double moneyd;
char moneystr[100];
}mt;
int main()
{//利用共同体定义钱的变量
union moneytype mt;
//赋值,每次只能赋一个值
//mt.moneyi = 99999;
//mt.moneyd = 123.32;
strcpy(mt.moneystr, "100万");
//输入打印,上面赋值哪个类型,下面就从哪个类型取出来
//printf("%d\n", mt.moneyi);
//printf("%lf\n", mt.moneyd);
printf("%s\n", mt.moneystr);//100万
return 0;
}
②需求:金融项目中,钱有可能是整数,小数,字符串,请定义对应共同体
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef union moneytype
{
int moneyi;//4字节
double moneyd;//8字节
char moneystr[100];//1字节
//char:100*1=100字节,因为double最大,必须是8的倍数:104!
}mt;
int main()
{//利用共同体定义钱的变量
union moneytype mt;
//获取内存地址
printf("%p\n", &(mt.moneyi));
printf("%p\n", &(mt.moneyd));
printf("%p\n", &(mt.moneystr));
printf("------------------------------\n");
printf("%zu\n", sizeof(mt.moneyi));//4
printf("%zu\n", sizeof(mt.moneyd));//8
printf("%zu\n", sizeof(mt.moneystr));//100
printf("%zu\n", sizeof(mt));//104(后面补4个空白字节)
return 0;
}