iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言全面梳理结构体知识点
  • 923
分享到

C语言全面梳理结构体知识点

2024-04-02 19:04:59 923人浏览 泡泡鱼
摘要

目录一、什么是结构体二、结构体的定义三、结构体变量的定义四、结构体变量的初始化五、结构体变量的赋值六、引用结构体变量中的成员七、结构体变量的传参问题八、传输地址带来的问题九、动态结构

一、什么是结构体

为了更好地模拟现实,需要把各种基本数据类型组合在一起构成一种新的复合数据类型,我们把这种自定义的数据类型称为结构体。结构体是程序员根据实际需求,把各种基本数据类型组合在一起构成的一种新的复合数据类型。

二、结构体的定义

结构体的定义方式共有3种,这里只用最常见也最常用的一种方式定义,即:

struct 结构体名
{
    成员列表;
}; // 注意这里的分号不能省略

举个例子:

struct Student
{
	int age;
	float score;
	char gender;
};

三、结构体变量的定义

结构体与我们经常使用的基本数据类型一样,它也是一种数据类型,所以我们可以用这一数据类型定义其对应的变量,我们把用结构体类型定义的变量称为结构体变量。定义结构体变量的方式如下所示:

#include <stdio.h>
struct Student // 定义结构体
{
	int age;
	float score;
	char gender;
};
int main()
{
	struct Student stu; // 定义结构体变量
	return 0;
}

四、结构体变量的初始化

#include <stdio.h>
struct Student // 定义结构体
{
	int age;
	float score;
	char gender;
};
int main()
{
	struct Student stu = { 15, 66.5, 'M' }; // 初始化结构体变量
	return 0;
}

五、结构体变量的赋值

定义结构体变量后,我们可以对其中的成员进行赋值操作,但与初始化不同的是,需要通过结构体变量名.成员名的方式对结构体变量中的每个成员单独赋值。代码如下所示

#include <stdio.h>
struct Student // 定义结构体
{
	int age;
	float score;
	char gender;
};
int main()
{
	struct Student stu; // 定义结构体变量
	stu.age = 15; 		// 对结构体变量中的age成员赋值
	stu.score = 66.5;	// 对结构体变量中的score成员赋值
	stu.gender = 'M';	// 对结构体变量中的gender成员赋值
	return 0;
}

六、引用结构体变量中的成员

方法1:结构体变量名.成员名

#include <stdio.h>
struct Student // 定义结构体
{
	int age;
	float score;
	char gender;
};
int main()
{
	struct Student stu;  // 定义结构体变量
	// 对各成员赋值
	stu.age = 15;
	stu.score = 66.5;
	stu.gender = 'M';
	printf("%d %f %c\n", stu.age, stu.score, stu.gender); // 输出各成员的内容
	return 0;
}

方法2:结构体指针变量名->成员名

#include <stdio.h>
struct Student // 定义结构体
{
	int age;
	float score;
	char gender;
};
int main()
{
	struct Student stu;  // 定义结构体变量
	struct Student * pStu = &stu; //定义结构体指针变量
	// 对各成员赋值
	pStu->age = 15;
	pStu->score = 66.5;
	pStu->gender = 'M';
	printf("%d %f %c\n", stu.age, stu.score, stu.gender); // 输出各成员的内容
	return 0;
}

方法3:(*结构体指针变量名).成员名

#include <stdio.h>
struct Student // 定义结构体
{
	int age;
	float score;
	char gender;
};
int main()
{
	struct Student stu; //定义结构体变量
	struct Student * pStu = &stu; //定义结构体指针变量
	// 对各成员赋值
	(*pStu).age = 15;
	(*pStu).score = 66.5;
	(*pStu).gender = 'M';
	printf("%d %f %c\n", stu.age, stu.score, stu.gender); // 输出各成员的内容
	return 0;
}

七、结构体变量的传参问题

当我们在一个函数中定义了结构体变量,而想要在另外一个函数中对该结构体变量进行操作时,则需要向被调用的函数传递参数,那传递结构体变量作为参数还是应该传递结构体指针变量作为参数呢?这是一个必须要搞清楚的问题。我以下面的程序为例阐述不同情况下的传参问题:

