学习c++ Part03

news2024/12/24 3:03:49

文章目录

    • 前言
    • 1.动态空间申请
      • 1.1 静态空间申请
      • 1.2 动态分配
    • 2.字符串处理函数
    • 3.结构体
      • 3.1 结构体的浅拷贝
      • 3.2 结构体的深拷贝
      • 3.3 结构体变量在堆区 结构体指针成员也指向堆区(先释放成员,再释放结构体)
      • 3.4 结构体的对齐规则
      • 3.5 结构体的位域(了解 放几张图 可以看看 通常用在嵌入式中)
      • 3.6 共用体union
      • 3.7 枚举 enum(需要了解,可以测试)
    • 4.链表
        • 4.1 为什么要预设首元结点,只想head节点?
        • 4.2 动态链表的插入、删除

前言

日期:2023年7月3日 下午开始~平时还有论文和实验代码要看 进度缓慢 还没到正经内容。

1.动态空间申请

1.1 静态空间申请

事先知道大小,分配在栈区或者全局区

int num = 100;
int arr[4] = {0};

1.2 动态分配

关键字:

  • new 申请堆区空间
  • delete 释放空间
  • 释放申请是数组空间 需要 加上[]
  • new delete 是成对使用的
    使用实例:
void test08()
{
    // new delete 动态申请空间
    //动态申请int
    int *p = new int(10);
    cout<<*p<<endl;
    //释放
    delete p;
/*------------------------------------------*/
    //动态申请数组
    int *arr = new int[4]{10,20,30,40};
    for (int i = 0; i < 4; ++i) {
        cout<<*(arr+i)<<endl;
    }
    //释放
    delete [] arr;
}

2.字符串处理函数

头包含

#include<string.h>

各种操作:

#include<string.h>
//测量字符长度
//size_t strlen(const char *s); // s指测量字符串的首元素地址 '\0'停止
char str1[128]="hello";
strlen(str1);//5

//字符串拷贝
/*
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n); dest:目的空间地址
src:原字符串的首元素地址
*/
char dst[128]="";
char src[]="hello\0world";
strcpy(dst,src);
cout<<dst<<endl;//hello

//字符串追加
/*
char *strcat(char *dest, const char *src);
char *strncat(char *dest, const char *src, size_t n); 将src指向的字符串 追加到 dest指向的字符串尾部
*/
char dst[128]="hello";
char src[]="world";
strcat(dst,src);
cout<<dst<<endl;//helloworld

//字符串比较
/*
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
返回值:
比较的ASCII值
>0 s1字符串 > s2字符串 
<0 s1字符串 < s2字符串
==0 s1字符串==s2字符串
*/

3.结构体

定义&使用:

#include<string.h>
sturct Student{
	int num;
	char name[32];
}
Student lucy; //不初始化通过lucy.num 获取到的是随机值
Student zhang = {01,"zhang"} //按照顺序初始化
//name成员时数组名 位符号常量 不允许用=给name赋值 
//zhang.name = "xiaozhang";//错误 
strcpy(zhang.name, "xiaozhang");
// 获取值的方式
//zhang.num zhang.name

清空结构体变量:

//void *memset(void *_Dst,int _Val,size_t _Size); 
//将地址从_Dst开始 长度位_Size的所有字节赋值位_Val
memset(&zhang,0,sizeof(zhang));

结构体嵌套:

struct Address{
	char province[32];
	char region[32];
	int num;
}
struct Student{
	int num;
	char name[32];
	Address add;
}

结构体数组:

Student stus[3] = {01,"zhangxueyou",02,"zhangtielin",03,"zhangguorong"};
//stus[0] 与数组使用类似

结构体指针变量:

struct Student{
int num;
char name[32];
}
Student zhang = {01,"zhang"};
Student *stu = &zhang;
//通过指针访问成员变量
//stu->num
//stu->name

结构体指针成员,指针文字常量区(只读)

