IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言】struct结构体保姆级别教学! -> 正文阅读

[C++知识库]【C语言】struct结构体保姆级别教学!

目录

1.格式,命名

2. 大小计算

3.应用


struct是一种结构体,用来保存较为复杂的变量信息,这种信息的特点通常是:类型多且杂,内容多,分散不易于调试

比如一个人的信息,我们想把他封装起来保存,这样易于读取,使分散的信息集中

1.格式,命名?

我们现在想要记录一个学生的信息:学号1234,姓名lily,年级14,性别female

如何实现?

struct Student
{
	char ID[10];
	char name[10];
	int age;
	char gender[10];
};
int main()
{
	struct Student l = { "1234","Lily",14,"female" };
	printf("%s  %s  %d  %s", l.ID, l.name, l.age, l.gender);
}

?请注意这里一些基本的语法结构,包括初始化的方式(花括号),创建结构体的方式,结构体成员访问的细节

当然在我之前的博客已经分享过这个细节,https://blog.csdn.net/weixin_71138261/article/details/126071887?spm=1001.2014.3001.5501

这里不在赘述了?


2. 大小计算

关于结构体的大小计算才是本篇文章的重难点!!

首先,结构体也是有大小的

struct A
{
	int a;
	short b;
	int c;
	char d;
};
struct B
{
	int a;
	short b;
	char c;
	int d;
};

int main()
{
	printf("%d %d", sizeof(struct A), sizeof(struct B));
}

首先我们思考一下,应该是多少呢

直观来说,

对于struct A : int a? ?4字节? short b? ?2字节??int c? ?4字节? char d? 1字节

4+2+4+1=11

对于struct B:int a? ?4字节? ??short b? 2字节? ?char c? 1字节? ?int d? ?4字节

4+2+1+4=11

?那结果是这样吗?

居然一个都没对

到底是什么计算规则呢?

首先普及一下最最基本的规则 (你要从心底里接受它):对齐数,单位是字节(一下谈论的都是字节)

每个平台都有默认的对齐数

我现在使用的是vs2022,他的默认对齐数是8

每个结构体成员都有自己的类型,也就是自己的对齐数

自身的对齐数肯定会和默认对齐数冲突,那么我们到底在计算大小的时候听谁的?

谁小听谁的!!!!!!!!!!!!!!!

比如int? 自身对齐数是4,平台默认对齐数是8

所以int 最终的对齐数就是4

那么数组怎么办?和元素个数有关

?下一个很重要的概念:偏移量!

我们知道了各种类型的对齐数之后,到底他们是和谁对齐的呢?

是相对于0而言的,这个0是我们为了方便计算假想出来的,每个类型的对齐数就代表了他的偏移量

第一个偏移就是相对于0开始的

先掌握这两个概念之后,我们回头看一下上面的例子

一定要注意图片里的补充规则

那么自己算一下struct B的大小吧

?

如果大家怕默认对齐数不对的话可以自己检查

用offsetof这个函数

#include <stddef.h>
int main()
{
	printf("%d\n", sizeof(struct Book));
	printf("%d\n",(int) offsetof(struct Book,page));
	printf("%d\n", (int)offsetof(struct Book,name));
	printf("%d\n", (int)offsetof(struct Book,writer));

}

这个函数可以帮助你计算每个结构体成员的起始偏移量


难道每个平台就这么霸道吗?

注意:Linu系统没有默认对齐数,就是成员自身类型

其实我们可以修改默认对齐数

#include <stdio.h>

#include <stddef.h> 
//modifier fixed  alignment number  
//offsetof is a fonction to calculate the type shall be a structure or union type. 
struct Book
{
	char name[20];
	int page;
	char writer[20];
};

//if I wanna change the alignment number 
# pragma pack(1)
int main()
{
	printf("%d\n", sizeof(struct Book));
	printf("%d\n",(int) offsetof(struct Book,page));
	printf("%d\n", (int)offsetof(struct Book,name));
	printf("%d\n", (int)offsetof(struct Book,writer));

}

通过#progma pack(1)把默认对齐数修改成1,这样所有类型都是紧挨着填充,不会出现浪费


3.应用?

?其实我们可以感受到struct的重要性,这样生活中很多东西都可以封装,比如一本书,一个教室

那么我们来看一下用struct实现通讯录储存联系人的信息

//contact.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "contact.h";

void Init(struct conster*p)
{
	assert(p);
	p->sz = 0;
	memset(p->date, 0, sizeof(struct information) * MAX);

}

void Add(struct conster* p)
{
	assert(p);
	if (p->sz == 100)
	{
		printf("lack of memory !\n");
		return;
	}
	else
	{
		printf("Please input the name \n");

		scanf("%s", &(p->date[p->sz].name));

		printf("Please input the gender \n");

		scanf("%s", &(p->date[p->sz].gender));

		printf("Please input the  age\n");
		
		scanf("%d", &(p->date[p->sz].age));

		printf("Please input the tele \n");

		scanf("%s", &(p->date[p->sz].tele));

		printf("Please input the adress\n");

		scanf("%s", &(p->date[p->sz].adress));

		p->sz++;
		printf("success\n");
	}
}

