指针、引用

news/2024/11/7 9:26:32/文章来源:https://www.cnblogs.com/chhh31/p/18523997

内存

1.什么是内存?

  • 内存也叫主存储器,用于临时存储数据和程序指令,便于CPU(也就是处理器)快速访问

    • 读写非常快,对比硬盘等外存,一秒一般 \(10^8\) 次读写,下面是一个输出一秒大致多少次运算的程序

      int main() {//clock_t 是一个用来表示CPU时钟的变量  clock()函数是获取程序运行时间的函数clock_t start_t=clock(); // 记录开始时间start_tclock_t time; //运行时间timelong long cnt = 0;while(true){clock_t end_time=clock();  //每层循环都记录一次时间time = end_time - start_time; //用开始的时间减去当前时间就是CPU运行时间if((double)(time)/CLOCKS_PER_SEC >= 1)break;//如果时间大于一秒,就break。CLOCKS_PER_SEC是一个单位,这个时间time单位还是毫秒cnt++;}cout<<(double)(time)/CLOCKS_PER_SEC<<"s"<<endl;//输出时间cout<<cnt<<endl;return 0;
      }
      
    • 在电脑突然断电后,内存数据会丢失,数据库跑任务突然断电有丢失数据的危险,现在的数据库都有数据库管理系统来防止突然断电的情况

    • 地址空间以字节为单位,每个字节都有自己独立的地址

image-20241031193934562

这是内存的大致表示图,每个字节都是以十六进制表示出来的。0x 是一个前缀,代表后面的是十六进制的数

2.各个数据类型所占用的空间大小:

int类型:4字节

long long类型:8字节

double类型:8字节

float类型:4字节

bool类型:1字节

char类型:1字节

汉字字符类型:不同编码方式大小不同,UTF-8编码中占3字节,GBK编码中占2字节

cout<<sizeof(int)<<'\n';
cout<<sizeof(long long)<<'\n';
cout<<sizeof(double)<<'\n';
cout<<sizeof(float)<<'\n';
cout<<sizeof(bool)<<'\n';
cout<<sizeof(char)<<'\n';
cout<<sizeof("a")<<'\n';

sizeof函数:

获取大小

memset(arr,0,sizeof(arr));

memset(arr,0x3f,sizeof(arr));//注意,初始化值是以字节为单位把每个字节初始化为0x3f

memset(arr,0x3f,sizeof(arr));
for(int i = 0;i < 100;i ++) cout<<arr[i]<<" ";
cout<<endl;
cout<<"0x3f3f3f3f代表的值为:"<<0x3f3f3f3f<<endl;

image-20241103200518117

image-20241103204224606

3. 内存分区以及程序运行过程中,各个分区占用情况

内存可以分为5个区域

image-20241031192743751

  • 栈区

    用于放局部变量、参数、返回地址,在函数结束时释放

  • 堆区

    用于动态分配内存,由我们手动释放,比如mallocnew

  • 数据段

    存放已初始化的全局变量和静态变量

  • BSS段

    存放未初始化的全局变量和静态变量

    在程序加载时自动初始化为0

  • 代码段

    存储计算机需要执行的代码,也就是我们写的程序

如何动态分配内存?

在C语言中,我们学过用malloc动态分配内存,c++里面我们可以用new一段内存出来

int *x = new int;  //为指针b分配了一个整型的空间
int *array = new int[100] //新建了一个数组大小为100的整型数组

如何释放分配的内存?

注意在不需要使用内存或者函数结束的时候需要我们手动释放内存,这就需要delete函数来释放内存了

delete x;
delete[] array;

指针

  • 指针是用于存储其他变量的地址的变量

    int a = 10;
    int *p = &a; //&取地址
    

