iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言结构体(struct)的详细讲解
  • 535
分享到

C语言结构体(struct)的详细讲解

2024-04-02 19:04:59 535人浏览 安东尼
摘要

目录引言1. 动态内存管理2. 结构体2.1 定义语法2.2 定义示例2.3 初始化2.4 结构体赋值2.5 结构体数组2.6 结构体指针赋值3. 学生管理系统附:结构体变量的存储原

引言

当前文章介绍动态堆空间内存分配与释放,C语言结构体定义、初始化、赋值、结构体数组、结构体指针的相关知识点,最后通过一个学生管理系统综合练习结构体数组的使用。

1. 动态内存管理

C语言代码----->编译----->链接------>可执行的二进制文件(windows下xxx.exe) 二进制文件中的数据是如何摆放的? 文本数据段、静态数据段、全局数据段。

堆栈空间: 代码在运行的时候才有的空间。 栈空间: 系统负责申请,负责释放。比如: 函数形参变量、数组…… 堆空间: 程序员负责申请,负责释放。

 #include <stdlib.h>     //标准库头文件
 void *malloc(int size); //内存申请。 形参表示申请的空间大小,返回值:申请的空间的地址
 void free(void *p);     //内存释放。 形参就是要释放的空间首地址。

动态空间申请示例。

 动态空间申请
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 int main()
 {
     int *p=malloc(sizeof(int)); //申请空间
     if(p!=NULL)
     {
         printf("申请的空间地址: 0x%X\n",p);
         *p=888;
         printf("%d\n",*p);
     }
     free(p); //释放空间
     return 0;
 }
 示例2:
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ​
 char *func(void)
 {
     char*str=malloc(100); //char str[100];
     if(str!=NULL)
     {
         strcpy(str,"1234567890");
         printf("子函数打印:%s\n",str);
         //free(str); //释放空间
         return str;
     }
     else
     {
         return NULL;
     }
 }
 ​
 int main()
 {
     char *p=func();
     printf("主函数打印:%s\n",p);
     return 0;
 }

2. 结构体

2.1 定义语法

结构体的概念: 可存放不同数据类型的集合。 比如: 存放一个班级学生的信息。 可以使用一个结构体存放一个学生的信息。 一个结构体数组存放整个班级的学习信息。 数组的概念: 可存放相同数据类型的集合。

结构体的定义语法:

 //声明一种新类型-----数据类型
 struct <结构体的名称>
 {
     <结构体的成员>1;
 <结构体的成员>2;
 …………
 };  //最后有分号结束
 ​
 struct MyStruct 
 {
     char a;
     int b;
     float c;
     char str[100];
 };

2.2 定义示例

结构体如何赋值? 如何访问结构体内部成员

 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ​
 //定义结构体数据类型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 };
 int main()
 {
     struct MyStruct data={'A',123,456.789,"abcd"}; //data就是结构体类型的变量
     //结构体变量访问内部成员的语法:  . 点运算符
     printf("%c\n",data.a);
     printf("%d\n",data.b);
     printf("%f\n",data.c);
     printf("%s\n",data.str);
     return 0;
 }

2.3 初始化

 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ​
 //定义结构体数据类型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }data={'A',123,456.789,"abcd"}; //data就是结构体类型的变量
 ​
 int main()
 {
     //结构体变量访问内部成员的语法:  . 点运算符
     printf("%c\n",data.a);
     printf("%d\n",data.b);
     printf("%f\n",data.c);
     printf("%s\n",data.str);
     return 0;
 }

2.4 结构体赋值

   //结构体变量访问内部成员的语法:  . 点运算符
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ​
 //定义结构体数据类型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }; 
 ​
 int main()
 {
     struct MyStruct data;//data就是结构体类型的变量
     //成员单独赋值
     data.a='A';
     data.b=123;
     data.c=456.789;
     strcpy(data.str,"abcd"); //数组赋值
 ​
     //结构体变量访问内部成员的语法:  . 点运算符
     printf("%c\n",data.a);
     printf("%d\n",data.b);
     printf("%f\n",data.c);
     printf("%s\n",data.str);
     return 0;
 }

