C语言学习之路
第一章 初识C语言
第二章 变量
第三章 常量
第四章 字符串与转义字符
第五章 数组
第六章 运算符
第七章 指针
前言
在前面几章的学习中,我们通过数组和字符串了解到了地址的概念。那么本章我们将对地址的概念深挖,从而初次认知指针的存在。
一、什么是地址
(1)引入:
在生活中,当我们去在网上购买东西时,我们会在下单的界面输入我们的家庭住址。这样做的目的就是让快递员能够精准地将快递送到我们的家中。
那么在计算机中也采用了同样的原理,当我们创建一个变量后,计算机就会将这个变量存储起来,那么这个变量所存储的位置就会对应一个地址。那么这个地址的作用就是,当我们对该变量进行某些操作时,计算机能够通过地址精准地定位该变量,并对其进行运算。
(2)地址的创建原理:
我们知道,在一台计算机中存储着庞大的数据,那么这些数据的地址是如何做到不重复,这些地址又有什么规律呢?同时,一个最小的内存单元又是多大呢?
a、编号原理:
我们在使用我们的电脑时,我们会发现两个特别的数字,有的电脑是32位,有的电脑是64位,那么这两个数字的背后是什么含义呢?
我们以32位为例,32位指在电脑内部有32根地址线,这些地址线是真实存在的,那么每一根线的通电状况分为两个状态,0或者1。那么根据我们高中学的乘法原理,这32根地址线的状态共有232种,同时其状态所对应的二进制序列就有232种。那么这些序列就称为了编号,也就是我们所说的地址。
b、内存单元:
当我们了解了地址的由来,我们知道我们能够管理232个内存单元。那么每个内存单元的大小是多少呢?
我们可以假设每个存储单元是一个比特。那么这个时候,我们想,232个比特,那么我们将其转换一下:
也就是说,倘若把一比特作为最小的存储单元,那么其存储的大小为0.5gb。这很明显太小了。不仅小,也过于详细。就好比,在填写地址时,没有人会写上自己的经纬度。
因此,我们为了解决这个问题,我们就将一个字节作为了最小的存储单元。那么我们在进行
一次换算:
最后这个结果大家是否熟悉呢?我们大家的游戏本,基本上都是512个GB的大小。
因此,我们就明白了,地址编号来自于地址线所对应的二进制位序列,而每一个最小的内存单元是一个字节。
2、指针
(1)指针的定义:
有了地址的概念,我们就能够了解到每一个变量都对应着一个地址。于是就出现了一个叫做指针变量的东西,来存储这个地址。那么有了这个指针我们就能够精准的找到对应的变量,并对其进行操作。由此,我们就能够定义什么是指针。
指针就是地址。
(2)语法:
int a = 0;
int* p = &a; //变量的数据类型 * 指针名称 = & 变量名称
*p = 20;
printf("%p\n",p);//地址的占位符是%p
printf("%d\n",*p);
变量的数据类型,和指针定义前面所写的数据类型保持一致。然后再后面补充一个*
,接着写下这个指针名称。那么在赋值操作符的右侧,我们要写下&变量名称
这个符号叫做取址符。
那么这个代码的背后含义就是,我们重新创建了一个变量,这个变量存储内容是一串地址。
因此,我们发现,指针其实也是一种变量。只是其存储的内容是地址而已。因此指针又称为指针变量。
那么如果我们想要通过指针找到对应的数据,则需要解引用的操作。即*p
。这样我们就通过指针对变量a进行访问了。
这时候,我们如果打印的是p
,那么结果就是a的地址
如果打印的是*p
则打印的是a的数据内容。
另外,我们知道一个整形数据所占的内存大小是4个字节,但是每一个字节都有一个地址,难道a的地址是四个一起的吗?其实,真实情况是,a会占据一个连续的内存空间,这段内存空间由四个字节组成。而它的地址就是第一个字节的地址。
图解:
(3)指针的大小:
既然我们创建了一个指针变量,那么它的大小又是多少呢?
我们可以采用计算的方式,根据开头对地址编号的介绍,32位的电脑中,我们知道地址对应的二进制序列有三十二位,而每一位都是一个比特。因此就是4个字节。
同样,我们也可以用代码计算:
sizeof(p);//4
我们要注意的是,指针的大小和其前面的数据类型是无关的,因为无论前面的数据类型是什么,其地址都是那一串二进制数。
但是根据刚才的图示内容,我们发现,a和b的地址并不是二进制。这是因为我们打印出来的是十六进制的表示方法。
总结
以上就是我们对指针的初步认识。通过本章节的学习,希望各位能够对指针有一个初步的了解和应用。