C++学习 结构体

news2024/11/25 5:02:15

目录

结构体

结构体定义和使用

结构体数组

结构体指针

结构体嵌套结构体

结构体做函数的参数

结构体中const使用场景


结构体

结构体定义和使用

定义:

        结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。

语法:

        struct 结构体名称 

        {

               结构体成员列表

        }; (struct 关键字不可省略)

创建结构体实例的三种方式:   推荐使用第一种、第二种。我个人喜欢使用第一种

        ① struct 结构体名 变量名; 

         eg: struct Student s1;    (struct 关键字可省略)。

        ② struct 结构体名 变量名 = {成员值1,成员值2...}

         eg: struct Student s2 ={ "李四",20, 95}; (struct 关键字可省略)。

        

        ③定义结构体时创建结构体变量

        eg: struct Student{ string name;int age;int score;} s3;

成员访问方式:

        结构体变量.属性名,点出来。

#include <iostream>
using namespace std;

// 结构体
// 需求:创建学生类型(姓名、年龄、成绩)的结构体

// 结构体定义(自定义的包含多种数据类型的类型集合)
struct Student
{
    // 姓名
    string name;
    // 年龄
    int age;
    // 成绩
    int score;
};

int main()
{
    // 创建具体学生的三种方式
    // 第①种 习惯使用第一种 创建结构体时 struct关键字可以省略(定义结构体时不可以省略(代码第8行),定义变量时可以省略(代码第22、30、37行可省略struct关键字))
    struct Student s1;
    // s1属性赋值
    s1.age = 10;
    s1.name = "张三";
    s1.score = 100;
    cout << "姓名 :" << s1.name << "  年龄 :" << s1.age << "  成绩:" << s1.score << endl;

    // 第②种 struct Student s2={...}
    struct Student s2 =
        {
            "李四",
            20,
            95};
    cout << "姓名 :" << s2.name << "  年龄 :" << s2.age << "  成绩:" << s2.score << endl;
    // 第③种 在定义结构体时创建结构体变量 不推荐使用原因:定义时变给了实例 如果代码比较长或者看其他同事代码,有时忽然看到一个s3还要去找这个结构体在哪里定义的
    // struct Student
    // {
    //     // 姓名
    //     string name;
    //     // 年龄
    //     int age;
    //     // 成绩
    //     int score;
    // } s3;
    // s3.age = 30;
    // s3.name = "王五";
    // s3.score = 90;
    // cout << "姓名 :" << s3.name << "  年龄 :" << s3.age << "  成绩:" << s3.score << endl;
    return 0;
}

 

结构体数组

作用:

        将自定义的结构体放入到数组中方便维护。

语法:

        struct 结构体名 数组名[元素个数] = { {},{},...{}};

#include <iostream>
using namespace std;

// 结构体

// 结构体数组
// 需求:结构体定义->创建结构体数组->结构体数组赋值->遍历结构体数组

// ① 结构体定义
struct Student
{
    // 姓名
    string name;
    // 年龄
    int age;
    // 成绩
    int score;
};

int main()
{
    // ② 创建结构体数组 ③ 结构体数组赋值 这里使用第二种方式直接定义时进行赋值。也可以定义完 stuArr[i].属性 进行逐一赋值(i为数组长度-1)
    struct Student stuArr[3] =
        {
            {"张三", 18, 100},
            {"李四", 20, 95},
            {"王五", 25, 90}};
            
    // ④ 遍历结构体数组
    for (int i = 0; i < sizeof(stuArr) / sizeof(stuArr[0]); i++)
    {
        cout << "姓名 :" << stuArr[i].name << "  年龄 :" << stuArr[i].age << "  成绩:" << stuArr[i].score << endl;
    }
    return 0;
}

 

结构体指针

作用:

        通过指针访问结构体中成员。

        利用操作符 ->可以通过结构体指针访问结构体属性。

#include <iostream>
using namespace std;

// 结构体

// 结构体指针

// 结构体定义
struct Student
{
    // 姓名
    string name;
    // 年龄
    int age;
    // 成绩
    int score;
};

