结构体简介
1.结构体
笔记
struct:关键字
gf1.里面的“.”表示调用里面的这些成员
小程序
#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.结构体数组
小程序
#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去取了个名之后,上面结构体正式的名字可以省略不写
小程序
#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.结构体作为函数的参数进行传递
#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,// 所以要把这个整体括起来,然后再去调用nameprintf("请输入要修改的学生名字\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.结构体嵌套
#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;//因为此时还没有起别名,所以只要用到结构体前面必须要写structstruct Message msg;
};int main()
{/*定义一个结构体表示表示学生studentstudent成员如下:名字,年龄,性别,身高,联系方式联系方式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.综合练习----投票选举
#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;}