当前位置: 首页 > news >正文

一篇文章学懂C++和指针与链表

指针

目录

指针

C++的指针学习

指针的基本概念

指针变量的定义和使用

指针的所占的内存空间

空指针和野指针

const修饰指针

指针和数组

指针和函数

指针、数组、函数


 接下来让我们开始进入学习吧!

C++的指针学习

指针的基本概念

指针的作用:可以通过指针间接访问内存

  1. 内存编号是从0开始记录的,一般用十六进制数字表示

  2. 可以利用指针变量保存地址

这个概念和C语言是一模一样的,只要记住指针就是地址

指针变量的定义和使用

#include<iostream>
using namespace std;
int main()
{int a = 10;int *pa = &a;cout << a << endl;cout << pa << endl;cout << &a << endl;cout << *pa << endl;//可以通过解引用的方式来找到指针指向的内存*pa = 20;//通过指针来改变a的值cout << a << endl;cout << *pa << endl;return 0;
}
输出结果:
10
0x61fe14
0x61fe14
10
20
20

指针的所占的内存空间

指针也是一种数据类型,所以也会占内存空间。

#include<iostream>
using namespace std;
int main()
{int* pa;char* pb;short* pc;long* pd;float* pe;double* pf;cout << sizeof(pa) << endl;cout << sizeof(pb) << endl;cout << sizeof(pc) << endl;cout << sizeof(pd) << endl;cout << sizeof(pe) << endl;cout << sizeof(pf) << endl;return 0;
}
8
8
8
8
8
8

在32位的操作系统中,指针都是占4个字节的空间的。

在64位的操作系统中,指针则都是占8个字节的空间的。

所以看题目或者写代码的时候一定要清楚自己机器的大小和型号。

空指针和野指针

空指针:指针变量指向内存中编号为0的空间

用途:初始化针变量

注意:空指针指向的内存是不可以访间的

示例1:空指针

#include<iostream>
using namespace std;
int main()
{//空指针//空指针用于给指针变量进行初始化int* p = NULL;//2.空指针是不可以进行访问的,//0~255内存编号是系统占用的,使用会错误,因此不可访问cout << *p <<endl;return 0;
}

野指针:指针变量指向非法的内存空间

示例2:野指针

#include<iostream>
using namespace std;
int main()
{int* p = (int*)0x1100;cout << *p << endl;//这里还是无法输出,指向的是非法内存空间int arr[2] = { 1,2 };p = arr[2];//越界访问cout << *p <<endl;return 0;
}

总结:空指针和野指针都不是我们自己申请的空间,因此不要访问。

const修饰指针

const修饰指针的三种情况:

  1. const修饰指针——常量指针

  2. const修饰常量——指针常量

  3. const既修饰指针,又修饰常量

示例:

#include<iostream>
using namespace std;
int main()
{int a = 10;int b = 20;//常量变量//特点:指针的指向可以修改,但是指针指向的值不可以改const int* p1 = &a;a = 0;//*p1也会相应改变p1 = &b;//可以实现*p1 = 0;//不允许//指针常量//特点:指针的指向不可以修改,但是指针指向的值可以改int* const p2 = &a;*p2 = 10;p1 = &b;//不允许*p1 = 0;//可以实现//既修饰指针,又修饰常量//特点:指针的指向不可以修改,但是指针指向的值也不可以改const int* const p3 = &a;p3 = &b;//不允许*p3 = 0;//不允许return 0;
}

指针和数组

作用:利用指针访问数组中元素

一维数组

#include<iostream>
using namespace std;
int main()
{int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };int * p = arr;for(int i = 0;i < 10; i++){cout << *p + i << endl;//用p[i]也可以做到}return 0;
}

二维数组

#include<iostream>
using namespace std;
int main()
{int arr[2][3] = { { 0,1,2 },{ 3,4,5} };int (* parr)[3] = arr;for(int i = 0;i < 2; i++){for(int j = 0;j < 3; j++){cout << (*parr[i]+j)<<endl;}}return 0;
}
 

指针和函数

作用:利用指针作函数参数,可以修改实参的值