2.5 结构体数组

 结构体赋值分为两种标准:  C89 、C99
 结构体数组
 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 ​
 //定义结构体数据类型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }; 
 ​
 int main()
 {
     struct MyStruct data[100];//data就是结构体数组类型变量
     struct MyStruct data2[50];
 ​
     //成员单独赋值
     data[0].a='A';
     data[0].b=123;
     data[0].c=456.789;
     strcpy(data[0].str,"abcd"); //数组赋值
 ​
     //结构体变量访问内部成员的语法:  . 点运算符
     printf("%c\n",data[0].a);
     printf("%d\n",data[0].b);
     printf("%f\n",data[0].c);
     printf("%s\n",data[0].str);
     return 0;
 }

2.6 结构体指针赋值

 #include "stdio.h"
 #include "string.h"
 #include <stdlib.h>
 //定义结构体数据类型
 struct MyStruct
 {
     char a;
     int b;
     float c;
     char str[100];
 }; 
 ​
 int main()
 {
     //struct MyStruct buff[100];
     //struct MyStruct *data=buff; //结构体指针类型变量
 ​
     struct MyStruct *data=malloc(sizeof(struct MyStruct));
     data->a='A';
     data->b=123;
     data->c=456.789;
     strcpy(data->str,"abcd");
 ​
     //结构体指针访问内部成员的变量 通过  ->  运算符。 
     printf("%c\n",data->a);
     printf("%d\n",data->b);
     printf("%f\n",data->c);
     printf("%s\n",data->str);
     return 0;
 }

3. 学生管理系统

作业: 学生管理系统

需求: (每一个功能都是使用函数进行封装) 1.实现从键盘上录入学生信息。 (姓名、性别、学号、成绩、电话号码) 2.将结构体里的学生信息全部打印出来。 3.实现根据学生的姓名或者学号查找学生,查找到之后打印出学生的具体信息。 4.根据学生的成绩对学生信息进行排序。 5.根据学号删除学生信息。

示例:

#include "stdio.h"
#include "string.h"
#include <stdlib.h>

//定义存放学生信息的结构体类型
struct StuDentInfo
{
	char Name[20]; //姓名
	int number;    //学号
	char phone[20];//电话号码
}; 

//全局变量区域
unsigned int  StuDentCnt=0; //记录已经录入的全部学生数量

//函数声明区域
void PrintStuDentInfoList(void);
void InputStuDentInfo(struct StuDentInfo*info);
void FindStuDentInfo(struct StuDentInfo*info);
void SortStuDentInfo(struct StuDentInfo*info);
void PrintStuDentInfo(struct StuDentInfo*info);

int main()
{
	struct StuDentInfo data[100]; //可以100位学生的信息
	int number;
	while(1)
	{
		PrintStuDentInfoList(); //打印功能列表
		scanf("%d",&number);
		printf("\n");
		switch(number)
		{
		case 1:
			InputStuDentInfo(data);
			break;
		case 2:
			FindStuDentInfo(data);
			break;
		case 3:
			SortStuDentInfo(data);
			break;
		case 4:
			PrintStuDentInfo(data);
			break;
		case 5:
			break;
		default:
			printf("选择错误!\n\n");
			break;
		}
	}
 	return 0;
}


void PrintStuDentInfoList(void)
{
	printf("\n--------------学生管理系统功能列表----------------\n");
	printf("1. 录入学生信息\n");
	printf("2. 根据学号查找学生信息\n");
	printf("3. 根据学号排序\n");
	printf("4. 打印所有学生信息\n");
	printf("5. 删除指定的学生信息\n");
	printf("请选择功能序号:");
}


void InputStuDentInfo(struct StuDentInfo*info)
{
	printf("输入学生姓名:");
	scanf("%s",info[StuDentCnt].Name);
	printf("输入学号:");
	scanf("%d",&info[StuDentCnt].number);
	printf("输入电话号码:");
	scanf("%s",info[StuDentCnt].phone);
	StuDentCnt++; //数量自增
}


void FindStuDentInfo(struct StuDentInfo*info)
{
	int num,i;
	printf("输入查找的学号:");
	scanf("%d",&num);
	for(i=0; i<StuDentCnt; i++)
	{
		if(info[i].number==num)
		{
			printf("信息查找成功,该学生的信息如下:\n");
			printf("姓名:%s\n",info[i].Name);
			printf("学号:%d\n",info[i].number);
			printf("电话号码:%s\n",info[i].phone);
			printf("\n");
			break;
		}
	}
	if(i==StuDentCnt)
	{
		printf("----------%d学号不存在!---------\n",num);
	}
}