struct stu{
	int num;
	char *name;
}
Stu zhang;
zhang.num = 100;
zhang.name = new char[32];
strcpy(zhang.name, "xiaozhang");
cout<<zhang.num<<" "<<zhang.name<<endl;
delete [] zhang.name;

3.1 结构体的浅拷贝

整体赋值就是浅拷贝,结构体中没有指针成员变量的时候,浅拷贝不会带来任何问题;如果结构体中有指针成员变量时,会出现多次释放堆区空间的问题

struct stu{
	int num;
	char *name;
}
stu zhang;
zhang.num = 100;
zhang.name = new char[32];
strcpy(zhang.name, "xiaozhang");
stu wang;
wang = zhang;
//操作完毕后多次释放空间
delete [] zhang.name;
delete [] wang.name;

3.2 结构体的深拷贝

如果结构体中有指针成员,尽量使用深拷贝
深拷贝就是为结构体中的指针成员分配独立的空间,然后再进行内容拷贝

struct stu{
	int num;
	char *name;
}
stu zhang;
zhang.num = 100;
zhang.name = new char[32];
strcpy(zhang.name, "xiaozhang");
stu wang;
wang.num = zhang.num;
wang.num = new char[32];
strcpy(wang.name, zhang.name);
//操作完毕后多次释放空间
delete [] zhang.name;
delete [] wang.name;

3.3 结构体变量在堆区 结构体指针成员也指向堆区(先释放成员,再释放结构体)

struct stu {
	int num;
    char *name;
};
//结构体在堆区
stu *p = new stu;
//结构体中指针成员指向堆区 
p->name = new char[32];
//赋值
p->num = 100;
strcpy(p->name, "hello world");
cout<<p->num<<" "<<p->name<<endl;
//释放空间
delete [] p->name;//先释放成员指向 
delete p;//再释放结构体

3.4 结构体的对齐规则

对齐规则是按照字节来的 char1 short2 int4
自动对齐:

  • 一行多少字节,由结构体中最大的基本类型决定
  • 成员偏移量:最大成员的类型的正数倍
  • 结构体的总大小=分配单位整数倍
struct Data {
    char a;
    short b;
    int c;
    char d;
    short e;
};

结构体内存分布图:
在这里插入图片描述
强制对齐:

#pragma pack (value)时的指定对齐值value。
  • 分配单位:min(最大基本类型,value)
  • 成员偏移量= 成员自身类型的整数倍
  • 结构体总大小:分配单位的整数倍
    在这里插入图片描述
    在这里插入图片描述

3.5 结构体的位域(了解 放几张图 可以看看 通常用在嵌入式中)

位域是以二进制位为单位的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用案例:
在这里插入图片描述

3.6 共用体union

结构体:所有成员拥有独立的空间
共用体:所有成员共享同一块空间
共用体空间,由最大的成员类型决定

union data{
	char a;
	short b;
	int c;
}
void test01(){
	Data ob;
    ob.a = 10;
    ob.b = 20;
    ob.c = 30;
    cout<<ob.a+ob.b+ob.c<<endl;//90==30+30+30
}
void test02(){
	Data ob;
ob.c = 0x01020301;
ob.b = 0x0102;
ob.a = 0x01;
cout<<ob.a+ob.b+ob.c<<endl;//0x01020203
}

3.7 枚举 enum(需要了解,可以测试)

enum province{JIANGSU,ZHEJIANG,ANHUI,HENAN};//0,1,2,3

4.链表

每个节点通过指针域 保存下一个节点的位置 达到逻辑上连续
链表数组优缺点:
数组:

  • 优缺点:查询效率高,插入效率低
    链表
  • 优缺点:插入效率高,查询效率低

静态链表的定义:

struct p{
	//数据域
	int num;
	char name[32];
	//指针域
	struct p *next;
}