#include <stdio.h>
#include <string.h>
struct Student // 定义结构体
{
	int age;
	float score;
	char name[100];
};
// 函数声明
void input_student(struct Student* pStu);
void output_student(struct Student* pStu);
int main()
{
	struct Student stu; // 定义结构体变量
	input_student(&stu);	// 传递地址的原因详见该程序下方
	output_student(&stu);	// 传递地址的原因详见该程序下方
	return 0;
}
// 赋值函数
void input_student(struct Student * pStu)
{
	(*pStu).age = 10;
	pStu->score = 66.5;
	strcpy(pStu->name, "南森"); 
	
}
// 输出函数
void output_student(struct Student* pStu)
{
	printf("%d %f %s\n", (*pStu).age, pStu->score, pStu->name);
}

为什么要传递地址?由于input_student函数要修改主函数中结构体变量stu各个成员的值,所以只能传输地址,不能传输变量stu,我已经在《C语言之指针知识大总结》这篇文章中详细叙述了其中的原因。而output_student函数并不需要修改主函数中结构体变量stu各个成员的值,所以此时是可以传输变量stu的,但由于变量stu的类型是结构体类型,其所占字节数较多,而所有的指针变量都只有四个字节,所以为了减少内存耗用并提高数据传输的效率,往往传输对应的结构体指针变量。

八、传输地址带来的问题

向一个函数传入某个变量的地址不仅可以修改该变量的值,而且可以提高数据传输效率,但这样做也会有一定的风险。例如上一小结中的程序,其中的output_student函数作为输出函数并不需要在其内部修改变量的值,而一旦传入变量的地址,那就意味着output_student函数也可以对该地址所对应的变量进行修改,这样就导致output_student这个函数非常不安全,那怎么样才能实现既可以快速传输数据,又可以在不需要修改变量值的函数中禁止该函数修改数据呢?答案很简单,只需要在形参的指针变量前加上关键字const就可以达到这样的目的。如下所示:

void output_student(const struct Student* pStu)
{
	pStu->score = 88; // 错误,因为指针变量pStu前有const修饰,无法修改其对应的普通变量的值
	(*pStu).age = 10; // 错误,因为指针变量pStu前有const修饰,无法修改其对应的普通变量的值
	printf("%d %f %s\n", (*pStu).age, pStu->score, pStu->name);
}

九、动态结构体数组

#include <stdio.h>
#include <malloc.h>
// 定义结构体
struct Student
{
	char name[100];
	int age;
	float score;
};
// 函数声明
int create_array(struct Student**);
void input_array(struct Student*, int);
void bubble_sort(struct Student*, int);
void print(struct Student*, int);
int main()
{
	int length;
	struct Student* pStu;
	length = create_array(&pStu); // 由于要对指针变量pStu的内容进行修改,所以只能传输其地址
	input_array(pStu, length);
	bubble_sort(pStu, length);
	print(pStu, length);
	return 0;
}
// 该函数的作用是分配内存并构造数组
int create_array(struct Student** q) // 由于需要接收一级指针变量,所以这里需要使用二级指针
{
	int length;
	printf("请输入学生人数:");
	scanf("%d", &length);
	printf("\n");
	*q = (struct Student*)malloc(sizeof(struct Student) * length); // 动态分配内存构造结构体数组
	return length;
}
// 该函数的作用是对结构体数组中的各元素进行赋值
void input_array(struct Student* p, int length)
{
	int i;
	for (i = 0; i < length; i++)
	{
		printf("请输入第%d个学生的信息:\n", i + 1);
		printf("姓名:");
		scanf("%s", (p + i)->name);
		printf("年龄:");
		scanf("%d", &(*(p + i)).age);
		printf("成绩:");
		scanf("%f", &p[i].score);
		printf("\n");
	}
}
// 该函数的作用是按照结构体数组中的score成员从低到高进行冒泡排序
void bubble_sort(struct Student* p, int length)
{
	int i, j;
	struct Student t;
	for (i = 1; i < length; i++)
		for (j = 0; j < length - i; j++)
			if (p[j].score > p[j + 1].score)
			{	
				// 注意:比较的是score的大小,但是需要交换的是结构体数组中元素的位置,而不是只交换成员score
				t = p[j];
				p[j] = p[j + 1];
				p[j + 1] = t;
			}
}
// 该函数的作用是输出结构体数组中各元素的内容
void print(struct Student* p, int length)
{
	int i;
	printf("按照分数由低到高排序的结果为:\n");
	for (i = 0; i < length; i++)
	{
		printf("姓名:%s\n", (p + i)->name);
		printf("年龄:%d\n", (*(p + i)).age);
		printf("成绩:%f\n", p[i].score);
		printf("\n");
	}
}