void SortStuDentInfo(struct StuDentInfo*info)
{
	int i,j;
	struct StuDentInfo tmp; //保存临时信息
	for(i=0; i<StuDentCnt-1; i++)
	{
		for(j=0;j<StuDentCnt-i-1;j++)
		{
			if(info[j].number>info[j+1].number)
			{
				tmp=info[j];
				info[j]=info[j+1];
				info[j+1]=tmp;
			}
		}
	}
}


void PrintStuDentInfo(struct StuDentInfo*info)
{
	int i=0;
	printf("-----------所有学生的信息列表------------\n");
	for(i=0;i<StuDentCnt;i++)
	{
		printf("姓名:%s\n",info[i].Name);
		printf("学号:%d\n",info[i].number);
		printf("电话号码:%s\n",info[i].phone);
		printf("\n");
	}
}

附:结构体变量的存储原理

1)结构体数据成员对齐的意义

内存是以字节为单位编号的,某些硬件平台对特定类型的数据的内存要求从特定的地址开始,如果数据的存放不符合其平台的要求,就会影响到访问效率。所以在内存中各类型的数据按照一定的规则在内存中存放,就是对齐问题。而结构体所占用的内存空间就是每个成员对齐后存放时所占用的字节数之和。

计算机系统对基本数据类型的数据在内存中存放的限制是:这些数据的起始地址的值要求是某个数K的倍数,这就是内存对齐,而这个数 K 就是该数据类型的对齐模数(alignment modulus)。这样做的目的是为了简化处理器与内存之间传输系统的设计,并且能提升读取数据的速度。

结构体对齐不仅包括其各成员的内存对齐(即相对结构体的起始位置),还包括结构体的总长度。

2)结构体大小的计算方法和步骤

i. 将结构体内所有数据成员的长度值相加,记为 sum_a ;

ii. 将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到sum_a上,记为sum_b。

对齐模数是 #pragma pack 指定的数值与该数据成员自身长度相比较得到的数值较小者。该数据相对起始位置应该是对齐模数的整数倍。

iii. 将和 sum_b 向结构体模数对齐。

该模数则是 #pragma pack 指定的数值与结构体内最大的基本数据类型成员长度相比较得到的数值较小者。结构体的长度应该是该模数的整数倍。

数据类型自身对齐:

所谓“对齐在N上”,是指“存放的起始位置是%N = 0”.

总结

到此这篇关于C语言结构体(struct)的文章就介绍到这了,更多相关C语言结构体struct内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言结构体(struct)的详细讲解

