C语言指针:内存和指针 初识指针一、内存和地址1. 内存2. 地址二、认识指针1. 取地址2. 指针和指针变量⭐⭐⭐(2) 指针的类型⭐3. 解引用操作符4. 指针变量的大小⭐一、内存和地址1. 内存●在计算机的组成结构中有一个很重要的部分就是存储器。存储器是用来存储程序和数据的部件对于计算机来说有了存储器才有记忆功能才能保证正常工作。存储器的种类很多按其用途可分为主存储器和辅助存储器主存储器又称内存储器(简称内存港台称之为记忆体)。●内存又称主存是CPU(中央处理器)能直接寻址的存储空间由半导体器件制成。内存的特点是存取内存速率快。●内存就是暂时存储程序以及数据的地方。举一个例子假设有一栋宿舍楼你的同学就住在这栋宿舍楼里如果有一天你想去找他玩但这栋楼的房间都没有编号你的同学也不好描述他所在的宿舍位置你就只能挨个房间去找。如果这栋宿舍楼有100个房间最坏的情况你可能会找100次房间才会找到你的同学。但是如果我们给宿舍楼里的每层每间房都编一个号比如三层二号房302六层十四号房614。这样你同学提前告诉你他在614号房间你就可以很快高效的找到你的同学。计算机中内存也是像宿舍楼这样将内存划分为一个个的内存单元每个内存单元的大小取1个字节。计算机中常见内存单位的换算每个内存单元就像一间学生宿舍一样1个字节空间里有8个比特位就好比一间宿舍住八个人一样。一个比特位上存储的是二进制的0或者1。2. 地址每个内存单元都有一个编号(这个编号就相当于宿舍房间的门牌号)有了这个内存单元的编号CPU就可以快速找到一个内存空间。生活中我们把门牌号也叫地址在计算机中我们把内存单元的编号也称为地址。C语言中给地址起了个新名字叫:指针。由上图每个字节都对应着一个编号也就是地址。所以我们可以理解:内存单元的编号地址指针。关于计算机中地址的深入学习请参看下面。https://blog.csdn.net/m0_62183318/article/details/137638845二、认识指针1. 取地址在理解了内存和地址的关系之后在C语言中创建变量其实就是在向内存申请空间例如#includestdio.hintmain(){intn10;return0;}上述的代码就是创建了整型变量n向内存申请了4个字节的空间用于存放整数10其中每个字节都有地址上图中4个字节的地址分别是:1 0x00D3F7102 0x00D3F7113 0x00D3F7124 0x00D3F713上面是如何得到变量n的地址的呢这里要用到一个取地址操作符。#includestdio.hintmain(){intn10;n;//取出n的地址printf(%p\n,n);//%p是专门用来打印地址的占位符return0;}这里是小端字节序存储也就是这个整型变量的低位字节排放在内存的低地址端以后会解释这个知识点的。由上面的代码对变量n取地址然后打印会得到这个变量的地址为0x00D3F710(开头的0x表示十六进制)由此可知n取出的是变量n所占4个字节中地址较小的字节地址。虽然整型变量占4个字节但只要知道了第一个字节的地址后面三个字节的地址也就可以顺势知道了这样就能访问4个字节的数据了。2. 指针和指针变量⭐⭐⭐(1) 通过取地址操作符()拿到的地址是一个数值比如上面n的地址00D3F710这个数值有时候也是需要被存储起来的方便后期再使用我们把这样的地址值存放在指针变量中。#includestdio.hintmain(){intn10;int*pnn;//取出n的地址并存储到指针变量pn中return0;}只要记住用来存放地址的变量就叫指针变量。通常我们叙述时会把指针变量简称为指针但实际他们的含义不同指针就是地址。但我们单独说指针变量时他是一个变量其中存放的是其他变量的地址他是可变的。通过上面的代码来说明●1.指针— —即地址比如上面的n就是变量n的指针一个变量的地址称为该变量的指针。通过变量的指针能够找到该变量。nn的地址或者叫n的指针●2.指针变量— —专门用于存储其他变量地址的变量比如上面的指针变量pn的值就是变量n的地址指针与指针变量的区别就是变量值与变量的区别。假设现得到变量n的地址为0x0118F704则pn0x0118F704(2) 指针的类型⭐指针也是有类型的那要如何理解指针的类型呢就比如上面的int* pn n:intn10;int*pnn;指针变量pn的左边是int*即pn的类型其中*号是在说明pn是一个指针变量前面的int是在说明pn指向的是整型(int)类型的对象。假设这里得到n的地址为0x0118F704所以这里pn的类型是int*pn存储了n的地址我们就说pn指向了n。上图中指针变量pn也是有自己的地址的只是这里没有给出后面讲二级指针时会说明。类似的如果要存放一个字符类型变量的地址charchq;char*pcch;指针变量前的*号不管是挨着类型名、挨着变量名或是单独空出来都没有影响都是一样的意思。3. 解引用操作符我们将地址保存起来未来是要使用的那要怎么使用呢?在现实生活中我们使用地址要找到一个房间在房间里可以去拿或存放物品。C语言中其实也是一样的我们只要拿到了指针(地址)就可以通过指针找到指针指向的对象这里要学习一个操作符叫解引用操作符(*)。#includestdio.hintmain(){intn10;int*pnn;*pn20;return0;}上面的代码中*pn 20就使用了解引用操作符*pn的意思就是通过pn中存放的地址找到指向的空间*pn就等价于变量n所以*pn 20即把n的值改成了20。那为什么不直接对n赋值改掉n的值而要通过指针解引用来赋值呢其实这样就多了一种修改变量值的途径写代码就会更加灵活。后面在学习函数传址时会深入理解这里的知识。4. 指针变量的大小⭐(1) 因为指针变量是用来存储地址的所以指针变量的大小取决于地址的大小。通过对计算机中地址的深入学习可知在32位机器下假设有32根地址总线每根地址线发出来的电信号转换成数字信号后是1或0那我们把32根地址线产生的2进制序列当做一个地址那么一个地址就是32个bit位8个bit位为一个字节需要4个字节才能存储。如果用指针变量来存放地址那么指针变量的大小就得是4个字节的空间才可以。同理在64位机器下假设有64根地址线一个地址就是64个二进制位组成的二进制序列存储起来就需要8个字节的空间指针变量的大小就是8个字节。#includestdio.hintmain(){//32位平台下地址是32个bit位(即4个字节)//64位平台下地址是64个bit位(即8个字节)printf(%zd\n,sizeof(char*));printf(%zd\n,sizeof(short*));printf(%zd\n,sizeof(int*));printf(%zd,sizeof(double*));return0;}上面的代码在32位平台下运行结果上面的代码在64位平台下运行结果总结●32位平台下地址是32个bit位指针变量大小是4个字节●64位平台下地址是64个bit位指针变量大小是8个字节●指针变量的大小和类型是无关的只要是指针类型的变量在相同的平台下大小都是一样的。