十、关键字typedef

typedef关键字的作用是对数据类型起别名。例如:

#include <stdio.h>
typedef int INTEGER; // 给int取了个别名叫INTEGER,故INTEGER就等同于int
int main()
{
	INTEGER i = 10; // 等同于 int i = 10;
	return 0;
}
#include <stdio.h>
typedef struct Student
{
	char name[100];
	int age;
	float score;
}ST, * PST; // 给 struct Student 起了个别名ST,给 struct Student * 起了个别名叫PST
int main()
{
	ST stu;		// 等同于 struct Student stu;
	PST pStu;	// 等同于 ST * pStu; 也等同于 struct Student * pStu;
	return 0;
}

十一、C++中的引用

使用C++中的引用在向其它函数传参时可以帮助我们提高编码效率,严蔚敏老师在《数据结构》这本书中也多次使用了C++中的引用。

传输普通变量

C语言实现普通变量的传输:

#include <stdio.h>
void modify(int* p)
{
	(*p)++;
}
int main()
{
	int i = 10;
	modify(&i);
	printf("%d\n", i);
	return 0;
}

C++语言实现普通变量的传输:

#include <stdio.h>
void modify(int& i)
{
	i++;
}
int main()
{
	int i = 10;
	modify(i);
	printf("%d\n", i);
	return 0;
}

传输指针变量

C语言实现指针变量的传输:

#include <stdio.h>
#include <malloc.h>
void modify(int** q)
{
	*q = (int *)malloc(sizeof(int));
}
int main()
{
	int * p;
	modify(&p);
	return 0;
}

C++语言实现指针变量的传输:

#include <stdio.h>
#include <malloc.h>
void modify(int*& p)
{
	p = (int *)malloc(sizeof(int));
}
int main()
{
	int * p;
	modify(p);
	return 0;
}

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

--结束END--

本文标题: C语言全面梳理结构体知识点

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

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

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

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

