1.结构体
笔记
struct:关键字
gf1.里面的"."表示调用里面的这些成员



小程序
cs
#include <stdio.h>
#include <string.h>
/*
结构体:
自定义的数据类型
就是由很多的数据组合成的一个整体
每一个数据,就是结构体的成员
书写的位置:
函数的里面:局部位置,只能在本函数中使用
函数的外面:全局位置,在所有函数都可使用
*/
struct GirlFriend //
{
char name[100];
int age;
char gender;
double height;
};
int main()
{
//使用结构体
//定义一个女朋友类型的变量
struct GirlFriend gf1;//在C语言中并没有规定 GirlFriend的类型,是自己定义的,在前面要加上struct
//gf1.name = //.表示调用里面这些成员
//name是一个字符串,不能在这直接写一个"",因为字符串赋值,真正的是要把它里面的每一个字符赋值到上面的数组里面
//所以说此时如果要对名字进行赋值,要用string里面的函数
strcpy_s(gf1.name, "jjj");
gf1.age = 23;
gf1.gender = 'F';
gf1.height = 1.63;
//输出打印
printf("名字为:%s\n", gf1.name);
printf("年龄为:%d\n", gf1.age);
printf("性别为:%d\n", gf1.gender);
printf("身高为:%lf\n", gf1.height);
return 0;
}
2.结构体数组
小程序
cs
#include <stdio.h>
struct Student
{
char name[100];
int age;
};
int main()
{
//1.定义3个学生,同时进行赋值
struct Student stu1 = { "zhangsan" ,23};
struct Student stu2 = { "lisi",24 };
struct Student stu3 = { "wangwu",25 };
//2.把三个学生放入数组当中
struct Student stuArr[3] = {stu1,stu2,stu3 };//stuArr为名字,容易看的名字
//struct Student 是自己定义的类型
//3.遍历数组得到每一个元素
for (int i = 0; i < 3; i++)
{
struct Student temp = stuArr[i];//StuArr[i]这样就能获取数组里的每一个元素,其实就是每一个学生0,然后再把他赋值给一个临时变量
printf("学生的信息为:姓名%s,年龄%d\n", temp.name, temp.age);
}
return 0;
}
3.起别名
笔记
type就是类型的意思,def是define的意思,
如果用typedef去取了个名之后,上面结构体正式的名字可以省略不写


