C/C++有意思的指针(1)

指针带来的乐趣

在C/C++中指针是一个常用的类型,但同时指针也是一个重要且有意思的概念。这个概念说大了与量子纠缠什么还能联系在一起,也可以与宇宙空间联系起来。而我更喜欢它另外一个角度的理解:玄幻小说里男主角的空间戒指。

记得以前看玄幻类小说时常羡慕男主角的空间储物戒指,想放什么就放什么,还可以在信物戒指里面住,甚至生活都可以。里面放的都是奇珍异宝,鸟语花香等等,总之它是一个与世无争的空间。只要你有一个这样的戒指你就能获得具大的空间,这里的空间是指宇宙空间。而计算机相当于现实世界的虚拟,它也有自己的空间,这个空间称为内存空间。而要获得内存空间就需要通过内存地址访问,指针就充当了这样一个角色,作为内存空间的钥匙,打开内存空间的大门。只是这个内存空间只能存储数据(或说寄存器状态)。

  • 关于内存空间的外话
    我们计算机内存芯片,比如说2G内存空间,这个内存空间是掉电丢失性质的,它保存的数据只是暂时性的,这样的记录数据的方式其它我们都知道只是寄存器的0或1来保存数据。

内存如何保存住我们的数据

普通人理解的计算机保存我们数据及图像数据,但其它是保存了0或1的状态。内存中的数据也是,内存中的2G内存空间大小是如何来的。
内存空间最小计算单元为字节即8Bit位,为了便于理解只表示正数,表示的范围是(00000000 - 11111111)0~255,也可以说一字节内存能记录256种状态。程序中使用的char数据类型即占用一个字节。

现在嵌入普通使用的都是32位的内存地址线,那么代表它能访问的内存空间大小为2的32次方字节。
2的32次方 = 4294967295/1024 = 4193280KB = 4095MB = 4GB 就是说4G内存可以保存4294967295种状态。
我们可以通过程序中使用指针地址来访问到内存的每一字节内存空间。当然有些内存空间特殊用处不能让用户随意访问到这个另外的话题。

虽说一个字节能表示256种状态,但在同一时刻它只能处在256种状态中的一种。所以内存空间一个字节在某时刻只能表示0~256之间的一个数值。比如我们一张图片假定分辨率为1024x600,16位深度,那么显示器要显示一张这个图片需要到内存读取多少内存空间呢。需要102460016状态来表示一张图片即1200KB数据量。

内存空间与数据类型关系

说到内存空间就必须要提到数据类型,在高级语言很都没有数据类型一说,但C/C++是面向内存操作的编程语言,需要按照一定的方式来访问内存空间,这个约定的方式即是数据类型。

可以这样,数据类型是程序员与CPU约定的一种读取内存的方式,指定数据类型后CPU按照指定类型去访问内存空间。避免随意访问内存空间导致的错误。

如定义char类型数据那么CPU就读取内存1个字节内存空间,int读取4字节内存空间。那么定义的变量即是数据类型能访问到的内存空间大小。即 char a; 定义变量a为char类型数据,CPU通过a变量名的首地址访问内存空间1个字节。 int b = 4;那b变量名能访问到内存空间4个字节,即a变量占用4字节内存空间。

数据类型与指针的关系

指针变量说白了就是保存内存地址的变量。所以指针变量必须也是给定数据类型,这个CPU才知道到地址内存空间读取多少字节空间。char* a;定义a为指针变量,a变量中保存了一片内存空间的地址,至于这个指向的内存空间是多大或说通过这个指针变量能访问到多少的内存空间则于数据类型决定。这里指针能访问到1个字节内存空间。
int* b; 定义一个整型类型指针,或说定义变量b保存的地址能访问到4字节的内存空间。因整型类型占用4字节内存。
即然数据类型是程序员与CPU之间约定的读取内存的方式,所以当定义了一个指针变量时,那么在指针变量的赋值或指向其它空间时,这个读取的约定必须是相同的。即指针赋值时指针指向的内容数据类型必须相同,或说指针类型相同。
示例:

int age = 10;
int* a = &age; //&取age的地址运算,约定CPU读取内存方式为int类型即4字节读取

进一步理解指针变量及指针类型

指针也是一种数据类型,它通常占4字节内存空间(依不同平台占字节数不同)。
char* a; //变量a存放char指针类型
int
b; // 变量b存放int* 指针类型

指针类型代表了2种含义

  • 它是存放一块内存空间首地址
  • 它能访问到的内存空间大小或说占用内存空间大小(数据类型)
  • 如果是void类型即void*(无指定类型)则能访问到申请到任意内存空间大小。

指针就是受限制的空间存物戒指(类型的限制,void类型则无限制)

从上面内容可以看到,指针变量可以保存内存空间首地址,相当是拿到内存中某块存储空间的入口号码。有了这个地址,便可以访问这片内存区域,但具体怎么访问或说能访问到这片内存区域的大小则由数据类型指定。
想象下内存空间就是宇宙空间,我们申请内存空间,分为受类型限制大小的方式,即使用了数据类型(这个数据类型可以自定义)。或不使用数据类型,申请一片内存空间。
int* a = (int*)malloc(sizeof(int)); //也可以使用int* a = (int*)malloc(sizeof);
void* b = (void*)malloc(size);
第一个int* a由于这指针类型为int类型,所以申请空间后需要强制类型转换成(int)类型,至于申请的内存空间大小则不是必须为sizeof(int)的,你可以指定任意大小内存空间。只是指针类型为int*类型,就是CPUf读取内存只能是首地址偏移4字节,如果申请内存更大,也访问不到浪费内存而已。
但是变量b就不同,它没有跟cpu约定怎么读取内存空间,所以它申请任意大小的空间都可以通过指针访问到。
至于指针变量的增减操作,则依语言默认是增加一个数据类型的大小。这里也就很好理解,因为指定了数据类型那么变量的偏移操作肯定要以数据类型为最小单元来偏移,否则访问到其它地方数据就乱了(其它也可以强制类型转换那样想怎么访问就怎么访问,有时我们把int类型转换成char就是这个原理)。

什么是数据类型强制转换

说白了就是程序员与CPU约定读取内存的方式变了,这个如果想正常使用只能是从大转成小,如果小转成大则会访问到超出数据类型的内存空间,导致数据错误(错误是未知的)。

这样就理解了什么是强制类型转换了。强制类型转换从大数据类型转到小数据类型是可以正常读取的,如int转换成char类型可以访问内存前1个字节内容,后面3字节内容就丢失了。如果char转int则不行,会访问到指针内存空间外的内存。这样可能会损坏其它内存空间数据。

指针其它用处,只是指针原理的延伸处理方。如函数指针就是函数名即是一个指针变量,数组名也类似。

更详细的指针使用,待续。。。。

用于个人理解,仅供参考。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值