下载Word文档
猜你喜欢
  • C语言全面梳理结构体知识点
    目录一、什么是结构体二、结构体的定义三、结构体变量的定义四、结构体变量的初始化五、结构体变量的赋值六、引用结构体变量中的成员七、结构体变量的传参问题八、传输地址带来的问题九、动态结构...
    99+
    2022-11-13
  • C语言数组全面总结梳理
    目录一,一维数组1.创建和初始化2.使用下标访问3.在内存中的存储二,二维数组 1.创建和初始化2.使用下标访问3.在内存中的存储三,越界问题数组(array)是由一系列类...
    99+
    2022-11-13
  • C语言结构体的全方面解读
    目录前言一、结构体的声明与定义1.结构体的声明2.结构成员的类型3.结构体的定义二、初始化结构体三、访问结构体成员四、结构体嵌套五、结构体指针六、结构体传参总结前言 C语言提供了不同...
    99+
    2022-11-12
  • R语言控制结构知识点总结
    if(condition) true_expression else false_expression if(condition) expression ...
    99+
    2022-11-11
  • C语言超全面覆盖操作符知识点
    目录算术操作符移位操作符位操作符赋值操作符单目操作符关系操作符逻辑操作符条件操作符算术操作符 主要是 (+ - * / %) 五种算数操作符。 1、除了 % 操作符之外,其他的几个操...
    99+
    2022-11-13
  • C语言入门篇--初识结构体
    目录1.为什么要有结构体2.结构体的定义2.1结构体类型的定义2.2定义结构体普通变量及访问2.3定义结构体指针变量及访问1.为什么要有结构体 (1)之前int、char等类型描述的...
    99+
    2022-11-12
  • 深入浅出理解C语言初识结构体
    目录1.定义和使用结构体变量结构体的基础知识自己建立结构体类型struct 结构体名类型名 成员名:声明结构体的形式结构体的初始化  2. 结构体成员的访问3.结构体传参1...
    99+
    2022-11-13
  • 全面梳理下CSS盒模型的相关知识点
    CSS 盒模型是 CSS 基础的重点难点,因此常被面试官们拿来考察候选人对前端基础的掌握程度,这篇文章将对 CSS 盒模型知识点进行全面的梳理。我们先看个例子:下面的 div 元素的总宽度是多少呢?<!DOCTYPE html>...
    99+
    2023-05-14
    css 前端 JavaScript 面试
  • C语言全面梳理文件操作方法
    目录1.什么是文件1.1程序文件1.2数据文件1.3文件名2.为什么使用文件3.文件的打开和关闭3.1文件指针3.2文件的打开和关闭4.文件的顺序读写什么是流5.文件的随机读写5.1...
    99+
    2022-11-13
  • C语言自定义类型超详细梳理之结构体枚举联合体
    目录一、什么是结构体1.结构体实现2.匿名结构体类型3.结构体自引用4.结构体的内存对齐5.结构体位段 二、什么是枚举1.枚举类型的定义2.枚举的优点三、联合(共用体)1.什么是联合...
    99+
    2022-11-13
  • C语言线性表全面梳理操作方法
    线性表:零个或多个数据元素的有限序列 强调几点: 首先它是一个序列。也就是说,元素之间是有顺序的,若元素存在多个,则第一个元素无前驱,最后一个元素无后继,其他都有一个前驱和后继。其次...
    99+
    2022-11-13
  • c语言中main函数用法及知识点总结
    1、main函数是C程序的入口函数,即程序的执行从main函数开始,其他函数的调动也直接或间接地在main函数中调用。 2、main函数的返回值用于解释程序的退出状态。 若返回0,则...
    99+
    2022-11-12
  • Go语言数据结构之二叉树必会知识点总结
    目录前言二叉树概念二叉树的性质创建二叉树树的遍历前序遍历(V-L-R)中序遍历(L-V-R)后序遍历(L-R-V)前言 如果你是一个开发人员,或多或少对树型结构都有一定的认识,我个人...
    99+
    2022-11-11
  • R语言学习Rcpp基础知识全面整理
    目录1. 相关配置和说明2. 常用数据类型3. 常用数据类型的建立4. 常用数据类型元素访问5. 成员函数6. 语法糖6.1 算术和逻辑运算符6.2. 常用函数7. STL7.1. ...
    99+
    2022-11-12
  • C语言详解热门考点结构体内存对齐
    目录一、为什么存在内存对齐二、如何计算?(考点)三、手撕代码一、为什么存在内存对齐         大...
    99+
    2022-11-13
  • C语言中你容易忽略的知识点与技巧总结
    目录‍♀️前言字符串常量输出函数puts除法运算的商和余数除法运算的结果有关赋值double类型的运算数据类型和运算总结‍♀️前言 大家有没有一种感觉,随着一门编程语...
    99+
    2022-11-13
  • C语言热门考点结构体与内存对齐详解
    目录一、引例二、小试牛刀三、嵌套结构体的特殊情况四、关于为什么存在内存对齐1.平台原因(移植原因): 2.性能原因: 总结一、引例 到底什么是结构体内存对齐,我们用一段代码来介绍一下...
    99+
    2022-11-12
  • C语言结构体中内存对齐的问题理解
    目录前言思考结构体在内存中开辟空间时内存对齐的规则为什么存在内存对齐1.平台的原因2.性能的原因前言 学C的同学应该知道~ 想精通C语言就不得不面对—指针与内存 续上次指...
    99+
    2022-11-13
  • C语言联合体Union特点及运用全面讲解教程
    目录前言一、联合(共用体)定义二、联合的特点及运用三、联合的大小计算总结前言 上一期C语言快速入门我们学习了枚举类型及相关知识点 这期我们来跟着笔者学习一下联合体相关知识,相信聪明的...
    99+
    2022-11-12
  • C语言结构体链表和指针实现学生管理系统
    目录一、需求分析二、整体设计三、详细设计学生档案管理子系统学生成绩管理子系统四、代码实现本文实例为大家分享了C语言结构体链表和指针实现学生管理系统的具体代码,供大家参考,具体内容如下...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作