【C语言】初阶结构体

  •  🎈个人主页:库库的里昂
  •  🎐CSDN新晋作者
  •  🎉欢迎 👍点赞✍评论⭐收藏
  •  ✨收录专栏:C语言初阶
  •  ✨其他专栏:代码小游戏
  •  🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗

【前言】

书接上回,上一章将初识指针讲完了,相信只要你将该章节读完,肯定对大部分的指针有了一定的了解,并且你肯定对指针这一重要的知识点有了个基础的认识,本章将写的内容时初阶的结构体,当你将本认真的读完,相信你肯定也会对什么是结构体、以及结构体的使用,有更深的了解。所以系好安全带,发出啦!

一、结构体的声明、定义和初始化

1.结构的基本知识

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。

说到集合,我们之前学习过的数组也是一种相同类型元素的集合,但是结构体的值的类型可以是不同的。

我们知道,在C语言中有一些基本的数据类型,如:

char  int  float  long  double 等等类型。

他们可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,这时候C提供了一种自定义数据类型,他可以封装多个基本数据类型,这种数据类型叫结构体

英文名称struct,可以使用struct关键词声明结构体

规则:

1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragmapack指定的数值和这个数据成员自身长度中,比较小的那个进行。

2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragmapack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。

3、结合1、2可推断:当#pragmapack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。

在C语言中,可以定义结构体类型,将多个相关的变量包装成为一个整体使用。在结构体中的变量,可以是相同、部分相同,或完全不同的数据类型。在C语言中,结构体不能包含函数。在面向对象的程序设计中,对象具有状态(属性)和行为,状态保存在成员变量中,行为通过成员方法(函数)来实现。C语言中的结构体只能描述一个对象的状态,不能描述一个对象的行为。

2.如何声明一个结构体类型

首先,要使用结构体就必须声明(创建) 一个结构体类型,就必须用到结构体关键字:struct

其中tag结构体标签,用来区分不同的结构体类型。struct tag表示结构体类型,声明完结构体后就可以用该类型来创建变量了。member-list:成员列表,它是结构体所包含的基本的结构类型。variable-list:表示变量列表,这个列表可写可不写,写了就代表你用上面所创建的结构体类型定义了一个该类型的变量,没写则表示你仅仅只创建了一个结构体类型
 

struct tag
{
	member-list;
}variable-list;

描述一个学生

代码示例:

typedef struct Stu
{
    char name[20];//名字
    int age;//年龄
    char sex[5];//性别
    char id[20];//学号
}Stu;//分号不能丢

这段代码表示声明了一个结构体类型名为struct stu,成员就是不同类型的成员变量。

注意:

1.若结构体声明是在mian函数之外的,那么列表后创建的结构体变量是一个全局变量
2.结构体成员变量也可以是另一个结构体类型,这种用法被称为:嵌套结构体
3.在结构体声明结束的时候,千万不要忘记{}后面是有一个的。

3.结构成员的类型


结构的成员可以是标量、数组、指针,甚至其他是结构体

小知识:

在C语言中,枚举类型字符型各种整数的表示形式统一叫做标量类型
当在C表达式中使用标量类型的值时,编译器就会自动将这些标识符转换为整数保存。
这种机制的作用是,在这些标量类型上执行的操作与整型上执行的操作完全一样。

4. 结构体变量的定义和初始化
 

声明完结构体类型,就可以用它来定义初始化结构体变量了。

注意:

结构体初始化与数组一样需要用{}

代码示例:

#include<stdio.h>
struct grade
{
	double math;
	double english;
};
struct student
{
	char name[20];//姓名
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
	struct grade;//成绩(这是一个嵌套结构体类型)
};
int main()
{
	//定义、初始化结构体类型
	struct student ly = {"王二", 23, "男", "2117305789", {98.5, 66.0}};
	return 0;
}

不知道大家在用结构体类型定义一个变量时,有没有觉得结构体的类型名太长了。其实可以通过typedef来重定义结构体的类型名,如下所示:

typedef struct student
{
	char name[20];//姓名
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
	struct grade;//成绩(这是一个嵌套结构体类型)
}stu;

注意这里的stu并不是创建的变量,而是对于struct student的重命名。之后我们既可以用stu来创建变量也可以用struct student来创建。

二、结构体成员的访问

1.结构体变量访问成员

结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。

例如:

 我们可以看到 s 有成员 nameage


那我们如何访问s的成员?

代码示例:

struct S s;
strcpy(s.name, "zhangsan");//使用.访问name成员
s.age = 20;//使用.访问age成员

2.结构体指针访问指向变量的成员