p p1 = {1, "aaa", NULL}; 
p p2 = {2, "bbb", NULL}; 
p p3 = {3, "ccc", NULL}; 
p p4 = {4, "ddd", NULL}; 
p p5 = {5, "eee", NULL};
//定义一个数据域为空的链表头
p *head = &p1;
p1.next = &p2; 
p2.next = &p3; 
p3.next = &p4; 
p4.next = &p5; 
p5.next = NULL;

//遍历
p *pd = head; // 添加首元节点
while(pd->next != NULL){
	cout<<pd->num<<" "<<pd->name<<endl;
	pd = pd->next; 
}

4.1 为什么要预设首元结点,只想head节点?

  1. 便于首元结点的处理:增加头结点后,首元结点的地址保存在头结点的指针域中,则对链表的第一个元素的操作和其他元素相同,无需进行特殊处理。(若单链表不带头结点,则首元结点无前驱结点,在其前插入结点和删除该结点操作复杂些。)

  2. 便于空表和非空表的统一处理:增加头结点后,无论链表是否为空,头指针都是指向头结点的非空指针

  • 注:首元结点是指链表中存储线性表中第一个数据元素a1的结点(头结点的下一个结点)。为了操作方便,通常在链表的首元结点之前附设一个结点(头结点)。

4.2 动态链表的插入、删除

struct stu{
	//数据域
	int num;
	char name[32];
	//指针域
	stu *next;
}

插入:

# if 0
//插入节点 头插
stu *linkInsert(stu *head, stu tmp) {
    //开辟堆空间
    stu *pi = new stu;
    *pi = tmp;
    pi->next = NULL; //下个节点指向空
    //判断头节点是否为空
    if (head == NULL) {
        //直接令插入节点为头结点
        head = pi;
    } else {
        //头结点不为空
        pi->next = head;
        head = pi;
    }
    return head;
}
#endif
# if 0
//插入节点 尾插
stu *linkInsert(stu *head, stu tmp) {
    //开辟堆空间
    stu *pi = new stu;
    *pi = tmp;
    pi->next = NULL; //下个节点指向空
    //判断头节点是否为空
    if (head == NULL) {
        //直接令插入节点为头结点
        head = pi;
    } else {
        //找到尾结点
        stu *pb = head; // 必须这么做 保留前面的数据
        while (pb->next != NULL) {
            pb = pb->next;
        }
        pb->next = pi;
    }
    return head;
}
#endif

#if 1
    //有序插入
stu *linkInsert(stu *head, stu tmp) {
    stu *pi = new stu;
    *pi = tmp;
    pi->next = NULL;
    //判空
    if (head == NULL) {
        head = pi;
    } else {
        //链表存在
        stu *pf = head;
        stu *pb = head;
        while (pi->num > pb->num && pb->next != NULL) {
            //保存pb节点
            pf = pb;
            //pd像后移动
            pb = pb->next;
        }
            //判断插入点位置
            if(pi->num <= pb->num){
                if(pb == head){
                	//pb->next == NULL 的情况
                    //最开头插入
                    pi->next = head;
                    head = pi;
                }else{
                    //中间插入(pf&pd之间搭桥)
                    pf->next = pi;
                    pi->next = pb;
                }
            }else{
                //尾部插入(值最大)
                pb->next = pi;
            }
    }
    return head;
}
#endif

删除节点

stu *linkDelete(stu *head, int num) {
    //判空
    if (head == NULL) {
        cout << "link not exit" << endl;
    }
    stu *pf = head;
    stu *pb = head;
    //遍历链表
    while (pb->num != num && pb->next != NULL) {
        pf = pb;
        pb = pb->next;
    }

    //找到删除点
    if (pb->num == num) {
        if (pb == head) {
            //删除头节点
            head = pb->next;
        } else {
            //不是头结点
            pf->next = pb->next;
        }
        delete pb;
    } else {
        cout << "未找该节点" << endl;
    }
    return head;
}

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

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

相关文章

跟我一起从零开始学python(三)多线程/多进程/协程