#include<iostream>
using namespace std;
void Swap(int* x,int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
int main()
{//实现a,b交换int a,b;cin >> a >> b;Swap(&a,&b);cout << "a = " << a << endl;cout << "b = " << b << endl;return 0;
}

指针、数组、函数

案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序 如数组:int arr[10]={4,3,6,9,1,2,10,8,7,5}

#include<iostream>
using namespace std;
​
void bubbleSort(int *p,int sz)
{for(int i = 0;i < sz - 1; i++){for(int j = 0; j < sz - i - 1; j++){//如果j>j+1的数据就要交换if(*(p + j) > *(p + j + 1)){int tmp = *(p + j);*(p + j) = *(p + j + 1);*(p + j + 1) = tmp;}}}
}
​
//打印数组
void printArray(int * p,int sz)
{for(int i = 0;i < sz; i++){cout << *p + i << " ";}
}
int main()
{//1.创建数组int arr[10];for(int i = 0;i < 10; i++){cin >> arr[i];}//数组长度int sz = sizeof(arr) / sizeof(arr[0]);//2.创建函数bubbleSort(arr,sz);
​//3.打印排序后的数组printArray(arr,sz);return 0;
}

链表

学习C++链表

链表的基本概念avi_

数据域1+next地址 ——> 数据域2+next地址 ——> 数据域3+next地址 ——> 数据域4+next地址 ——> 数据域5+next地址 ——> NULL(空)

链表是一种物理存储单元上非连续非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。链表可以在多种编程语言中实现。像Lisp和Scheme这样的语言的内建数据类型中就包含了链表的存取和操作。程序语言或面向对象语言,如C,C++和Java依靠易变工具来生成链表。

链表在指定位置插入和删除不需要移动元素,只需要修改指针即可。

查找效率低于数组

链表相对于数组而言,多了指针域空间开销

链表种类:

静态链表 动态链表 单向链表 双向链表 循环链表 单向循环链表 双向循环链表

拿到链表的第一个节点,就相当于拿到整个链表

头节点不保存任何数据

静态链表

 

静态链表:分配一整片连续的内存空间,各个结点集中安置,逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成的链表称为静态链表。也就是说静态链表是用数组来实现链式存储结构,静态链表实际上就是一个结构体数组

实现一个链表

#define _CRT_SECURE_NO_WARNING
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
​
//链表节点类型定义
struct LinkNode
{int data;struct LinkNode *next;
};
​
void test()
{struct LinkNode node1 = { 10, NULL };struct LinkNode node2 = { 20, NULL };struct LinkNode node3 = { 30, NULL };struct LinkNode node4 = { 40, NULL };struct LinkNode node5 = { 50, NULL };struct LinkNode node6 = { 60, NULL };node1.next = &node2;node2.next = &node3;node3.next = &node4;node4.next = &node5;node5.next = &node6;//连成链表//如何遍历这个链表struct LinkNode *pCurrent = &node1;while(pCurrent != NULL){printf("%d ",pCurrent->data);//指针移动到下一个元素的首地址pCurrent = pCurrent->next;}
}
​
int main()
{test();return 0;
}

如何遍历这个链表 需要一个pCurrent指针能够指向下一个链表的地址

pCurrent = pCurrent->next

动态链表

这种链表在初始时不一定分配足够的空间, 但是在后续插入的时候需要动态申请存储空间,并且存储空间不一定连续, 在进行插入和删除时则不需要移动元素, 修改指针域即可,所以仍然具有链表的主要优点,链表结构可以是动态地分配存储的,即在需要时才开辟结点的存储空间,实现动态链接

链表的实现

LinkList.h

#define _CRT_SECURE_NO_WARNINGS
​
#pragma once
​
#include<stdio.h>
#include<stdnool.h>
#include<stdlib.h>
​
#iddef __cplusplus
#endif//定义节点数据类型struct LinkNode{int data;struct LinkNode *next;}
​//初始化链表struct LinkNode * Init_LinkList();//在值为oldval的后面插入一个新的数据newvalvoid InsertByValue_LinkList(struct LinkNode *header,int oldval,int newval);//删除值为val的节点void RemoveByValue_LinkList(struct LinkNode *header,int delValue);//遍历void Foreach_LinkList(struct LinkNode *header);//销毁void Destroy_LinkList(struct LinkNode *header);//清空void Clear_LinkList(struct LinkNode *header);#ifdef __cplusplus
#endif

LinkList.c

#include "LinkList.h"
//初始化链表
struct LinkNode * Init_LinkList()
{//创建头节点struct LinkNode *header = malloc(sizeof(struct LinkNode));header->data = -1;header->next = NULL;//尾部指针struct LinkNode *pRear = header;int val = -1;while(true){printf("输入插入的数据:\n");scanf("%d",&val);if(val == -1){break;}//先创建新节点struct LinkNode *newnode = malloc(sizeof(struct LinkNode));newnode->data = val;newnode->next = NULL;//新节点插入到链表中pRear->next = newnode;//更新尾部指针指向pRear = newnode;}return header;
}
​//在值为oldval的位置插入一个新的数据newvalvoid InsertByValue_LinkList(struct LinkNode *header,int oldval,int newval){if(NULL == header){return;}//两个辅助指针变量struct LinkNode *pPrev = header;struct LinkNode *pCurrent = pPrev->next;while(*pCurrent != NULL){if(pCurrent->data == oldval){break;}pPrev = pCurrent;pCurrent = pCurrent->next;}//pCurrent为空那就说明链表中不存在职位oldval的节点if(pCurrent == NULL){return;}//先创建新节点struct LinkNode *newnode = malloc(sizeof(struct LinkNode));newnode->data = newval;newnode->next = NULL;//新节点插入到链表中pPrev->next = newnode;newnode->next = pCurrent;//删除值为val的节点void RemoveByValue_LinkList(struct LinkNode *header,int delValue){if(NULL == header){return;}//两个辅助指针变量struct LinkNode *pRrev = header;struct LinkNode *pCurrent = pRrev->next;//while(pCurrent != NULL){if(pCurrent->data == delValue){break;}//移动两个辅助指针pPrev = pCurrent;pCurrent = pCurrent->next;}if(pCurrent == NULL){return;}//重新建立待删除节点的前驱和后继节点关系pPrev->next = pCurrent->next;free(pCurrent);pCurrent == NULL;}
​//遍历void Foreach_LinkList(struct LinkNode *header){if(NULL == header){return;}//辅助指针变量struct LinkNode *pCurrent = header->next;while(pCurrent != Null){printf("%d ",pCurrent->data);pCurrent = pCurrent->next;}}
​//销毁void Destroy_LinkList(struct LinkNode *header){if(NULL == header){return;}//辅助指针变量struct LinkNode *pCurrent = header;while(pCurrent != NULL){//先保存当前节点的下一个节点地址struct LinkNode *pNext = pCurrent->next;//释放当前节点内存free(pCurrent);//指针向后移动pCurrent = pNext;}}//清空void Clear_LinkList(struct LinkNode *header){if(NULL == header){return;}//辅助指针变量struct LinkNode *pCurrent = header->next;while(pCurrent != NULL){//先保存当前节点的下一个节点位置struct LinkNode *pNext = pCurrent->next;//释放当前节点内存free(pCurrent);//pCurrent指向下一个节点pCurrent = pNext;}header->next = NULL;}

TestLinkList.c

相关文章:

一篇文章学懂C++和指针与链表

指针 目录 指针 C的指针学习 指针的基本概念 指针变量的定义和使用 指针的所占的内存空间 空指针和野指针 const修饰指针 指针和数组 指针和函数 指针、数组、函数 接下来让我们开始进入学习吧&#xff01; C的指针学习 指针的基本概念 指针的作用&#xff1a;可…...

TPGS-cisplatin顺铂修饰维生素E聚乙二醇1000琥珀酸酯

TPGS-cisplatin顺铂修饰维生素E聚乙二醇1000琥珀酸酯(TPGS)溶于大部分有机溶剂,和水有很好的溶解性。 长期保存需要在-20℃,避光,干燥条件下存放&#xff0c;注意取用一定要干燥,避免频繁的溶解和冻干。 维生素E聚乙二醇琥珀酸酯(简称TPGS)是维生素E的水溶性衍生物,由维生素E…...

【20230206-0209】哈希表小结

哈希表一般哈希表都是用来快速判断一个元素是否出现在集合里。哈希函数哈希碰撞--解决方法&#xff1a;拉链法和线性探测法。拉链法&#xff1a;冲突的元素都被存储在链表中线性探测法&#xff1a;一定要保证tableSize大于dataSize&#xff0c;利用哈希表中的空位解决碰撞问题。…...

c++11 标准模板(STL)(std::multimap)(一)

定义于头文件 <map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class multimap;(1)namespace pmr { template <class Key, class T…...

python进阶——自动驾驶寻找车道

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…...

男,26岁,做了一年多的自动化测试,最近在纠结要不要转行,求指点。?

最近一个粉丝在后台问我&#xff0c;啊大佬我现在26了&#xff0c;做了做了一年多的自动化测试&#xff0c;最近在纠结要不要转行&#xff0c;求指点。首选做IT这条路&#xff0c;就是很普通的技术蓝领。对于大部分来说干一辈子问题不大&#xff0c;但是发不了什么财。如果你在…...

源码级别的讲解JAVA 中的CAS

没有CAS之前实现线程安全 多线程环境不使用原子类保证线程安全&#xff08;基本数据类型&#xff09; public class T3 {volatile int number 0;//读取public int getNumber(){return number;}//写入加锁保证原子性public synchronized void setNumber(){number;} }多线程环…...

JUC锁与AQS技术【我的Android开发技术】

JUC锁与AQS技术【我的Android开发技术】 AQS原理 AQS就是一个同步器&#xff0c;要做的事情就相当于一个锁&#xff0c;所以就会有两个动作&#xff1a;一个是获取&#xff0c;一个是释放。获取释放的时候该有一个东西来记住他是被用还是没被用&#xff0c;这个东西就是一个状…...

【问题代码】顺序点的深入理解(汇编剖析+手画图解)

这好像是一个哲学问题。 目录 前言 一、顺序点是什么&#xff1f; 二、发生有关顺序点的问题代码 vs中&#xff1a; gcc中&#xff1a; 三、细读汇编 1.vs汇编如下&#xff08;示例&#xff09;&#xff1a; 2.gcc汇编如下&#xff08;示例&#xff09;&#xff1a; 四…...

BinaryAI全新代码匹配模型BAI-2.0上线,“大模型”时代的安全实践

导语BinaryAI&#xff08;https://www.binaryai.net&#xff09;科恩实验室在2021年8月首次发布二进制安全智能分析平台—BinaryAI&#xff0c;BinaryAI可精准高效识别二进制文件的第三方组件及其版本号&#xff0c;旨在推动SCA&#xff08;Software Composition Analysis&…...

nvidia设置wifi和接口

tx-nx设置wifi和接口前言基础知识点1.创建和删除一个wifi连接2. 启动连接和关闭连接代码和调试1. 代码展示2. 调试写到最后前言 针对嵌入式开发&#xff0c;有时候通过QT或PAD跨网络对设备设置WIFI&#xff0c;在此记录下&#xff0c;方便后续的查阅。 基础知识点 1.创建和删…...

PostgreSQL 变化数据捕捉(CDC)

PostgreSQL 变化数据捕捉&#xff08;CDC&#xff09;基于CDC&#xff08;变更数据捕捉&#xff09;的增量数据集成总体步骤&#xff1a;1.捕获源数据库中的更改数据2.将变更的数据转换为您的消费者可以接受的格式3.将数据发布到消费者或目标数据库PostgreSQL支持触发器&#x…...

Spring 事务【隔离级别与传播机制】

Spring 事务【隔离级别与传播机制】&#x1f34e;一.事务隔离级别&#x1f352;1.1 事务特性回顾&#x1f352;1.2 事务的隔离级别(5种)&#x1f352;1.3 事务隔离级别的设置&#x1f34e;二.Spring 事务传播机制&#x1f352;2.1 Spring 事务传播机制的作用&#x1f352;2.2 事…...

HTTP和HTTPS协议

HTTP协议 HTTP协议是一种应用层的协议&#xff0c;全称为超文本传输协议。 URL URL值统一资源定位标志&#xff0c;也就是俗称的网址。 协议方案名 http://表示的就是协议方案名&#xff0c;常用的协议有HTTP协议、HTTPS协议、FTP协议等。HTTPS协议是以HTTP协议为基础&#…...

day3——有关java运算符的笔记

今天主要学习的内容有java的运算符 赋值运算符算数运算符关系运算符逻辑运算符位运算符&#xff08;专门写一篇笔记&#xff09;条件运算符运算符的优先级流程控制 赋值运算符 赋值运算符&#xff08;&#xff09;主要用于给变量赋值&#xff0c;可以跟算数运算符相结合&…...

Git多人协同远程开发

1. 李四&#xff08;项目负责人&#xff09;操作步骤 在github中创建远程版本库testgit将基础代码上传⾄testgit远程库远程库中基于main分⽀创建dev分⽀将 githubleaflife/testgit 共享给组员李四继续在基础代码上添加⾃⼰负责的模块内容 2. 张三、王五&#xff08;组员&…...

Chapter4:机器人仿真

ROS1{\rm ROS1}ROS1的基础及应用&#xff0c;基于古月的课&#xff0c;各位可以去看&#xff0c;基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。 ROS{\rm ROS}ROS版本&#xff1a;ROS1{\rm ROS1}ROS1的Melodic{\rm Melodic}Melodic&#xff1b;实际机器人&#xff1a;Ha…...

python(14)--集合

前言 本篇文章学习的是 python 中集合的基础知识。 集合元素的内容是不可变的&#xff0c;常见的元素有整数、浮点数、字符串、元组等。至于可变内容列表、字典、集合等不可以是集合元素。虽然集合不可以是集合的元素&#xff0c;但是集合本身是可变的&#xff0c;可以去增加或…...

【Spark分布式内存计算框架——Spark Core】4. RDD函数(中)Transformation函数、Action函数

3.2 Transformation函数 在Spark中Transformation操作表示将一个RDD通过一系列操作变为另一个RDD的过程&#xff0c;这个操作可能是简单的加减操作&#xff0c;也可能是某个函数或某一系列函数。值得注意的是Transformation操作并不会触发真正的计算&#xff0c;只会建立RDD间…...

Mysql 数据类型

1、数值数据类型 1.1 整数类型(精确值) INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT MySQL支持SQL标准的整数类型INTEGER (或INT)和SMALLINT。作为标准的扩展&#xff0c;MySQL还支持整数类型TINYINT、MEDIUMINT和BIGINT。下表显示了每种整数类型所需的存储和范围。…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...