首页 > 其他分享 >深入理解指针(一)

深入理解指针(一)

时间:2024-09-08 18:21:56浏览次数:6  
标签:字节 int 理解 地址 pa 深入 内存 指针

1.内存和地址

1.1内存

在讲内存和地址之前,我们想有个生活中的案例:

假设有一栋宿舍楼,把你放在楼里,楼上有100个房间,但是房间没有编号,你的一个朋友来找你玩儿,如果想找到你,就得安一个房子去找,这样效率很低。但是我们如果根据楼层和楼层的房间情况,应每个房间边上号有的房间号,如果你的朋友得到房间号,就可以快速地找房间找到你。

生活中每一个房间有的房间号就能提高效率,能快速的找到房间。

如果把上面的例子对照到计算中又是怎么样的呢?我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中。那我们买电脑的时候,电脑上有内存是8GB/16GB/32GB的。但这些内存空间如何高效的管理呢?

其实也是把内存划分为一个个的内存单元,每个内存单元的大小取一个字节。

计算机中常见的单位:

  1. bit - 比特位                         1byte = 8bit 
  2. byte - 字节                          1KB=1024byte
  3. KB                                      1MB=1024KB
  4. MB                                      1GB=1024MB
  5. GB                                       1TB=1024GB
  6. TB                                        1PB=1024TB
  7. PB

每个内存单元相当于一个学生宿舍的一个人。自己的空间里面能放八个比特位,就好比同学们住的八人间,每个人是一个比特位。

每个内衣寸单元也都有一个编号。这个编号就相当于宿舍房间的门牌号。有了这个内存单元的编号,CPU就可以快速找到一个内存空间。

内存
0XFFFFFFFF1个字节
0XFFFFFFFE1个字节
1个字节
1个字节
0X000000011个字节
0X000000001个字节

                                     生活中我们把门牌号也叫地址在计算机中,我                                       们把内存单元的编号也称为地址。C语言中给                                       地址起了新的名字叫指针。

                                     所以我们可以理解为:

                                     内存单元的编号==地址==指针

2.指针变量和地址

2.1取地址操作符(&)

比如上述代码就是创建了整型变量。a内存中申请四个字节用于存放整数0X11223344,其中每个字节都有地址(一个字节一个地址)。

0X表示16进制,即11223344是个16进制数。

1个字节是8个比特位,一个比特位可以存放一个二进制数,即一个字节可存放16个二进制数,进而我们可以推断出,一个字节可以存放两个16进制数,11223344有8个16进制数,int是4个字节,所以11223344正好被分成四份放在内存中。

那我们如何能得到a的地址呢?

这里就学习一个操作符(&)-取地址操作符

#include<stdio.h>
int main()
{
int a=10;
&a;
printf("%p\n",&a);
return 0;
}
内存
0XFFFFFFFF一个字节
0XFFFFFFFE一个字节
一个字节
0x006FFD73a
0x006FFD72a
0x006FFD71a
0x006FFD70a
0X00000001一个字节
0X00000000一个字节

按照我画图的例子,会打印处理:006FFD70

&a取出的是a所占字节中地址较小的字节的地址。

虽然仍型变量占用四个字节,我们只要知道第一个字节地址,顺藤摸瓜范围,问到四个字节的数据也是可行的。

2.2指针变量和解引用操作符

2.2.1指针变量

那我们通过取地址操作符拿到的地址是一个数值,比如0X006FFD70这个数值有时候也是需要存储起来,方便后期再使用的。那么我们把这样的地址存放在哪里呢?当然是指针变量中,比如:

#include<stdio.h>
int main()
{
int a=10;
int *pa=&a;//取出a的地址并存储到指针变量pa中

return0;
}

指针变量也是一种变量。这种变量就是用来存放地址的,存放在指针变量中的值都会理解为地址。

2.2.2如何拆解指针类型

我们看到的pa类型是int*,我们该怎么理解指针的类型呢?

int a=10;
int*pa=&a;

这里pa左边写的是int*,*是在说明pa是指针变量,而前面的int是在说明pa指向的是整型类型的对象。  

0x0012ff4010int类型
int a=10;a
int* pa=&a;
0x0012ff40int*类型
pa

同理,如下

char ch='w';
char*pc=&ch;

2.2.3解引用操作符

我们将地址保存起来未来是要使用的,那怎么使用呢?

在现实生活中,我们使用地址要找到一个房间,在房间里可以拿去或者存放物品。

C语言中其实也是一样的,我们只要拿到地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象。

这里必须学习一个操作符叫解引用操作符(*)。

#include<stdio.h>

int main()
{
int a=100;
int* pa=&a;
*pa=0;
return 0;
}

*pa的意思就是通过pa中存放的地址,找到指向的空间,*pa其实就是a变量了;所以*pa=0这个操作符就是把a变量的值改成0了;

