《算法笔记知识点记录》第二章——快速入门3[函数、指针](2)

简介: 《算法笔记知识点记录》第二章——快速入门3[函数、指针](2)

⚔️1.2 指针

🗡1.2.1 指针究竟是什么

先放上一张神图。大名鼎鼎的冯·诺伊曼体系结构。

f1cd2a5bfc609f263827fa98b112aa5.png

可以发现运算器能直接读取的程序是在存储器内的。那么运算器怎么拿到这个数据呢?

首先我们先明确,因为变量的读取都是从内存中的,所以一定会有一片空间在内存中。我们把它想象成有一栋公寓有一堆房间,我们想要找到我们的房间是不是得有个房间号?

19e66112d35f74aec6ad8735baae5c0.png

然后有没有发现102 103 104 105这四个房间我没画隔断,因为很多地方是按照门来编号的,但是一个大房间可能对应多个门呀。


上面的门的编号方式就是编制方式(可以一个门一个号,也可以两个门一个号),地址就每个门的房号,然后数据其实就是门内的内容。

我们根据房号找到家,计算机就是根据地址找到数据。

指针其实就是地址。也就是上面的房号。

我们假如忘了门号就看看外面门上的标识牌对吧?计算机内如果变量想要直到自己的地址也是需要看看自己的房号,怎么去看呢?用&,因为是变量自己看所以就是&x就拿到地址啦0.0

举个例子:


#include<cstdio>
int main(){
  int a = 0;
  printf("%d %d\n", &a,a);
  return 0;
}


输出结果可能是:2686748 1

其中地址是一个unsigned类型的整数(64位是unsigned longlong),至于为啥是无符号的,你见过谁家房号是负数么0.0


🛡1.2.2 指针变量

指针变量用来存放地址,然后可以看下图,就是指针变量,比较厉害,手里有把钥匙,并且这个钥匙可以开对应的门。

3e8c49fe11326fb3a28a7379bf626d1.png

然后由于这是一把钥匙,所以在声明它的时候需要在它前面加个*,表示它是一把钥匙。也就是int *p;,一般来说都是把*放在变量前面。

同时*也表示拿钥匙开门,*p就表示拿到对应的数据,所以图上的就是104号房间对应的元素。

刚才知道&是取地址,就是看看房间号,那么p = &a就可以把p这把钥匙变成a所对应的地址。此时再去*p就是a的值。

看下面的程序:


#include<cstdio>
int main(){
  int a;
  int *p = &a;
  *p = 233;
  printf("%d %d", *p, a);
  return 0;
}


输出结果是233 233,因为开房间的优先级很高,在赋值的时候是先打开门,再把数据写入,所以就把值写入到了a之中。最后输出就是两次a的值。


最后说明一下,不同的指针是不同的,比如下面的两把钥匙是不一样的。因为102-105是连着的,所以第一把钥匙钥匙+1实际地址会加4,而右边的指针对应的只有一个门,+1的时候只会加1,

其实对应的就是int *和char *类型的指针,其中一个长度为4,另一个为1。

这个指针的类型叫做基类型。

1cbadd7e38a885bd2da3b3b779fe02a.png

🔧1.2.3 指针与数组

之前有提到过数组就是一片连续的空间,数组名称也作为数组的首地址使用。

1fde4e5bca26b6dd29d5dd8442c28e2.png

根据上面提到的指针加1等于加对应的数据长度,所以a+i和&a[i]是完全相同的。

在枚举元素的时候可以这么写:


#include<cstdio>
int main(){
  int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  for(int *p = a; p < a +10;p+)
  printf("%d ",*p);
  return 0;
}


指针的减法


#include<cstdio>
int main(){
  int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  int *p = a;
  int *q = &a[5];
  printf("p = %d ", p);
  printf("q = %d ", q);
  printf("q - p = %d",q - p);
}


输出结果是:p = 2686688 q = 2686708 q - p = 5