image-20241031195127130

  • * 符号 ,解引用

    • 号的使用主要在两个地方,声明指针的时候和对指针解引用的时候
    什么是解引用?

    解引用就是访问指针所指向的地址的数据

  • 通过指针解引用来访问被指向的变量或者变量的地址

    int a = 10;
    int *p = &a;
    *p = 100;
    cout<<a<<endl;
    
  • 指针也能用来指向一段内存空间

    int *arr = new int[100];
    arr[10] = 2;
    
  • 为什么指针算数和数组是等价的

    指针算数:

    int p[100];
    *(p + 10) = 2;
    cout<<*(p + 10)<<endl;
    

    数组:

    int p[100];
    p[10] = 2;
    cout<<p[10];
    

    等价的原因是在c++内部处理指针算数的方式

    我们对一个指针变量+1,指针增加的数量等于它指向的变量类型的字节数,在数组中的表现就是从p[0] 增加了一个整型的空间 变成了p[1];

    *(p + 10)就是增加了10个整型空间变成了p[10]

    image-20241031211753404

  • 对数组取地址

    int arr[100];
    cout<<arr<<endl; //这个输出的arr[0]
    cout<<&arr<<endl; //这个输出的是整个数组的地址,虽然输出的地址和arr[0]的地址是一样的,在含义上它代表的是整个数组的地址
    

    *arr指针的数据类型是int **

    &arr的数据类型是 int (*) [10]

    两者虽然输出一样但是含义不一样

  • 野指针

​ 野指针是指没有初始化的指针变量,没有指向合法的内存空间

  • 悬空指针

    悬空指针是指针指向的变量被delete掉了

 int *p = new int;int *pp = p;delete p;

这里我们为p分配了一个int大小的空间,让pp指向指针p,然后我们把这段空间释放掉,pp就没有指向了,成为了悬空指针,也是一种野指针

  • 指针数组

    int* p[10];
    int a = 100,b = 20,c = 30;
    p[0] = &a,p[1] = &b,p[2] = &c;
    

    和int p[10] 一样,int* 表示的后面数组p[10]的数据类型,数组每一个位置都是一个指针

  • 数组指针

    数组指针就是指向数组的指针

    屏幕截图 2024-11-02 113825

    int arr[20][20];
    int (*p)[10] = arr;//意思是p这个指针指向的空间大小是10
    

    这个与指针数组的区别就是在* p这里多了一个括号,但是含义就差别很大了

  • 指针函数

    指针函数是返回值是指针的函数,有了这个我们可以方便的动态分配内存给数组

    int* getArray(int size)
    {int *arr = new int[size];return arr;
    }
    
  • 函数指针

    #include<iostream>
    using namespace std;int add(int a,int b) // 两数相加函数
    {return a + b;
    }int subtract(int a,int b) //两数相减函数
    {return a - b;
    }int multiply(int a,int b)//两数相乘函数
    {return a * b;
    }int main() {int (*p)(int ,int) = NULL;char c;cin>>c;switch(c){case('-'):p = subtract;break;case('+'):p = add;break;case('*'):p = multiply;break;};int a,b;cin>>a>>b;cout<<p(a,b);return 0;
    }
    

    函数指针定义格式是:

    函数类型 ( 指针名) (指向的函数的数据类型)* 以函数int add(int a,int b)举例,指针就是 int ( p) (int, int) = add;*

    和指针函数的区别:

    • 和指针函数相比多了个括号 如果少了括号就容易被识别成函数指针
    • 括号里面只有变量类型,没有变量名

引用

  • 概念:引用是为已存在的变量取了一个别名,引用引用的变量共用同一块内存空间**

    例子:int &a = b;后面直接可以用a代替b;

  • 引用的性质

    • 引用在定义的时候必须初始化
    • 一个变量可以有多个引用
    • 一个引用也能有引用
    • 引用一旦引用一个实体,不能再引用其他实体
    • 可以对任意类型进行引用
    引用在定义时必须初始化
     int &b;int a = 10;b = a;
    

    这种是错误的

    int a = 10;
    int &b = a;
    

    在定义的时候就要初始化

    一个变量可以有多个引用
    int a = 10;
    int &b = a;
    int &c = a;
    
    一个引用也能有引用
    int a = 10;
    int &b = a;
    int &c = b;
    

    一个引用也能被引用

    引用一旦引用一个实体,就不能再更改
    int a = 10,c = 20;
    int &b = a;
    b = c;
    

    这种是错误的

    可以对任意类型进行引用

    以函数的引用为例子,我们这里要引用一个add加法函数,它的两个参数都是int类型,我们定义函数引用的时候也要遵循函数的参数类型

    int add(int a,int b)
    {return a + b;
    }
    int main()
    {int (&p)(int,int) = add;return 0;
    }
    

    函数引用的定义方式和我们的函数指针类似,都是括号里面指针名或者引用名,后面再加上函数的变量类型

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaweb基础总结

截至目前还差最后一个案例 最后再重写一遍所有功能即可 但也包括一些新的功能 学习笔记如下图 一大半代码还是自己敲得 摸样的话大部分都是这样的

