C语言 结构体
C语言 结构体
数组:描述一组具有相同类型数据的有序集合,用于处理大量相同类型的数据运算。
有时我们需要将不同类型的数据组合成一个有机的整体,如:一个学生有学号/姓名/性别/年龄/地址等属性。显然单独定义以上变量比较繁琐,数据不便于管理。
C语言中给出了另一种构造数据类型——结构体。
结构体变量定义初始化
一、定义结构体变量的方式
- 先声明结构体类型再定义变量名
- 在声明类型的同时定义变量
- 直接定义结构体类型变量(无类型名)
二、 结构体类型和结构体变量关系
- 结构体类型:指定了一个结构体类型,它相当于一个模型,但其中并无具体数据,系统对之也不分配实际内存单元。
- 结构体变量:系统根据结构体类型(内部成员状况)为之分配空间。
三、结构体案例
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> // struct 结构体名 // { // 结构体成员列表 // 姓名 // 年龄 // 成绩 // }; struct student { char name[21]; int age; int score; char addr[51]; }; // 方式三 // 创建全局变量 // stu = { "张三",18,100,"北京市昌平区北清路22号" }; int main(void) { // 方式一 // 创建结构体变量 // 结构体类型 名称 结构体变量 // struct student stu; // 数组结构体变量为常量:不能直接复制stu.name = "张三"; // 通过拷贝方式赋值变量 // strcpy(stu.name, "张三"); // stu.age = 18; // stu.score = 100; // strcpy(stu.addr, "北京市昌平区北清路22号"); // 方式二 struct student stu = { "张三",18,100,"北京市昌平区北清路22号" }; printf("姓名:%s\n", stu.name); printf("年龄:%d\n", stu.age); printf("成绩:%d\n", stu.score); printf("地址:%s\n", stu.addr); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> struct student { char name[21]; int age; int score; char addr[51]; }; int main(void) { // 通过键盘获取 struct student stu; // 数组不需要取地址,变量需要取地址 scanf("%s%d%d%s", stu.name, &stu.age, &stu.score,stu.addr); printf("姓名:%s\n", stu.name); printf("年龄:%d\n", stu.age); printf("成绩:%d\n", stu.score); printf("地址:%s\n", stu.addr); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> struct student { // 结构体成员需要偏移对齐 char name[21]; int age; char sex; int score[3]; char addr[51]; }; int main(void) { // 结构体数组 struct student stu[]= { {"蛮王",34,'M',88,99,0,"诺克萨斯"}, {43,'M',0,0,0,"德玛西亚",.name = "盖伦" }, {"拉克丝",18,'F',2,2,2,"窑子"} }; // 打印 for (int i = 0; i < 3; i++) { printf("姓名:%s\n", stu[i].name); printf("年龄:%d\n", stu[i].age); printf("性别:%s\n", stu[i].sex == 'M' ? "男" : "女"); printf("成绩:%d\n", stu[i].score[0]); printf("成绩:%d\n", stu[i].score[1]); printf("成绩:%d\n", stu[i].score[2]); printf("地址:%s\n\n", stu[i].addr); } // 通过sizeof求出结构体 printf("结构体数组大小:%d\n", sizeof(stu)); printf("结构体数组元素大小:%d\n", sizeof(stu[0])); printf("结构体数组元素个数:%d\n", sizeof(stu[0])/sizeof(stu[0])); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> struct student { char name[21]; int age; char sex; int score[3]; char addr[51]; }; int main(void) { struct student stu[]= { {"蛮王",34,'M',88,99,0,"诺克萨斯"}, {.age = 43,'M',0,0,0,"德玛西亚",.name = "盖伦" }, {"拉克丝",18,'F',2,2,2,"窑子"} }; // 根据年龄排序 for (int i = 0; i < 3 - 1; i++) { for (int j = 0; j < 3 - 1 - i; j++) { if (stu[j].age > stu[j + 1].age) { struct student temp = stu[j]; stu[j] = stu[j + 1]; stu[j + 1] = temp; } } } // 打印 for (int i = 0; i < 3; i++) { printf("姓名:%s\n", stu[i].name); printf("年龄:%d\n", stu[i].age); printf("性别:%s\n", stu[i].sex == 'M' ? "男" : "女"); printf("成绩:%d\n", stu[i].score[0]); printf("成绩:%d\n", stu[i].score[1]); printf("成绩:%d\n", stu[i].score[2]); printf("地址:%s\n\n", stu[i].addr); } return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> // 为 struct student 起别名 typedef struct student ss; struct student { char name[21]; int age; char sex; int score[3]; char addr[51]; }; int main(void) { // 输出结构体大小 // printf("%d\n", sizeof(struct student)); // 创建结构体指针类型的堆空间并指定结构体内存大小 ss * p = (ss *)malloc(sizeof(ss) * 3); prinf("结构体指针大小:%d", sizeof(ss*)); // 通过键盘存储内容 for (int i = 0; i < 3; i++) { scanf("%s%d,%c%d%d%d%s", p[i].name, &p[i].age, &p[i].sex, &p[i].score[0], &p[i].score[1], &p[i].score[2], p[i].addr); } // 打印 for (int i = 0; i < 3; i++) { printf("姓名:%s\n", p[i].name); printf("年龄:%d\n", p[i].age); printf("性别:%s\n", p[i].sex == 'M' ? "男" : "女"); printf("成绩:%d\n", p[i].score[0]); printf("成绩:%d\n", p[i].score[1]); printf("成绩:%d\n", p[i].score[2]); printf("地址:%s\n\n", p[i].addr); } // 释放内存 free(p); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> // 游戏案例 /* struct 技能 { 名称 等级 伤害 范围 消耗 冷却 } struct 人物信息 { 等级 经验 金钱 hp mp 力量 智力 敏捷 struct 技能 skills[4] } struct 人物信息 info; info.skills[0].名称 */ struct scores { int c1;//c语言 int cpp;//c++ int cs;//c# }; struct student { char name[21]; int age; struct scores ss; char addr[51]; }; int main(void) { // 赋值 struct student stu = { "貂蝉",18,99,99,99,"徐州" }; // 打印 printf("%s\n%d\n%d\n%d\n%d%\n%s\n", stu.name, stu.age, stu.ss.c1, stu.ss.cpp, stu.ss.cs,stu.addr); // 赋值 strcpy(stu.name, "小乔"); stu.age = 16; stu.ss.c1 = 88; stu.ss.cpp = 88; stu.ss.cs = 88; strcpy(stu.addr, "江东"); // 打印 printf("%s\n%d\n%d\n%d\n%d%\n%s\n", stu.name, stu.age, stu.ss.c1, stu.ss.cpp, stu.ss.cs, stu.addr); printf("学生结构体大小%d\n",sizeof(stu)); printf("学生结构体大小%d\n", sizeof(stu.ss)); printf("名称数组大小%d\n", sizeof(stu.name)); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> struct student { char name[21]; int age; int score; char addr[51]; }; int main(void) { // 赋值 struct student stu = {"孙嫩香",26,60,"巴蜀"}; // 赋值变量 struct student s1 = stu; // 深拷贝和浅拷贝 strcpy(s1.name, "甘夫人"); s1.age = 28; s1.score = 80; // 输出 printf("%s\n", stu.name); printf("%d\n", stu.age); printf("%d\n", stu.score); return 0; }
#include<stdio.h> #include <string.h> //结构体类型的定义 struct stu { char name[50]; int age; }; //函数参数为结构体普通变量 void set_stu(struct stu tmp) { strcpy(tmp.name, "mike"); tmp.age = 18; printf("tmp.name = %s, tmp.age = %d\n", tmp.name, tmp.age); } int main() { struct stu s = { 0 }; set_stu(s); //值传递 printf("s.name = %s, s.age = %d\n", s.name, s.age); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> typedef struct student ss; struct student { // char name[21] char *name; int age; int score; char addr[51]; }; void fun(ss stu) { strcpy(stu.name, "卢俊义"); } int main(void) { ss stu = { NULL,50,101,"水泊梁山" }; stu.name = (char*)malloc(sizeof(char) * 21); strcpy(stu.name, "松江"); printf("%s\n", stu.name); fun(stu); printf("%s\n", stu.name); return 0; }
结构体和指针
一、说明
通过指针结合结构体进行操作
二、案例
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> // 结构体称为为指针类型 struct student { char* name; int age; int *scores; char* addr; }; int main(void) { struct student stu; // 常量:stu.name = "张春生";//err // 开辟堆空间 stu.name = (char*)malloc(sizeof(char) * 21); stu.scores = (int*)malloc(sizeof(int) * 3); stu.addr = (char*)malloc(sizeof(char) * 51); // 赋值 strcpy(stu.name, "张三"); stu.age = 18; stu.scores[0] = 88; stu.scores[1] = 99; stu.scores[2] = 100; strcpy(stu.addr, "北京市"); // 打印 printf("%s\n", stu.name); printf("%d\n", stu.age); printf("%d\n", stu.scores[0]); printf("%d\n", stu.scores[1]); printf("%d\n", stu.scores[2]); printf("%s\n", stu.addr); // 释放内存 free(stu.name); free(stu.scores); free(stu.addr); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> // 结构体称为为指针类型 struct student { char name[21]; int age; int scores[3]; char addr[51]; }; int main(void) { // 结构体指针 struct student stu = {"林冲",30,100,100,100,"边境"}; // 赋值结构体指针 struct student * p = &stu; // 打印值 // printf("%s\n", (*p).name); // printf("%d\n", (*p).age); // 结构体指针->成员 // 结构体变量.成员 printf("%s\n", p->name); printf("%d\n", p->age); printf("%d\n", p->scores[0]); printf("%d\n", p->scores[1]); printf("%d\n", p->scores[2]); printf("%s\n", p->addr); return 0; }
#include<stdio.h> #include <string.h> #include <stdlib.h> //结构体类型的定义 struct stu { char name[50]; int age; }; int main() { struct stu *p = NULL; p = (struct stu *)malloc(sizeof(struct stu)); //如果是指针变量,通过->操作结构体成员 strcpy(p->name, "test"); p->age = 22; printf("p->name = %s, p->age=%d\n", p->name, p->age); printf("(*p).name = %s, (*p).age=%d\n", (*p).name, (*p).age); free(p); p = NULL; return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> typedef struct student ss; struct student { char* name; int age; int* scores; char* addr; }; int main(void) { // 开辟 结构体堆空间 ss* p = (ss*)malloc(sizeof(ss) * 3); // 开辟 结构体成员堆空间 for (int i = 0; i < 3; i++) { (p + i)->name = (char*)malloc(sizeof(char*) * 21); (p + i)->scores = (int*)malloc(sizeof(int) * 3); (p + i)->addr = (char*)malloc(sizeof(char*) * 51); } // 赋值 for (int i = 0; i < 3; i++) { scanf("%s%d%d%d%d%s", p[i].name, &p[i].age, &p[i].scores[0], &p[i].scores[1], &p[i].scores[2], &p[i].addr); } // 输出 for (int i = 0; i < 3; i++) { printf("%s\n", p[i].name); printf("%d\n", p[i].age); printf("%d\n", p[i].scores[0]); printf("%d\n", (p + i)->scores[1]); printf("%d\n", (p + i)->scores[2]); printf("%s\n", (p + i)->addr); } // 释放堆空间内层 for (int i = 0; i < 3; i++) { free(p[i].name); free(p[i].scores); free(p[i].addr); } // 释放外层 free(p); return 0; }
#include<stdio.h> #include <string.h> //结构体类型的定义 struct stu { char name[50]; int age; }; //函数参数为结构体指针变量 void set_stu_pro(struct stu *tmp) { strcpy(tmp->name, "mike"); tmp->age = 18; } int main() { struct stu s = { 0 }; set_stu_pro(&s); //地址传递 printf("s.name = %s, s.age = %d\n", s.name, s.age); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> typedef struct student ss; struct student { char name[21]; //char *name; int age; int score; char addr[51]; }; void fun(ss * p) { strcpy(p->name, "公孙胜"); } int main(void) { // 结构体指针作为函数参数传递 ss stu = { "吴用",50,101,"水泊梁山" }; printf("%s\n", stu.name); fun(&stu); printf("%s\n", stu.name); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> typedef struct student ss; struct student { char name[21]; int age; int score[3]; char addr[51]; }; // 数组作为函数参数退化为指针、丢失元素静度、需要传递个数 void BubbleSort(ss * stu, int len) { for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - i - 1; j++) { // if(stu[j].age>stu[j+1].age) if ((stu + j)->age > (stu + j + 1)->age) { ss temp = stu[j]; stu[j] = stu[j + 1]; stu[j + 1] = temp; } } } } int main(void) { ss stu[3] = { { "鲁智深",30,33,33,33,"五台山" }, { "呼延灼",45,33,33,33,"汴京" }, { "顾大嫂",22,33,33,33,"汴京" }, }; // 传递结构体数组、 名称、通过函数排序 BubbleSort(stu, 3); // 输出 for (int i = 0; i < 3; i++) { printf("姓名:%s\n", stu[i].name); printf("年龄:%d\n", stu[i].age); printf("成绩:%d\n", stu[i].score[0]); printf("成绩:%d\n", (stu + i)->score[1]); printf("成绩:%d\n", (stu + i)->score[2]); printf("地址:%s\n", (stu + i)->addr); } return 0; }
//结构体类型的定义 struct stu { char name[50]; int age; }; void fun1(struct stu * const p) { //p = NULL; //err p->age = 10; //ok } //void fun2(struct stu const* p) void fun2(const struct stu * p) { p = NULL; //ok //p->age = 10; //err } void fun3(const struct stu * const p) { //p = NULL; //err //p->age = 10; //err }