也有同学肯定在想,这里如果目的就是把a改成0的话,写成a=0不就完了,为啥非要使用指针呢?

 其实这里是把a的修改交给了pa来操作,这样对a的修改就多了一种途径,写代码就会更加灵活。

2.3指针变量的大小 

上图是x64,8字节

上图是x86,4字节

结论:

  • 指针变量的大小是和类型无关的,只要指针类型的变量,在相同平台下,大小是相同的。
  • 32位平台下地址是32bit位(即4个字节)
  • 64位平台下地址是64bit位(即8个字节)

标签:字节,int,理解,地址,pa,深入,内存,指针
From: https://blog.csdn.net/2301_79924564/article/details/142022685

相关文章

  • 深入解析多智能体强化学习算法的训练效率
    深入解析多智能体强化学习算法的训练效率在多智能体强化学习(MARL)领域,不同算法的训练效率和最终性能差异显著。本文将深入分析几种主流MARL算法的训练特性,探讨影响其效率的关键因素。1.算法概览我们将讨论以下几种典型的MARL算法:VDN(ValueDecompositionNetworks)QM......
  • 深入理解线程池的运行流程
    序言:这篇文章主要记录了java线程池在一些特殊场景出现的奇怪问题。场景核心线程数量为2,最大线程数量为4,生存时间60s,任务队列大小为4。每次向线程池中提交8个任务执行。那么,这个线程池能否正常运行呢?1demo我们可以根据这个要求写一个demo出来publicclassDemo{stati......
  • 【C++11及其特性】智能指针——shared_ptr
    大家好,这里是国中之林!❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看←shared_ptr目录一.共享性智能指针二.shared_ptr的共享原理三.shared_ptr的构造函数1.普通的2.数组的3.带删除器......
  • 【C++】智能指针
    目录1.智能指针简介2. std::unique_ptr2.1.特点2.2.使用示例3. std::shared_ptr3.1.特点3.2.使用示例4. std::weak_ptr4.1.特点4.2.使用示例5.使用智能指针的注意事项5.1.选择合适的智能指针类型5.2.避免循环引用5.3.谨慎使用自定义删除器5.4.注......
  • 深入FastAPI:掌握使用多个关联模型的高级用法
    在构建RESTfulAPI时,经常需要处理复杂的数据关系。FastAPI通过支持多个关联模型,使得定义这些关系变得简单直观。这种方法不仅提高了代码的可维护性,还增强了API的灵活性。通过使用Pydantic库,我们可以轻松定义数据模型及其关联,从而在FastAPI应用中实现强大的数据处理逻辑。无论是一对......
  • 深入浅出:什么是日志技术?如何在项目中使用?
    深入浅出:什么是日志技术?如何在项目中使用?在软件开发中,日志技术就像一本记录系统“点点滴滴”的日记。系统运行时,它记录下关键事件——正常操作、异常情况都不会遗漏。日志不仅是开发人员分析系统行为的利器,还可以在项目出现问题时,帮助我们快速找到问题根源。那么,如何让系统“记日......
  • 算法专题一: 双指针
    目录前言1.移动零(easy)2.复写零(easy)3.快乐数(medium)4.盛水最多的容器(medium)5.有效三角形的个数(medium)6.和为s的两个数字(easy)7.三数之和(medium)8.四数之和(medium)前言常见的双指针有两种形式,一种是对撞指针,一种是左右指针。1.对撞指针:⼀般用于顺序结构中,也......
  • 深入掌握Go语言中的正则表达式与字符串处理
    Go语言中的正则表达式与模式匹配在编程中,字符串处理是常见的需求之一,而正则表达式则是一个强大的工具,能够帮助我们实现复杂的字符串匹配、提取和替换功能。Go语言内置了对正则表达式的支持,通过regexp包,我们可以轻松实现模式匹配的各种操作。本文将详细介绍正则表达式在Go语......
  • 滑动窗口系列(背向双指针)9/8
    一、好子数组的最大分数给你一个整数数组 nums (下标从0开始)和一个整数 k 。一个子数组 (i,j) 的 分数 定义为 min(nums[i],nums[i+1],...,nums[j])*(j-i+1) 。一个 好 子数组的两个端点下标需要满足 i<=k<=j 。请你返回 好 子数组的最大可能......
  • 重生之霸道C语言爱上我之走入指针(4)
    这次重生的内容比较难,如果大家有很简单的理解方式,欢迎指正。经过前面三次的指针学习,我们已经知道了关于指针的基础知识和一些指针运用,现在我们继续进行更深入的指针运用学习。1.字符指针变量在前面的学习中,我们学习了一个指针类型为字符指针char*。一般使用:intmain(){ ......