哈喽大家好,我是保护小周ღ,C语言,接下来给大家带来的是深入理解数组和指针的初识指针,这篇主要讲的是基础指针的相关知识,是博主的所见所闻,细节上的知识后面会这里面没有提,会放在后期的文章中与数组相结合讲,多多包含~
目录
我们怎么理解指针呢,博主刚开始学习指针的时候天真的以为指针会指向,我们也常常说指针指向了某一块空间,这样说其实是为了方便理解指针,接下来博主带你来好好感受一下指针的奥妙~
如果大家对计算机的存储有一定的了解就知道,我们的程序其实是加载到内存中运行的,那些定义的变量,指针,数组啥的实际上就是在内存上开辟的空间。那么地址的传输一般是根据地址总线来的,如果地址总线是32位,那么代表在一单位时内可以传输32个比特位的数据,也就是4个字节,这也是为什么在32位机 的环境下,指针是4个字节的部分原因,哪怕是读取一个char 类型的数据,也是一次性读取4个字节的空间,但是只会使用当前的有效一个字节的内容。同理在64位机的环境下理论上是CPU 有能力一次性访问 64个比特位 的数据 ,那么内存中的64 位如何理解呢 ,就是在32位的基础上翻了2倍,32位是4个字节,我们所说的64位就是8个字节,(实际上就是33个比特位描述) 所以64位的指针也是8个字节,因为此时的内存的编码翻了2倍,需要用8个字节来描述。我们电脑的内存其实是有限的。 32个比特位可以描述4G 的内存,33位就是8G ,34位就是16G , 64位那得多大,我们可没有那么大的内存。可千万不要说64位机,我的内存有 2^64 这么大,只能说在64 位机的环境下,我们的内存使用 8个字节来编码。我一次性可以读取8个字节的内容。
那么32根地址线产生的地址就会是:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
...
11111111 11111111 11111111 11111111
这里就有2的32次方个地址。
每个地址标识一个字节,那我们就可以给 (2^32Byte == 2^32/1024KB ==
2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB) 4G的空间进行编址。1Byte (字节)= 8 bit (比特位) ;
1KB =1024 Byte ;
1MB=1024KB;
1GB=1024MB;
这个类型后面添加 * 号,就相当于 告诉编译器这是个某类型指针。
所以指针是什么?可不可以理解为是一块4字节的空间(我这里假设指针是四个字节),实质是就是一块地址,我们常常说定义一个指针,其实说的就是指针变量,指针自身就是一块地址,然后我给他取了一个名字,给他指定了类型,那么这一块空间就可以存储相同类型的地址,我们的内存上的存储空间都是有自己的编码的,数据处理最基本的单位就是字节,所以每个字节都有自己的编码,这个就叫地址。(每一块地址都有自己独一无二的编码)
我们来分析分析,假如我们定义了 int 类型的指针变量 pa,我们还定义了一个局部变量a , 我们使用&(取地址操作符)取出变量a 的地址,整型数据其实是4个字节, 那么这四个空间的地址以其中的那一个字节地址为准呢?其实是首地址,就是四个地址最低位的为首地址,存放数据的时候从低地址往高地址存放。 我们知道了a 的地址,然后把这块地址给到指针pa 存储,你看 一个整型数据占4个字节,需要32 比特位来描述他的地址,所以一个整型指针也是4个字节。
总结:
指针变量就是用来存地址的!存放在指针变量的值都会被当成地址。
指针就是内存中的地址,指针变量就是用来存地址的。
不知道大家有没有发现一个点,就是一个 char 型的指针在内存中占4个字节,但是一个char 类型的数据占一个字节的空间,为什么char 类型的指针也需要4个字节呢,我们上面也说了,32 机,一次可以访问32位的数据,所以指针在32位的环境下占4个字节有利于存、取, 另外,在32位机的环境下需要4个字节来描述地址。
上面说到,我们常用的指针类型基本都是4个字节,而且某类型指针所占的大小好像跟某类型所占的大小不一样啊,那么为什么要有指针类型呢?明明都是4个字节,我要他有何用?
上图也可以进一步理解指针为什么是4个字节,哪怕他是一个结构体类型又怎么样,还是4个字节, 我们的指针只需要记住给这个结构体变量的划分的那片空间的起始字节的地址即可,然后就有能力访问,有朋友就要问了, 我们定义的结构体里面的成员 两个整型 8个字节,一个字符型 占一个字节,加起来应该是 9个字节,怎么就是12字节了呢,不难理解,上面也有讲过,32 位机的环境下,CPU 一次性可以读取4个字节的内容,9个字节要怎么读?还是要读取 3次,12字节,那干脆就多给这个结构体变量3个字节,是吧,大度一点,这个是简单的理解一下(粗略的理解),这个叫内存对齐,在不同的操作系统下,和不同的位数环境下,会有不同的表现,一般是4个字节的整数倍。
到这里我们总结一下,指针实际上就是内存上的地址,也有自己的地址编号,指针会把存储的数据当成地址来存储,就是这么设计的,指针在32位的环境下占4个字节,在64位的环境下占8个字节。
我们在上面也提到过指针的定义,类型 + ‘ * ’ + 指针名
- int a=0;
- int* pa=&a;
指针类型有什么用啊,整型指针也是4个字节,字符型指针也是4个字节,结构体指针也是4个字节,反正都是存地址的,地址又没有类型,要类型有何用?
我们来举个例子:
总结:指针的类型决定了指针向前或者向后走一步可以跳过几个字节。
整型指针+1,以当前存储的地址为基准,向高地址走4个字节,但是不会改变原先存储的地址,+2就是走8个字节咯。-1,以原存储的地址为基准,向低地址走4个字节。
上面说到,指针就是内存中的地址,指针变量就是用来存地址的,那我们存储地址就需要访问地址,我们能不能通过指针存储的地址,来操作那块地址中的数据呢?可以的!
先带大家了解一个操作符, ‘ * ’ 在定义的时候代表定义的是一个指针,在配合指针使用的时候就叫“解引用操作符” ,解引用是什么意思呢?举个例子。
今天是情人节,张三和自己的女朋友玩至深夜,女朋友是在太困了,就先说自己去开一间房睡觉,张三女朋友来到某某酒店(内存) 跟服务员(操作系统)说自己要一间房间,服务员看看了电脑哪里还有空房间,然后说520 房间可以使用(定义指针划分空间),随后张三对象打电话告诉张三说自己在某某酒店 520房间(地址),没关门,让他早点来休息,张三马不停蹄的来到 520 房间,果然没关门,张三此时知道女朋友在这间房间,推门而入,结果发现空无一人,张三直接糊涂了,明明女朋友给的地址是这里啊,发现床上有一个纸条,上面写的, 要想找到我,来 250 房间(对象的准确地址),去前台拿钥匙(解引用符号 ‘ * ’),别吵醒我,然后张三去前台拿到了要是然后 打开了250 房间的门,找到了女朋友。
以上故事 张三通过 520 房间(指针) 知道了女朋友的地址, 然后去前台拿钥匙 (解引用操作符 ‘ * ’ )打开了女朋友的房间。
所以 解引用操作符可以理解为,通过指针变量中存储的地址,找到该地址中存储的数据。既然找到了,那就可以修改。
总结:
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
另外大家一定对,使用char 类型的指针一个字节一个字节打印的数据是反着来的有疑惑,在vs 2019 的环境下数据是倒着存储的, 11 22 33 44 ,实际上存储的是 44 33 22 11 ,那我们的指针可不从 44 的那个位置访问吗? 至于为什么倒着存储,且听我慢慢道来:
根据上图,我们发现,我们的值以字节为单位(我们的存储单元最基本的单位就是字节),在内存中是倒着存贮的,嘶~,好奇怪啊。
一个数值超过1个字节,要在内存中存储,那就有了存储顺序的问题。
所以大小端存储更像是一种标准。不同的编译器有着不同得存储顺序,但是一般都是大端或者是小端存储。
博主用的是VS 2019 ,所以这个编译器是小端字节序存储。
至此C语言初识指针博主已经分享完了,相信大家对指针有了不一样的理解,尽请期待数组 &&指针。
本期收录于博主的专栏——C语言,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“C语言基础知识”。C语言_保护小周ღ的博客-CSDN博客
感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*
文章多处存在借鉴,如有侵权请联系修改删除!