本文链接: https://www.lsjlt.com/news/144528.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言结构体(struct)的详细讲解
    目录引言1. 动态内存管理2. 结构体2.1 定义语法2.2 定义示例2.3 初始化2.4 结构体赋值2.5 结构体数组2.6 结构体指针赋值3. 学生管理系统附:结构体变量的存储原...
    99+
    2024-04-02
  • C语言 struct结构体超详细讲解
    目录一、本章重点二、创建结构体三、typedef与结构体的渊源四、匿名结构体五、结构体大小六、结构体指针七、其他一、本章重点 创建结构体typedef与结构体的渊源匿名结构体结构体大...
    99+
    2024-04-02
  • C语言结构体struct详解
    目录结构体的概念结构体类型的声明结构体变量的创建typedef关键字结构体的嵌套结构体变量的初始化结构体成员的访问结构体的传参总结结构体的概念 结构体是由一系列具有相同类型或不同类型...
    99+
    2024-04-02
  • C语言结构体超详细讲解
    目录前言1、结构体的声明1.1 结构的基础知识1.2 结构的声明1.3 结构成员的类型1.4 结构体变量的定义和初始化2、结构体成员的访问2.1 点操作符访问2.2 ->操作符...
    99+
    2024-04-02
  • C语言之结构体(struct)详解
    目录为什么需要引入结构体struct定义typedef与#define结构体变量初始化及成员访问结构体访问总结为什么需要引入结构体 原有的数据类型不能满足需求,因此才设计了构造类型结...
    99+
    2024-04-02
  • C语言超详细讲解指针与结构体
    目录本节目标初识指针1、内存与地址2、变量的地址3、指针变量4、指针的使用5、指针变量的大小初识结构体1、什么是结构体2、结构体的定义3、结构体的使用本节目标 理解内存与地址的相关概...
    99+
    2024-04-02
  • C语言struct结构体介绍
    目录structstruct的嵌套实验struct C 语言没有其他语言的对象(object)和类(class)的概念,struct 结构很大程度上提供了对象和类的功能。 下面是st...
    99+
    2024-04-02
  • C语言超详细讲解结构体与联合体的使用
    目录结构体offsetof-宏位段枚举联合体(共用体)结构体 结构体内存对齐问题: 当我们在计算结构体的大小时,我们便需要清楚的知道结构体内存对齐是什么。 存在内存对齐的原因可细分为...
    99+
    2024-04-02
  • C语言结构体嵌套与对齐超详细讲解
    目录嵌套结构体结构体内存对齐32位的操作系统64位的操作系统嵌套结构体 格式:typedef struct 结构体名 {struct 结构体名1 结构体变量名1;struct 结构体...
    99+
    2022-12-26
    C语言结构体嵌套 C语言结构体对齐 C语言结构体嵌套与对齐
  • C语言之结构体定义typedef struct用法详解
    在C语言中,使用struct关键字可以定义一个结构体类型,用于存储不同类型的数据。为了方便使用,可以使用typedef关键字给结构体...
    99+
    2023-08-09
    C语言
  • C语言结构体详细图解分析
    目录结构体结构体的声明结构体变量的定义和初始化结构体大小计算结构体 结构是一些值的集合,这些值称为成员变量。结构的每个成员是不同类型的变量。 为什么要有结构体 比如说,描述一个学生时...
    99+
    2024-04-02
  • C语言的struct结构体怎么创建
    本篇内容主要讲解“C语言的struct结构体怎么创建”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言的struct结构体怎么创建”吧!一、本章重点创建结构体typedef与结构体的渊源匿名结...
    99+
    2023-06-30
  • Go语言中的Struct结构体
    一、Struct结构体 Go语言中没有像C#、Java一样的Class,只有Struct这样的结构体。Go语言使用type关键字来定义一个类型。 如下: type User stru...
    99+
    2024-04-02
  • C语言中结构体struct怎么对齐
    这篇文章主要介绍“C语言中结构体struct怎么对齐”,在日常操作中,相信很多人在C语言中结构体struct怎么对齐问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言中结构...
    99+
    2024-04-02
  • C语言结构体简单入门讲解
    结构体 定义:用于存储不同的数据类型,存储在同一块内存空间里面 关键字 struct 标签 结构体名称 成员 例如: struct student {...
    99+
    2024-04-02
  • C语言简明清晰讲解结构体
    目录本质简单使用一些写法我套我自己内存对齐举例-int char char举例-char int char举例-char char int由结构体指针访问成员本质 一些值的集合。 简...
    99+
    2024-04-02
  • Go语言结构体struct详解,Go空结构体的这些妙用你知道吗?
    本文详解了Go语言结构体的各个知识点,最后介绍了空结构体的3种妙用。希望对你有帮助。 定义 结构体,是一种自定义的数据类型,由多个数据类型组合而成。用于描述一类事物相关属性。 定义方式: typ...
    99+
    2023-09-07
    golang java 算法
  • C语言超详细讲解数据结构中的线性表
    目录前言一、分文件编写1、分文件编写概念2、代码展示二、动态分布内存malloc1、初识malloc2、使用方法三、创建链表并进行增删操作1、初始化链表2、在链表中增加数据3、删除链...
    99+
    2024-04-02
  • C语言数据结构超详细讲解单向链表
    目录1.链表概况1.1 链表的概念及结构1.2 链表的分类2. 单向链表的实现2.1 SList.h(头文件的汇总,函数的声明)2.2 SList.c(函数的具体实现逻辑)2.2.1...
    99+
    2024-04-02
  • 详解C语言中结构体的使用
    目录结构体的声明结构体成员的类型结构体成员的访问结构体的声明 结构体的定义:结构体是一些值的集合,这些值称为成员变量,结构体的每个成员可以是不同类型的变量。 举例: //定义结构体类...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作