int main()
{
    // 创建学生结构体变量
    Student s1 = {"张三", 20, 100};
    // 通过指针指向结构体变量
    Student *p = &s1;
    // 通过指针访问结构体变量数据
    cout << "姓名 :" << p->name << "  年龄 :" << p->age << "  成绩:" << p->score << endl;
    return 0;
}

结构体嵌套结构体

作用:

        结构体成员为结构体。

        eg:老师与学生的关系。

#include <iostream>
using namespace std;

// 结构体

// 结构体嵌套结构体

// 学生结构体定义
struct Student
{
    // 姓名
    string name;
    // 年龄
    int age;
    // 成绩
    int score;
};

// 老师结构体定义
struct Teacher
{
    // 职工编号
    int id;
    // 姓名
    string name;
    // 年龄
    int age;
    // 老师对应的学生
    struct Student stu;
};

int main()
{
    // 属性赋值两种方式
    // 第一种
    //  // 创建学生
    // Student s;
    // s.name = "张三";
    // s.age = 18;
    // s.score = 100;
    // // 创建老师
    // Teacher t;
    // t.name = "张老师";
    // t.age = 30;
    // t.id = 1;
    // t.stu = s;

    // 第二种
    Teacher t;
    t.name = "张老师";
    t.age = 30;
    t.id = 1;
    t.stu.name = "李四";
    t.stu.age = 20;
    t.stu.score = 98;

    // 通过指针访问结构体变量数据
    cout << "职工编号 :" << t.id << "   姓名:" << t.name << "  年龄:" << t.age
         << "   教的学生的姓名:" << t.stu.name << "   教的学生的年龄:" << t.stu.age << "   教的学生的分数:" << t.stu.score << endl;
    return 0;
}

 

结构体做函数的参数

作用:

        将结构体作为参数向函数中传递。

传递方式:

  • 值传递
  • 地址传递

 

#include <iostream>
using namespace std;

// 结构体

// 结构体做函数的参数
// 场景: 将学生作为参数传入,打印学生信息

// 学生结构体定义
struct Student
{
    // 姓名
    string name;
    // 年龄
    int age;
    // 成绩
    int score;
};

// 打印学生信息
// 1. 值传递 当形参发生改变时传递的实参会不受到影响
void printStu(struct Student s)
{
    cout << "值传递"
         << "学生的姓名:" << s.name << "   学生的年龄:" << s.age << "   学生的分数:" << s.score << endl;
}
// 2. 地址传递 之前讲过 当形参发生改变时传递的实参会受到影响跟着改变
void printStu2(struct Student *s)
{
    cout << "地址传递"
         << "学生的姓名:" << s->name << "   学生的年龄:" << s->age << "   学生的分数:" << s->score << endl;
}

int main()
{
    // 创建结构体变量
    Student stu;
    stu.name = "张三";
    stu.age = 18;
    stu.score = 100;

    // 将学生作为参数传入
    // 1. 值传递
    printStu(stu);
    // 2. 地址传递
    printStu2(&stu);
    // 打印学生信息
    // cout<< "学生的姓名:" << stu.name << "   学生的年龄:" << stu.age << "   学生的分数:" << stu.score << endl;
    return 0;
}

 

 这里面强调一下 :

  • 值传递 当形参发生改变时传递的实参会不受到影响。
  • 地址传递 之前讲过 当形参发生改变时传递的实参会受到影响跟着改变。

自行动手测试:

        可以在打印里面对学生的属性进行部分修改,在main中验证实参是否受到影响。

结构体中const使用场景

作用:

        用const防止误操作(只读)。

什么时候使用:        

         在参数进行值传递时,实际是进行了一次参数的拷贝,如果属性过多会造成内存溢出,所以我们通过地址传递可以节省内存空间,因为一个指针只占用四个字节,但是指针指向的是实参数据对应的内存地址,也就是同一块内存区域,这就存在我们前面所说的形参的改变影响到实参,有没有什么方法可以避免呢? 答案就是const,通过使用const修饰参数,参数变不可修改,否则编译报错。

 

#include <iostream>
using namespace std;

// 结构体

// 结构体中const使用场景