【牛客训练记录】牛客周赛 Round 66

训练情况赛后反思 目测 D、E是什么神秘线段树数据结构题吧,没有做出来,还得加练。 A题 先三个数排序,要么那最大的,要么拿两个较小的和,答案取大值即可。 #include <bits/stdc++.h> #define int long longusing namespace std;void solve(){int a[3];cin>>a[0…

【通用简历模板】简洁清爽通用求职简历模板下载

【通用简历模板】简洁清爽通用求职免费简历模板下载,Word【可编辑】,个人简历,免费简历​通用简历模板下载 ​ 简洁清爽通用求职简历免费下载,可编辑WORD格式简历模板免费下载直接修改,高效-便捷-实用,满足求职者的简历制作需求,简历编辑制作不求人,有效提升求职效率!…

一款开源简洁高颜值的酷狗第三方客户端V1.0.0 Beta

MoeKoe Music前言 早在10年前后的样子,那会在用网页版QQ的时候我就已经开始使用酷狗音乐了(也是十来年的老粉了),所以这些年收藏的歌曲全部都在上面.后来我也尝试开始使用网易云或QQ音乐,也尝试把酷狗的歌单导入进去,但是效果都不尽人意.我听的大多是日漫OP,好多歌曲都没办法找…

计量经济学(十六)——工具变量法

img { display: block; margin-left: auto; margin-right: auto } table { margin-left: auto; margin-right: auto } 在经济学和其他社会科学的研究中,研究人员经常希望通过观察数据来推断因果关系,以理解变量之间的影响机制。然而,实际数据往往受到多种因素的干扰,使得自…

『模拟赛』NOIP2024模拟1(更新 T2 T4)

『模拟赛记录』NOIP2024模拟1Rank 有点可惜,A. 玩游戏 绝妙贪心题。感觉这种能产生很多假做法且都可 hack 的贪心都是好题。 赛时不知道为什么犯唐没交一开始的暴力贪心。 考虑双指针,设左右指针分别为 \(l,r\)。主要思路是实时维护当前两个指针向两边最近的一个区间和不为正…

西电校园网基于 PPPoE+DHCP 方式实现带宽叠加

前言 由于个人对宿舍内局域网有一定需求,于是考虑在宿舍内配置一台路由器来搭建局域网。 而又因为西电的校园网有如下一些性质:一个免费账号可以同时在线 3 台设备,每台设备限速 100M。 校园无线网通过深澜 Portal 认证方式在设备连接到校园网 AP 且在网页端登录后以 DHCP 方…

博客园美化-Awescnb主题

本文主要记录安装Awescnb皮肤的安装过程,以及我做的配置,作为备份。一、安装皮肤 安装超级简单,根据官方文档,一分钟就搞定。首页HTML: <div id="loading"><div class="loader-inner"></div></div>页面定制CSS: #loading{bo…

数据库实验三:创建和管理数据表

数据库实验三:创建和管理数据表 惠州学院 《数据库应用》课程实验报告 实验题目: 实验三:创建与管理数据库 姓名: 曹锐旋 学号: 230703030 班级: 23 电子信息工程(3)班 指导教师: 黄冲 ‍ 一、实验目的掌握 SQL Server 中使用 T-SQL 语句创建…

【vjudge训练记录】11月个人训练赛1

训练情况赛后反思 被小数据背刺了,吃了几发RE,不过还是调出来了 A题 我们先考虑将连续的 v 先换成 w,之后就是统计子序列 wow 的个数,我们只需要找每个 o 前面有多少个 w,之后有多少个 w,根据乘法原理可知,这个 o 对答案的贡献就是两个相乘,维护前面和后面的 w 我们可以…

数据采集和融合技术作业3

作业①: 1)指定一个网站,爬取这个网站中的所有的所有图片,例如:中国气象网(http://www.weather.com.cn)。使用scrapy框架分别实现单线程和多线程的方式爬取。 代码解析 weather_spiders.py文件 解析起始页面 def parse(self, response):urls = response.xpath(//div[@cla…

19-操作系统安全保护

19.1 概述 1)概念 一般来说,操作系统的安全是指满足安全策略要求,具有相应的安全机制及安全功能,符合特定的安全标准,在一定约束条件下,能够抵御常见的网络安全威胁,保障自身的安全运行及资源安全。 操作系统的安全可控目标分为两个层面:第一个层面,是指给定一个操作系…