有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针

那该如何访问成员?

代码示例:

#include<stdio.h>
struct Stu
{
    char name[20];
    int age;
};
void print(struct Stu* ps)
{
    printf("name = %s  age = %d\n", (*ps).name, (*ps).age);
    //使用结构体指针访问指向对象的成员
    printf("name = %s  age = %d\n", ps->name, ps->age);
}
int main()
{
    struct Stu s = {"zhangsan", 20};
    print(&s);//结构体地址传参
    return 0;
}

三、结构体传参

结构体做函数参数有传递结构体传地址

代码示例:

struct S
{
    int data[1000];
    int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{
    printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
    printf("%d\n", ps->num);
}
int main()
{
    print1(s);  //传结构体
    print2(&s); //传地址
    return 0;
}

你觉得上面的 print1print2 函数哪个好些?

答案是:首选print2函数

原因

函数传参的时候,参数是需要压栈的。
如果传递一个结构体对象的时候,结构体过大参数压栈的的系统开销比较大,所以会导致性能的下降

结论

结构体传参的时候,要传结构体的地址

今天的初阶结构体分享到这里啦,期待博主下一篇文章吧!😘

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/59045.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

P14 电路定理——巧妙-灵性-智慧

1、替代定理 图示表示&#xff1a; 叠加定理和齐性定理只能用于线性电路&#xff0c;但是替代定理无论线不线性都可以用。 常见的&#xff1a;线性电路将某复杂支路等效成电压源或电流源之后&#xff0c;就可以使用叠加原理了。 引入两个相互抵消的电压源&#xff0c;拿其中一…

基于STM32设计的智能空调

一、项目背景 随着人们生活水平的不断提高&#xff0c;对居住环境的舒适度要求也越来越高。空调作为一种重要的家电设备&#xff0c;已经成为了现代家庭中必不可少的一部分。本文介绍了一种基于STM32的智能空调设计方案&#xff0c;可以自动地根据环境温度进行温度调节。 二、…

Opencv-C++笔记 (15) : 像素重映射 与 图像扭曲

文章目录 一、重映射简介二、图像扭曲 一、重映射简介 重映射&#xff0c;就是把一幅图像中某位置的像素放置到另一图像指定位置的过程。即&#xff1a; 在重映射过程中&#xff0c;图像的大小也可以同时发生改变。此时像素与像素之间的关系就不是一一对应关系&#xff0c;因…

PHP从入门到精通—PHP开发入门-PHP概述、PHP开发环境搭建、PHP开发环境搭建、第一个PHP程序、PHP开发流程

每开始学习一门语言&#xff0c;都要了解这门语言和进行开发环境的搭建。同样&#xff0c;学生开始PHP学习之前&#xff0c;首先要了解这门语言的历史、语言优势等内容以及了解开发环境的搭建。 PHP概述 认识PHP PHP最初是由Rasmus Lerdorf于1994年为了维护个人网页而编写的一…

租赁类小程序定制开发|租赁管理系统源码|免押租赁系统开发

随着互联网的发展&#xff0c;小程序成为了一种重要的移动应用开发方式。租赁小程序作为其中的一种类型&#xff0c;可以为很多行业提供便利和创新。下面我们将介绍一些适合开发租赁小程序的行业。   房屋租赁行业&#xff1a;租房小程序可以帮助房东和租户快速找到合适的租赁…

对当下AI的一些观感思考

目前来看&#xff0c;AI技术地震的震中还是在美帝那旮瘩。尤其是M7&#xff0c;这几家市值加总快15万亿美元了&#xff0c;个个都是行业翘楚&#xff0c;个个都有拿得出手的东西。AI是个技术密集、人才密集、计算密集的产业。美帝拥有全球一流的顶尖人才&#xff0c;以及财力、…

IntelliJ IDEA 2023.2社区版插件汇总

参考插件帝&#xff1a;https://gitee.com/zhengqingya/java-developer-document 突发小技巧&#xff1a;使用插件时要注意插件的版本兼容性&#xff0c;并根据自己的实际需求选择合适的插件。同时&#xff0c;不要过度依赖插件&#xff0c;保持简洁和高效的开发环境才是最重要…

2023下半年软考初级程序员报名入口-报名流程-备考方法

软考初级程序员2023下半年考试时间&#xff1a; 2023年下半年软考初级程序员的考试时间为11月4日、5日。考试时间在全国各地一致&#xff0c;建议考生提前备考。共分两科&#xff0c;第一科基础知识考试具体时间为9:00到11:30&#xff1b;第二科应用技术考试具体时间为2:00到4…

STM32 低功耗-睡眠模式

STM32 睡眠模式 文章目录 STM32 睡眠模式第1章 低功耗模式简介第2章 睡眠模式简介2.1 进入睡眠模式2.1 退出睡眠模式 第3章 睡眠模式代码示例总结 第1章 低功耗模式简介 在 STM32 的正常工作中&#xff0c;具有四种工作模式&#xff1a;运行、睡眠、停止和待机模式。 在系统或…

小白到运维工程师自学之路 第六十四集 (dockerfile构建tomcat、mysql、lnmp、redis镜像)

一、tomcat&#xff08;更换jdk&#xff09; mkdir tomcat cd tomcat/ tar xf jdk-8u191-linux-x64.tar.gz tar xf apache-tomcat-8.5.40.tar.gzvim Dockerfile FROM centos:7 MAINTAINER Crushlinux <syh163.com> ADD jdk1.8.0_191 /usr/local/java ENV JAVA_HOME /us…

AcWing257. 关押罪犯(二分图+染色法)

输入样例&#xff1a; 4 6 1 4 2534 2 3 3512 1 2 28351 1 3 6618 2 4 1805 3 4 12884输出样例&#xff1a; 3512 解析&#xff1a; 二分&#xff0c;每次查看是否是二分图 #include<bits/stdc.h> using namespace std; typedef long long ll; const int N2e45,M2e55…

《Spring Boot源码解读与原理分析》书籍推荐

Spring Boot 1.0.0 早在2014年就已经发布&#xff0c;只不过到了提倡“降本增效”的今天&#xff0c;Spring Boot才引起了越来越多企业的关注。Spring Boot是目前Java EE开发中颇受欢迎的框架之一。依托于底层Spring Framework的基础支撑&#xff0c;以及完善强大的特性设计&am…

使用 Go 语言实现二叉搜索树

原文链接&#xff1a; 使用 Go 语言实现二叉搜索树 二叉树是一种常见并且非常重要的数据结构&#xff0c;在很多项目中都能看到二叉树的身影。 它有很多变种&#xff0c;比如红黑树&#xff0c;常被用作 std::map 和 std::set 的底层实现&#xff1b;B 树和 B 树&#xff0c;…

前端实现打印1 - 使用 iframe 实现 并 分页打印

目录 打印代码对话框预览打印预览 打印代码 <!-- 打印 --> <template><el-dialogtitle"打印":visible.sync"dialogVisible"width"50%"top"7vh"append-to-bodyclose"handleClose"><div ref"print…

uni-app uView自定义底部导航栏

因项目需要自定义底部导航栏&#xff0c;我把它写在了组件里&#xff0c;基于uView2框架写的&#xff08;vue2&#xff09;&#xff1b; 一、代码 在components下创建tabbar.vue文件&#xff0c;代码如下&#xff1a; <template><view><u-tabbar :value"c…

推荐一款非常简单实用的数据库连接工具Navicat Premium

Navicat Premium是一款非常实用的数据库连接工具&#xff0c;别再用HeidiSQL和idea自带的数据库连接了&#xff0c;看完这篇文章&#xff0c;赶紧把Navicat Premium用起来吧。 首先&#xff0c;需要获取Navicat Premium的安装包&#xff0c;可以通过以下网盘链接下载&#xff0…

刷题笔记 day5

力扣 202 快乐数 首先来分析什么样的数是快乐数&#xff0c; 解题思路&#xff1a; 1&#xff09;定义快慢指针 &#xff1b; 2&#xff09;快指针走两步&#xff0c;慢指针走一步 &#xff1b;3&#xff09;两个指针相遇时判断相遇的数值是否为1。 怎样处理 取各分位数的平…

力扣初级算法(二分查找)

力扣初级算法(二分法)&#xff1a; 每日一算法&#xff1a;二分法查找 学习内容&#xff1a; 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 2.二分查找流程&…

SystemVerilog scheduler

文章目录 简介调度器simulation regionPreponed regionActive regionInactive regionNBA(Non-blocking Assignment Events region)Observed regionReactive regionRe-Inactive Events regionRe-NBA RegionPostponed Region PLI region:Pre-active regionPre-NBA regionPost-NBA…

常见的设计模式(超详细)

文章目录 单例模式饿汉式单例模式懒汉式单例模式双重检索单例模式 工厂模式简单工厂模式工厂&#xff08;方法&#xff09;模式抽象工厂模式 原型模式代理模式 单例模式 确保一个类只有一个实例&#xff0c;并且自行实例化并向整个系统提供这个实例。 饿汉式单例模式 饿汉式单…