void Show(struct conster* p)
{
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-20s\n", "name", "gender", "age", "telephone", "adress");
	for(int i=0;i<(p->sz);i++)
	{
		printf("%-20s\t%-5s\t%-5d\t%-20s\t%-20s\n", p->date[i].name, p->date[i].gender, p->date[i].age, p->date[i].tele, p->date[i].adress);
	}

}

int search_by_name(char* name,struct conster *p)
{
	for (int i = 0; i < p->sz; i++)
	{
		if (strcmp(name, p->date[i].name) == 0)
			//return 1;  //不能简单这样,需要记录要删除元素具体在通信录的位置
			return i;
	}
	return -1;
}
void Del(struct conster* p)
{
	char name[20] = { 0 };
	printf("Please input the name\n");
	scanf("%s", name);

	int ret=  search_by_name(name ,p);
	if (ret!=-1)
	{
		int j = 0;
		for (j = ret; j < p->sz - 1; j++)
		{
			p->date[j] = p->date[j + 1];
		}
		p->sz--;
		printf("success\n");
	}
	else
	{
		printf("There isn't the member!\n");
	}
}

void Mod(struct conster* p)
{
	char name[20] = { 0 };
	printf("Please input the name\n");
	scanf("%s", name);
	int ret = search_by_name(name, p);
	if (ret != -1)
	{
		int choice = 0;
	printf("** 1.name ** 2.gender ** 3.age ** 4.tele ** 5.adress**\n");
	scanf("%d", &choice);
	switch (choice)
	{
	case 1:
	{
		printf("Please input the name of the member who you want to modifier\n");
		scanf("%s", &(p->date[ret].name));
		break;
	}
	case 2:
	{
		printf("Please input the gender of the member who you want to modifier\n");
		scanf("%s", &(p->date[ret].gender));
		break;
	}
	case 3:
	{
		printf("Please input the age of the member who you want to modifier\n");
		scanf("%d", &(p->date[ret].age));
		break;
	}
	case 4:
	{
		printf("Please input the telephone of the member who you want to modifier\n");
		scanf("%s", &(p->date[ret].tele));
		break;
	}
	case 5:
	{
		printf("Please input the adress of the member who you want to modifier\n");
		scanf("%s", &(p->date[ret].adress));
		break;
	}
	}
	printf("success\n");
	}
	else
	{
		printf("There isn't the member!\n");
	}
	
}

void Search(struct conster* p)
{
	char name[20] = { 0 };
	printf("Please input the name\n");
	scanf("%s", name);

	int ret = search_by_name(name, p);
	if (ret != -1)
	{
		printf("%-20s\t%-5s\t%-5s\t%-20s\t%-20s\n", "name", "gender", "age", "telephone", "adress");

		printf("%-20s\t%-5s\t%-5d\t%-20s\t%-20s\n", p->date[ret].name, p->date[ret].gender, p->date[ret].age, p->date[ret].tele, p->date[ret].adress);

		
	}
	else
	{
		printf("There isn't the member!\n");
	}
}

void All_cls(struct conster *p)
{
	assert(p);
	p->sz = 0;
	memset(p->date, 0, sizeof(struct information) * MAX);
	printf("%-20s\t%-5s\t%-5s\t%-20s\t%-20s\n", "name", "gender", "age", "telephone", "adress");

	printf("%-20s\t%-5s\t%-5d\t%-20s\t%-20s\n", p->date[0].name, p->date[1].gender, p->date[2].age, p->date[3].tele, p->date[4].adress);
}

int comper(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2); //把小的放前
}
void Sort(struct conster* p)
{
	qsort(p->date, p->sz, sizeof(struct information), comper);
	printf("success\n");
}


//main.c

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "contact.h"

void menu()
{
	printf("********* 1.Add ******** 2.Delate *********\n");
	printf("********* 3.Modifier *** 4.Search *********\n");
	printf("********* 5.Show ******* 6.all cls *********\n");
	printf("********* 7.sort ******* 0.exit *********\n");

}


int main()
{
	//struct information date[MAX];  //创建一百个人的信息

	struct conster con;   //创建通讯录

	Init(&con); //初始化

	int num = 0;

	do {
		menu();

		printf("Please input your number\n");

		scanf("%d", &num);
		switch (num)
		{
		case 1:
			Add(&con);
			break;
		case 2:
			Del(&con);
			break;
		case 3:
			Mod(&con);
			break;
		case 4:
			Search(&con);
			break;
		case 5:
			Show(&con);
			break;
		case 6:
			All_cls(&con);
			break; 
		case 7:
			Sort(&con);
			break;
		case 0:
			printf("Bye~\n");
		  	break;
		default :
			printf("Please input agine\n");
			break;
		}
	} while (num);
	return 0;
}

//contact.h
#pragma once
#include <assert.h>
#include <string.h>
#include <stdlib.h>

#define MAX 10

struct information 
{
	//姓名、性别、年龄、电话、住址
	char name[20];
	char gender[5];
	int age;      
	int tele[20];  
	char adress[20];
};

struct conster
{
	int sz;
	struct information date[MAX];  //存放十个人的信息
};

void Init(struct conster* p);

void Add(struct conster* p);

void Show(struct conster* p);

void Del(struct conster* p);

void Mod(struct conster* p);

void All_cls(struct conster* p);

void Sort(struct conster* p);

int search_by_name(char* name, struct conster* p);

void Search(struct conster* p);


创作不易,感谢观看?

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 20:38:18  更:2022-09-24 20:40:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:01:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码