C语言指针详解(这个看懂了,你的C语言不会差)

都说C语言最重要的是指针,其实本质上也就是对内存的理解。

那好,我们就从内存上开始谈。

首先,我们知道数据在内存中是以二进制进行存储的,二进制包括0和1。而为什么以二进制进行存储是因为机器只能识别电信号,而电信号只有正电和负电之分。

下面谈一下内存的存储单元问题

在内存中的最小存储单元是bit,也叫比特,比特位,位,都是一个意思。

而在一个bit中能够存储的内容就是一个0或者一个1。

8个比特位为一个字节,一个字节也叫做Byte。再往上就是KB,MB,GB。

1KB = 1024Byte     1MB = 1024KB    1GB =1024MB

不过这些大的存储单位我们不常用到,对于程序员最常用的是字节(Byte)和位(bit)。

------------------------------------------------------------------

上面对内存的存储单元 有所了解,接下来我们 来聊一下地址这个概念。

在程序中我们知道,每一个变量,每一个函数,每一个数组都有它的地址。但地址究竟是个什么东西?

我们知道 32位机器的地址是32位,64位机器地址是64位,其实这是由地址线的数量来决定的,而地址线是物理上的存在。那么地址的作用是什么?其实是我们可以通过这个地址来访问地址指向的这块空间(这里就有点指针的意思了,别急我们继续往下聊)。

ok,那这样计算的话32位机器我们可以分配多少个地址呢?是2^32个。(64位同理)

那假如我们为每一个bit位分配一个地址,则内存总大小为2^32bit,不过后来专家们觉得这个可使用空间有点小,于是最终决定为每一个字节分配一个地址,则32位机器可访问空间就变为了2^32Byte,一下子可用空间就变成了原来的8倍。

了解到这里我们已经知道,每一个字节空间都会有一个对应的地址。

----------------------------------------------------------------------

下面我们来说C语言的数据类型

举个例子:int 代表整型   char 代表字符型,这是最基本的理解,但其实更重要的是 这两种类型所代表的空间大小。int 代表4个字节,char代表1个字节。

我们联系到指针上来,继续举例:int a = 0x12345678;   这条语句的意思是,我们开辟了4个字节的空间用来存储0x12345678这个十六进制数据。0x12345678转换为32位二进制为00010010 00110100 01010110 01111000,到这里会涉及到一个大小端存储的问题,这里我不细讲,简言之以小端存储为例这个数据在内存中具体的存储顺序为01111000 01010110 00110100 00010010 ,每个字节翻译成十六进制就是 0x78 ,0x56,0x34,0x12。

现在,在a这个变量里面每一个字节存储的数据,我们都清楚了。下面我们通过指针来读取数据。

在此之前说一下指针的用法,举个例子:int * p ;(忽略野指针)  这条语句的意思是创建一个指针变量p,这个指针所指向空间的数据类型是int,注意:* 说明了p是一个指针类型,int说明的是p指针所指向空间的数据类型。

接下来我们将a的地址赋给p指针,p = &a;  我们知道如果想取得a的值可以通过解引用的方式,即*p  ,这样我们就可以得到a这个变量的数据。此时我们知道p指针的类型为int* ,所以我们通过 * 这个解引用符,可以读取4个字节的空间,这个道理需要明白。那假如我们将 p指针的类型强制转换为 char* 又会发生什么呢?没错,我们可以一个字节一个字节的去读取数据。下面为演示代码

---------------------------------------------------------

下面为强制转换后,读取数据

 

 

这样我们就通过指针读出了第一个字节的数据,那我们可以不可以读第二个,第三个字节的数据呢?当然可以! 别忘了每一个字节都会有一个地址。

只要我们在p2这个指针变量上加1,就可以访问第二个字节的数据,第三第四个字节以此类推。下面是代码

 

---------------------------------------------------------------------

那么问题来了,如果我们用p指针能不能做到一个字节一个字节的访问?答案是不能,原因是p的指针类型为int* ,这意味着p指针每次加1,它都会跨越4个字节,如果用*(p+1)就会造成越界访问,因为我们不知道变量a后面的存储空间是什么状态。下面为代码演示

 

 

此时虽然没有报错,只能说变量a后面的空间存有数据,但这个数据明显不是我们想要的。如果后面的空间没有被使用,此时你解引用就会报错。

好了,文章暂时就写到这里啦,要说的东西太多,一下子说不完,哈哈

ps:如有不当之处,欢迎指正哦

 

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值