前言 回顾之前讲了python语法编程 &#xff0c;关于从零入门python的第一遍&#xff0c;编程语法必修内容&#xff0c;比如python3基础入门&#xff0c;列表与元组&#xff0c;字符串&#xff0c;字典&#xff0c;条件丶循环和其他语句丶函数丶面向对象丶异常和文件处理和网络…

oracle,update更新时,条件没走索引

update更新时没走索引&#xff0c; 查询索引是有效的&#xff1a; 没走索引的原因是条件字段的字段类型不一致&#xff0c; 一个是varchar2&#xff0c; 另一个是 nvarchar2 。 要走索引需要字段类型一致&#xff0c;可以利用to_char()将 nvarchar2转为 varchar2

VS2019+Qt5.15 在线显示百度地图

1.Qt5.15编译程序需要选择mscv2019 Release版本 2.需要到百度地图开发平台注册并获取到开发者key 3.显示地图是JS与Qt的交互过程&#xff0c;显示地图的html文件&#xff1a; <!DOCTYPE html> <html><head> <meta name"viewport" content&q…

订单自动取消的11种实现方式(上)

一、DelayQueue DelayQueue是JDK提供的api&#xff0c;是一个延迟队列 DelayQueue泛型参数得实现Delayed接口&#xff0c;Delayed继承了Comparable接口。 getDelay方法返回这个任务还剩多久时间可以执行&#xff0c;小于0的时候说明可以这个延迟任务到了执行的时间了。 com…

企业微信小程序登录,错误码:60020

在使用企业微信wx.qy.login API进行登录获取【session_key】时&#xff0c;报出错误码&#xff1a;60020 此错误记得好像意指的是获取的企业【access_token】用以去置换登录令牌【session_key】时&#xff0c;下发【access_token】的IP地址和获取【session_key】的IP不一致&am…

kotlin Flow系列之 - 冷流SafeFlow源码解析之 - Safe在那里?

本文涉及源码基于kotlinx-coroutines-core-jvm:1.7.1 kotlin 协成系列文章: 你真的了解kotlin中协程的suspendCoroutine原理吗? Kotlin Channel系列&#xff08;一&#xff09;之读懂Channel每一行源码 kotlin Flow系列之-冷流SafeFlow源码解析之 - Safe在那里&#xff1f; ko…

【vue2动画效果】实现两组单词逐渐减短,最后只保留首字母的效果

前言 实现两组单词逐渐减短&#xff0c;最后只保留首字母的效果 效果&#xff1a; 正文 <template><div class"header"><div style"margin-right: 12px; display: inline-flex"><divclass"door"id"book1"v-f…

常用数据回归建模算法总结记录

本文的主要目的是总结记录日常学习工作中常用到的一些数据回归拟合算法&#xff0c;对其原理简单总结记录&#xff0c;同时分析对应的优缺点&#xff0c;以后需要的时候可以直接翻看&#xff0c;避免每次都要查询浪费时间&#xff0c;欢迎补充。 (1)线性回归 (Linear Regressio…

解决springboot上传中文文件报错:NoClassDefFoundError: javax/mail/internet/MimeUtility

解决springboot上传中文文件报错:NoClassDefFoundError: javax/mail/internet/MimeUtility 1. 背景&#xff1a; springboot版本&#xff1a;2.7.11 前端使用 UnityEngine.WWWForm 进行文件上传 报错信息&#xff1a;org.springframework.web.multipart.MultipartException: F…

【资料分享】RK3568开发板规格书(4x ARM Cortex-A55(64bit),主频1.8GHz)

1 开发板简介 创龙科技TL3568-EVM是一款基于瑞芯微RK3568J/RK3568B2处理器设计的四核ARM Cortex-A55国产工业评估板&#xff0c;每核主频高达1.8GHz/2.0GHz&#xff0c;由核心板和评估底板组成。核心板CPU、ROM、RAM、电源、晶振、连接器等所有器件均采用国产工业级方案&#…

【拼多多API商品详情页面采集】具体的API接口调用步骤