// 背景: 在参数进行值传递时,实际是进行了一次参数的拷贝,如果属性过多会造成内存溢出
// 所以我们通过地址传递可以节省内存空间,因为一个指针只占用四个字节,但是指针指向的是实参数据对应的内存地址,也就是同一块内存区域
// 这就存在我们前面所说的形参的改变影响到实参,有没有什么方法可以避免呢? 答案就是const

// 学生结构体定义
struct Student
{
    // 姓名
    string name;
    // 年龄
    int age;
    // 成绩
    int score;
};

// 2. 地址传递 之前讲过 当形参发生改变时传递的实参会受到影响跟着改变 现在通过const修饰,函数功能为只读时使用。
void printStu2(const Student *s)
{
    // s->age = 100; 编译报错 assignment of member 'Student::age' in read-only object s->age = 100;
    cout << "地址传递"
         << "学生的姓名:" << s->name << "   学生的年龄:" << s->age << "   学生的分数:" << s->score << endl;
}

int main()
{
    // 创建结构体变量
    Student stu;
    stu.name = "张三";
    stu.age = 18;
    stu.score = 100;

    // 将学生作为参数传入
    // 2. 地址传递
    printStu2(&stu);
    // 打印学生信息
    // cout<< "学生的姓名:" << stu.name << "   学生的年龄:" << stu.age << "   学生的分数:" << stu.score << endl;
    return 0;
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day4 qtqtqtc++

cppcpp ui代码 <?xml version"1.0" encoding"UTF-8"?> <ui version"4.0"><class>Widget</class><widget class"QWidget" name"Widget"><property name"geometry"><rec…

Linux--获取与杀死当前进程PID

获取当前进程的代码&#xff1a; #include <sys/types.h>pid_t idgetpid();//获取的是自己的进程PID 杀死当前进程的指令&#xff1a; kill -9 进程的PID 我要是kill -9 16865(-bash进程)&#xff0c;你会发现无论你输入clear、ls、还是vim...指令&#xff0c;都无…

云深处绝影四足机器人协议学习解析

绝影四足机器人通信协议学习解析 本学习文档介绍了云深处 绝影X20 四足机器人的通信协议&#xff0c;并对相关的通信机制和命令格式进行了简单的解析。该协议在机器人系统和上位机&#xff08;例如外部板卡或系统&#xff09;之间进行TCP通信时使用。 1. 协议端口号 在此协议…

定义一个派生自D1的D2类,并且在D2中覆盖pvf();建立一个D2类的对象并且调用f()、vf()、pvf()

运行代码&#xff1a; //定义一个派生自D1的D2类&#xff0c;并且在D2中覆盖pvf() //建立一个D2类的对象并且调用f()、vf()、pvf() #include"std_lib_facilities.h" //---------------------------------------------------------------------- //定义B1类。 class …

配置通过域名访问网站(NETBASE第七课)

1 DNS服务器 域名系统_百度百科 域名和与之相对应的IP地址转换的服务器 DNS&#xff08;Domain Name Server&#xff0c;域名服务器&#xff09;是进行域名(domain name)和与之相对应的IP地址 (IP address)转换的服务器。DNS中保存了一张域名(domain name)和与之相对应的IP地…

通过GitHub Desktop,将本地项目上传到gitee上

介绍 这里主要介绍&#xff0c;通过 gitHub Desktop 软件&#xff0c;将本地的项目&#xff0c;上传到 gitee的仓库里&#xff08;这里仓库为新建的仓库&#xff0c;什么东西都没有&#xff09;。 这里主要介绍&#xff0c;仓库的新建方式&#xff0c;及本地代码上传到远端的操…

Unity 实现一个揭面膜效果

源码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;

【Django】列表页面的搜索功能

目的 页面列表增加多字段搜索显示查询结果 方案 分页显示搜索结果 效果 实现 列表页面 # list.html <div class"pull-left" style"margin-bottom: 10px"><form action"{% url api-search %}" method"get"><div …

ModaHub魔搭社区:开源向量数据库的Milvus怎么读?

Milvus是一个中文词语,意为“Milvus navigate,为智慧找方向,为价值做链接,为创作者做伙伴”。在读这个词语时,可以按照以下方式发音: 首先,我们需要将Milvus这个词语分解成多个音节。根据汉语拼音的规则,可以将其分解为“mi”、“lu”、“su”。 接下来,我们需要根…

Java阶段五Day03

Java阶段五Day03 文章目录 Java阶段五Day03回顾git命令Git远程仓库远程仓库概念远程仓库分支操作分支管理策略 回顾git命令 本地版本控制 git initgit addgit commitgit loggit statusgit taggit refloggit reset 分支管理 git branchgit branch b1git checkout b1git merg…

C#核心知识回顾——13.多线程、预处理器指令

1.多线程 了解线程前先了解进程 进程&#xff08;Process&#xff09;是计算机中的程序关于某数据集合上的一次运行活动 是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础 说人话&#xff1a;打开个应用程序就是在慢作系统上开启了一个进程 进程之间可以相…

【Vscode】解决 An SSH installation couldn‘t be found

【Vscode】解决 An SSH installation couldn‘t be found 背景描述&#xff1a;在vscode中使用ssh进行连接到时候&#xff0c;已经安装了ssh romote的plugin插件&#xff0c;但是在输入了ssh连接命令之后&#xff0c;仍然出现报错&#xff1a;an ssh installation could not be…

vue3+mapboxgl鼠标浮动显示cgcs2000

一、需求 鼠标在地图中浮动展示地图的经纬度&#xff0c;cgcs2000 xy 还有显示带号 二、实现效果 展示经度&#xff0c;纬度&#xff0c;x值&#xff0c;y值显示的是带号和y值 三、思路 3.1、mapbox获取经纬度方法 初始化地图后.on方法中有个mousemove方法 mapboxUtil._m…

leetcode:递增的三元子序列

递增的三元子序列 题解部分转自leetcode:Xzz medium 给你一个整数数组 nums &#xff0c;判断这个数组中是否存在长度为 3 的递增子序列。 如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k &#xff0c;使得 nums[i] < nums[j] < nums[k] &#xff0c;返回…

专享策略06 | 盘口策略CTP实盘版

量化策略开发&#xff0c;高质量社群&#xff0c;交易思路分享等相关内容 『正文』 ˇ 大家好&#xff0c;我们在6月29日发布了盘口策略| 回测版&#xff0c;今天我们做好了CTP的实盘版本供俱乐部会员使用和玩耍&#xff0c;今天主要说明一下如何使用CTP实盘版本。 先回顾一…

线上展厅设计方案,个性化自主打造720漫游展厅

导语&#xff1a; 随着科技的不断进步&#xff0c;线上展厅作为一种新型的展示方式&#xff0c;在现代社会得到了广泛的应用。线上展厅通过虚拟技术和创新设计&#xff0c;突破了时间和地域的限制&#xff0c;为企业和观众带来了全新的展览体验。本文将重点探讨线上展厅的优势和…

【工具使用】STM32CubeMX-单ADC模式规则通道配置

一、概述 无论是新手还是大佬&#xff0c;基于STM32单片机的开发&#xff0c;使用STM32CubeMX都是可以极大提升开发效率的&#xff0c;并且其界面化的开发&#xff0c;也大大降低了新手对STM32单片机的开发门槛。     本文主要讲述STM32芯片的ADC的配置及其相关知识。 二、…

6. Springboot快速回顾(集成Dubbo)

Dubbo是实现远程调用的一个框架&#xff0c;阿里巴巴开源的。远程调用就是B服务器可以调用A服务器的方法。大型项目会被拆分成多个模块&#xff0c;部署在不同的服务器上。若将公共模块集中部署在一台服务器上&#xff0c;可以方便其他服务器调用。因此&#xff0c;需要Dubbo。…

java代码实现自动录入数据

之前工作中遇到粘贴复制大量数据&#xff0c;研究一下java代码解放双手 模拟鼠标录入数据 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.0.RELEASE&…

本地私有化部署大模型RWKV-懒人包一键安装享受专属免费大模型-RWKV Runner

仓库地址&#xff1a;https://github.com/josStorer/RWKV-Runner 预设配置已经开启自定义CUDA算子加速&#xff0c;速度更快&#xff0c;且显存消耗更少。如果你遇到可能的兼容性问题&#xff0c;前往配置页面&#xff0c;关闭使用自定义CUDA算子加速 如果Windows Defender说这…