小程序
cs
#include <stdio.h>
typedef struct
{
char name[100];
int attack;
int defense;
int blood;
}M;
int main()
{
//1.定义奥特曼
M taro = { "泰罗",100,90,500 };
M rem = { "迪迦",90,80,500 };
M daina = { "戴拿",100,99,599 };
//2.定义数组
M arr[3] = { taro,rem,daina };
//3.遍历数组
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);
}
return 0;
}
4.结构体作为函数的参数进行传递
cs
#include<stdio.h>
#include <string.h>
typedef struct Student
{
char name[100];
int age;
}S;
//因为这个函数用到了结构体,所以函数的申明必须写在结构体的下面,否则代码会直接报错
//但是声明的位置也有讲究,不能写在结构体的上面,程序在运行时,他是从上往下一行一行去见检查,
// 当执行到第4行,第4行里面有个s,也不知道这个s是什么意思,s是定义在下面的,所以说这个函数要写在下面
void method(S st);
void method2(S* p);
int main()
{
/*
定义一个结构体表示学生
学生的属性:姓名,年龄
要求:
定义一个函数,修改学生中的数据
*/
//1.定义一个学生
S stu;
//2.给学生赋初始值
strcpy_s(stu.name, "aaa");// 因为name是一个字符串,所以在赋值时会用到string里面的函数,所以在上面先导入#include <string.h>
//就可以使用strcpy这个函数了
stu.age = 0; //age是一个int 类型的,所以直接赋值为0
//3.输出打印
printf("学生的初始数据为:%s,%d\n", stu.name, stu.age);
//4.调用函数修改学生中的数据
//来调用method,然后去把stu传递过去进行修改,
method2(&stu);//此时运行完之后,要来调用method2,然后要把stu的地址给传递过去,也就是要在前面写一个&
//5.输出打印
printf("学生的信息修改为:%s,%d\n", stu.name, stu.age);
return 0;
}
//如果函数中写的是结构体类型的变量,相当于定义了一个新的变量
//此时是把main函数中stu中的数据,传递给了method函数,并把stu中的数据赋值给了新的变量st
//我们在函数中,仅仅是修改了变量st的值,对main函数中stu 的值,是没有进行修改的
void method(S st)
{
printf("接受到main函数中学生的初始数值为:%s,%d\n", st.name, st.age);
//叫做接受到main函数中学生的初始数据,此时用str去调用就可以了
//修改 修改要以键盘录入的形式
printf("请输入要修改的学生名字\n");
scanf_s("%s", st.name);//注意的是这里的str.name,这里的name本身就是一个数组了,
//数组在参与计算的时候,这个name 数组的名字就会退化为指向第一个元素的指针,
//所以说str.name就已经是一个内存地址了,所以在前面就没必要再加一个&再去获取他的内存地址了
printf("请输入要修改的学生年龄\n");
scanf_s("%d", &(st.age));//现在这个age是一个int类型的,只是一个普通的变量,不是一个数组,
//所以要把这个整体括起来,然后再去获取他的内存地址
printf("在main函数中修改之后,学生的信息为:%s,%d\n", st.name, st.age);
}
//如果要在函数中修改stu的值,此时就不要再重新定义一个变量了
//直接接受str的内存地址,通过内存地址就可以修改stu中的数据了
//指针p里面记录的是main函数中stu的内存地址(stu 学生)
void method2(S* p)//*表示是一个指针
{
printf("接受到main函数中学生的初始数值为:%s,%d\n", (*p).name, (*p).age);
//通过内存地址,要用*+指针去解引用,其中*p.name中的*p表示的是main函数中的stu,
// 所以要把这个整体括起来,然后再去调用name
printf("请输入要修改的学生名字\n");
scanf_s("%s", (*p).name);//首先这个p是一个指针,指针里面记录的是main函数当中stu那个变量的内存地址
//然后我们要对这个指针进行解引用,一旦解引用了,他现在就表示的是main函数当中stu那个变量了
// ,也就是那个学生.那现在,要去获取他里面的name,即用这个整体去调用name就可以了
printf("请输入要修改的学生年龄\n");
scanf_s("%d", &((*p).age));//同样的,要用他去调用age,但是这个只是那个age的变量,我们还要获取到这个age这个变量的地址,
//还要把这个整体括起来,获取这个整体的内存地址,赋值给scanf,这才可以
printf("在main函数中修改之后,学生的信息为:%s,%d\n", (*p).name, (*p).age);
}
5.结构体嵌套
cs
#include <stdio.h>
#include <string.h>
struct Message
{
char phone[12];
char mail[100];
};
struct Student
{
char name[100];
int age;
char gender;
double heigth;
//因为此时还没有起别名,所以只要用到结构体前面必须要写struct
struct Message msg;
};
int main()
{
/*
定义一个结构体表示表示学生student
student成员如下:
名字,年龄,性别,身高,联系方式
联系方式Message也是一个结构体,成员如下
手机号,电子邮箱
*/
//1. 定义学生类型的变量
struct Student stu;
//2.给里面的每一个成员进行赋值
strcpy_s(stu.name, "zhangtao");
stu.age = 23;
stu.gender = 'M';
stu.heigth = 1.78;
strcpy_s(stu.msg.phone, "13112345678");
strcpy_s(stu.msg.mail, "12345678@qq.com");
//3.输出打印
printf("学生的信息为:\n");
printf("姓名为:%s\n", stu.name);
printf("年龄为:%d\n", stu.age );
printf("性别为:%c\n", stu.gender);
printf("身高为:%lf\n", stu.heigth);
printf("手机号为:%s\n", stu.msg.phone);
printf("邮箱为:%s\n", stu.msg.mail);
printf("------------------------\n");
//批量进行赋值
struct Student stu2 = { "lixiang",24,'F',1.65,{"1311234567","5678@qq.com"} };
//3.输出打印
printf("学生的信息为:\n");
printf("姓名为:%s\n", stu2.name);
printf("年龄为:%d\n", stu2.age);
printf("性别为:%c\n", stu2.gender);
printf("身高为:%lf\n", stu2.heigth);
printf("手机号为:%s\n", stu2.msg.phone);
printf("邮箱为:%s\n", stu2.msg.mail);
return 0;
}
6.综合练习----投票选举
cs
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct spot
{
char name[100];
int count;
};
int main()
{
/*
某班级组织野外郊游,想要再ABCD4个景点选择其中一个
现在班上有80名同学进行投票,找出投票数最多的景点
1.学生投票用随机数模拟
2.如果多个景点投票一样的话,A优先于B,B优先C,C优先于D
*/
//1.定义数组存储4个spot类型的变量
struct spot arr[4] = { {"A",0},{"B",0},{"C",0},{"D",0}};
//2.模拟80名同学的投票
srand(time(NULL));
for (int i = 0; i < 80; i++)
{
//choose 变量有2个含义
//含义一:表示用户的投票0A 1B 2C 3D
//含义二:表示arr中的索引,通过这个索引就可以获取到景点的名字和投票数量
int choose=rand() % 4;//0 1 2 3
//0就认为你投的是A,1就认为你投的是B,...
//choose是表示同学的投票,同时也表示数组中的索引
//arr[choose]:表示获取景点的信息(名字,数量)
//arr[choose].count: 表示这个景点已经投了多少票
//arr[choose].count++:给这个景点再投一票
arr[choose].count++;//用arr[]把choose传递过去,相当于我可以通过这个索引获取到景点的信息
}
//找最大值
int max = arr[0].count;
for (int i = 0; i < 4; i++)//现在默认零索引的count是最大值
//i可以从1开始,因为0已经赋值给max了,作为max的初始值
{
struct spot temp = arr[i];
if (temp.count > max)
{
max = temp.count;
}
}
//遍历数组,看谁的票数刚好是最大值
for (int i = 1; i < 4; i++)
{
struct spot temp = arr[i];
if(temp.count == max)
{
printf("投票最多的景点为:%s,共计: %d张票\n", temp.name, temp.count);
break;
}
}
//遍历
for (int i = 0; i < 4; i++)
{
struct spot temp = arr[i];
printf("%s %d\n", temp.name, temp.count);
}
return 0;
}
7.内存对齐