会不会感觉震惊?这个q-p竟然不是20???,其实指针的减法是计算两个指针直接差多少个基类型,因为是int所以返回的就是相差多少个int。

⚒1.2.4 使用指针变量作为函数参数

指针变量也可以作为函数的参数,这时会把变量的地址传入函数。如果在函数中对这个地址中的元素进行修改,那么原本的数据也会修改。

例如:


#include<cstdio>
void swap(int *a, int *b){
  int temp = *a;  
  *a = * b;
  *b = temp;
}
int main(){
  int a = 1, b = 2;
  swap(&a,&b);
  printf("%d %d",a , b);
  return 0;
}


结果就是2 1,是不是就做到了?但是为啥呢?我们来看看这个过程

ee71f3e4c41a867feb2ee288f544e4c.png

可以发现在执行的过程中,swap直接改的就是原内存空间的值,当然改成功啦0.0


我们再看一个错误写法:


void swap(int *a,int *b){
  int *temp = a;
  a = b;
  b = temp;
}


这个如果看图就是讲swap调用栈里的a和b的值改了,并没有对之前的a和b造成任何影响。


🔨1.2.6 引用

引用是C++中一个强有力的写法,引用时候不产生副本,只是给原变量起了个别名。对引用变量的操作就是对原始变量的操作。

看一个例子:


#include<cstdio>
void change(int &b){
  b = 1;
}
int main(){
  int x = 10;
  change(x);
  printf("%d\n",x);
  return 0;
}


上面打印的结果就是1。

其实底层实现的话就是使用的指针,我猜想应该是使用的不可修改指针进行实现的。感兴趣的话可以看看这篇博客。理解C++中引用的底层实现


但是要注意:


#include<cstdio>
void swap(int &a, int &b){
  int temp = a;
  a = b;
  b = temp;
}
int main(){
  int a = 1, b = 2;
  swap(&a,&b);
  return 0;
}


上面的写法会直接报错,因为a和b的地址都是常量,所有声明的变量的地址都是常量不可进行修改!!!所以引用的时候不能传入变量的取地址。


关于指针的一些知识点我写了一篇文章做总结,如果大家有兴趣的话可以去阅读一下,保证会有更深的理解0.0

关于室友收租懂了指针那点事


🐳课后习题

今天的题目难度也不高,也不老多 哈哈哈哈哈,我写完会放题解,大家写完了可以在评论区打卡哟!我觉得,题解我放评论区吧,这样不用修改文章。(大家有问题可以联系我,今天太晚了,题解等明天把)


题目

2.6小节——C/C++快速入门->函数

2.7小节——C/C++快速入门->指针


相关文章
|
21天前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
21天前
|
存储 搜索推荐 C语言
如何理解指针作为函数参数的输入和输出特性
指针作为函数参数时,可以实现输入和输出的双重功能。通过指针传递变量的地址,函数可以修改外部变量的值,实现输出;同时,指针本身也可以作为输入,传递初始值或状态。这种方式提高了函数的灵活性和效率。
|
1月前
|
算法 API 计算机视觉
人脸识别笔记(一):通过yuface调包(参数量54K更快更小更准的算法) 来实现人脸识别
本文介绍了YuNet系列人脸检测算法的优化和使用,包括YuNet-s和YuNet-n,以及通过yuface库和onnx在不同场景下实现人脸检测的方法。
31 1
|
1月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
56 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-160、相交链表)
❤️算法笔记❤️-(每日一刷-160、相交链表)
17 1
|
1月前
|
数据可视化 搜索推荐 Python
Leecode 刷题笔记之可视化六大排序算法:冒泡、快速、归并、插入、选择、桶排序
这篇文章是关于LeetCode刷题笔记,主要介绍了六大排序算法(冒泡、快速、归并、插入、选择、桶排序)的Python实现及其可视化过程。
13 0
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
30 0
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-26、删除有序数组的重复项)
❤️算法笔记❤️-(每日一刷-26、删除有序数组的重复项)
23 0
|
22天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
7天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。