要从拼多多获取商品数据&#xff0c;可以使用拼多多提供的API接口。首先需要注册一个拼多多开放平台的开发者账号&#xff0c;然后创建一个应用程序&#xff0c;获取应用程序的app_id和app_secret&#xff0c;以在API请求中进行身份验证。 在使用API接口时&#xff0c;需要按照…

力扣1816. 截断句子

代码展示&#xff1a; 方法1&#xff1a;通过StringBuilder创建的变量str来记录截断得到的字符串 思路&#xff1a;遍历字符串s&#xff0c;定义一个变量count_space来记录空格出现的次数&#xff0c;当空格没有出现k次时便将字符依次连接到StringBuilder类型的变量str后&#…

Web跳转案例、表单案例

一、跳转案例 <img>&#xff1a;html元素将图像嵌入文档 <body> <img src"../images(1)/images/7.5-1.jpg"> </body> 使用a标签进行一个跳转链接 <!DOCTYPE html> <html lang"en"> <head> <meta charset&qu…

7-3学习发布订阅模式,观察者模式

7-3学习发布订阅模式&#xff0c;观察者模式 1.发布订阅模式2.观察者模式 1.发布订阅模式 前端比较重要的两个设计模式&#xff0c;发布订阅模式和观察者模式。来简单的学习下。 let fs require(fs); let person {}let event {arr:[],on(fn){this.arr.push(fn);},emit(){t…

谷歌浏览器如何实现书签同步

推荐使用GIT仓库来当做中间介质&#xff0c;实现书签上传和下载&#xff0c;可以在不同机器上的谷歌浏览器之间同步书签 这里默认已经有了Git和谷歌浏览器&#xff0c;其中谷歌浏览器可以登陆账号也可以不登录。 GIT上创建私密仓库用于存储书签的json文件&#xff0c;生成秘钥…

回归预测 | MATLAB实现PSO-GCNN粒子群算法优化分组卷积神经网络的数据多输入单输出回归预测

回归预测 | MATLAB实现PSO-GCNN粒子群算法优化分组卷积神经网络的数据多输入单输出回归预测 目录 回归预测 | MATLAB实现PSO-GCNN粒子群算法优化分组卷积神经网络的数据多输入单输出回归预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 回归预测 | MATLAB实现…

数据结构课设---C语言为主体+引用

目录 一、设计要求 二、实现方法 三、实现过程 1.链栈的实现 2.前缀表达式变后缀表达式 3.括号匹配 4.链队列的实现 5.队列实现栈 6.应用代码实现汇总 7.小猫钓鱼 文章只写了代码的实现&#xff0c;并未进行原理的讲解&#xff0c;希望大家不喜勿喷 一、设计要求 1.…

C++读取一行内个数不定的整数的方式

&#x1f4af; 博客内容&#xff1a;C读取一行内个数不定的整数的方式 &#x1f600; 作  者&#xff1a;陈大大陈 &#x1f680; 个人简介&#xff1a;一个正在努力学技术的准前端&#xff0c;专注基础和实战分享 &#xff0c;欢迎私信&#xff01; &#x1f496; 欢迎大家&…

如何查询组织结构(组织结构树)

创建简单的组织表 字段1&#xff1a; 组织ID字段2&#xff1a;组织名称字段3&#xff1a;组织的父级ID -- 创建组织结构表 CREATE TABLE organization (id VARCHAR(36) PRIMARY KEY,name VARCHAR(100),parent_id VARCHAR(36) );插入几条数据 INSERT INTO organization (id, …

3D模型轻量化开发工具HOOPS与WebGL的对比分析

HOOPS是一种商业级的3D开发平台&#xff0c;由Tech Soft 3D公司开发。它提供了一套全面的工具和API&#xff0c;用于构建和展示高度复杂的3D场景和模型&#xff0c;可以在多个平台和环境中使用&#xff0c;包括Web、移动设备和桌面&#xff0c;这使得开发者能够在不同的设备上展…