C语言指针01
1.如何理解指针
首先我们需要有这样的认识,在计算机中当CPU处理数据时,是从内存中读取数据的,而内存由一个个内存单元组成的,因此我们需要读取的数据就被存放在一个个内存单元中。但是,你想操作一个数据的话,你首先需要找到这个数据的位置。那么怎么才能找我们需要的数据所在的内存单元呢,这时,我们会给每个内存单元编号,这些编号就是地址,而指针其实就是地址。
我们可以简单理解为内存单元的编号 == 地址 == 指针。
2.指针变量和地址
理解了内存和地址的关系,我们再回到C语⾔,在C语⾔中创建变量其实就是向内存申请空间。
如上所示就是当我们创建变量a时,在内存中申请的连续的4个字节的空间,每个字节8个比特位,这里用的是十六进制来表示的,这四个字节地址由低到高分别是
00F6FAD4//0A 00F6FAD5//00 00F6FAD6//00 00F6FAD7//002.1取地址操作符
那么我们应该如何获取a的地址呢,这时候我们就需要用到取地址操作符&,用法如下:
当我们需要打印地址的时候,用到的占位符是%p,如果想要获取a的地址的话,就使用&a。
但是这里可以看到,这里生成的a的地址,和我们上面所获得的a的地址并不一样,内存是随机分配的,每次执行程序的时候,a的地址都会不一样。并且,在取地址时(&a),取出是a所占4个字节中地址较⼩的字节的地址。
2.2解引用操作符
2.2.1指针变量
当我们得到了一个地址的时候,我们通常还需要将该地址保存起来,比如说0x006FFF30,这是一个地址型的数据,我们该如何保存呢?我们在最开始的时候说过,地址就是指针,指针就是地址,所以我们把一个地址存放在指针变量中。
此时,&a得到的是p的地址,p这个指针变量中存放的也是a的地址
我们不只有int* 这个类型的指针变量,同时也有存放各种数据类型的地址的指针变量
char*//用于存放char类型数据的地址 short*//用于存放short类型数据的地址 int*//用于存放int类型数据的地址 long*//用于存放long类型数据的地址 long long*//用于存放long long类型数据的地址 float*//用于存放float类型数据的地址 double*//用于存放double类型数据的地址 long double*//用于存放long double类型数据的地址比如说现在有个char类型的变量a,我想把他的地址存放进指针中,那该怎么做呢,即
char ch = 'a'; char* p = &ch;2.2.2解引用操作符(*)
同时,通过解引用操作符,我们现在可以不直接通过变量a而改变a的值了。
*p = 5;注意:这里的解引用操作符*,和创建指针变量时用的int* 中的*两个虽然是同一个操作符,但是概念上是不一样的,这里就用*pa举例。这里的解引用操作符就是通过指针变量pa中存放的地址,找到该地址指向的空间。而int* 这里的*相当于声明我现在定义的变量是一个指针变量,并且该变量用于存放int类型数据的地址。二者虽然是同一个符号,我们自己要清楚二者的含义是不一样的。
2.3指针变量的大小
既然指针变量中存放的是地址,那么该地址是否有大小限制呢,答案是一定的。、
但是我们先来了解一下计算机内部的知识,计算机中CPU用于对数据进行计算,但是数据都存放在内存中的内存单元中,因此CPU就需要通过地址找到目标数据的内存单元。那么该如何寻找呢,这时候就需要用到地址总线。
在32位的机器中,就有32跟地址总线,每一根线有两种状态,表示0和1(电脉冲有无),所以32根线就有2^32种状态,每一种状态都代表一个地址。那么64位机器就是64根地址总线,能表示2^64种状态。
了解了这些知识之后,我们再来了解指针变量的大小。32位机器有32根地址总线,那么每个地址就由32个bit位构成,8个bit位就是一个字节,那么在32位机器中就需要4个字节来存储地址。又因为指针就是地址,因此,指针变量的大小就是4个字节。
那么64位机器有64跟地址总线,每个地址就由64个bit构成,即8个字节,因此在64位机器当中,一个指针变量需要占8个字节的大小。
x86表示32个bit位
x64表示64个bit位
总结:在32位下,指针变量大小是4个字节,在64位下,指针变量大小是8个字节。注意,指针变量的大小与指针类型类型是无关的,在同一个机器下,大小都是相同的。
3指针类型变量的意义
3.1指针的解引用
对比下面两段代码,观察内存变化。
第一段代码
可以看到a的地址占了004FF968,004FF969,004FF96A,004FF96B四个地址,当我们执行*p = 0这个语句时,这四个地址对应的内存单元中的数据都变成了0。
第二段代码
我们可看到当指针p的类型时char*,执行*p = 0时,只有1个字节的数据改成了0,
结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。
⽐如: char*的指针解引⽤就只能访问⼀个字节,⽽int*的指针的解引⽤就能访问四个字节。
3.2 指针+-整数
这里看到,char*类型的指针变量+1一次跳过一个字节,int* 类型的指针变量+1一次跳过4个字节。
这就是指针变量类型差异带来的变化。指针+1,其实就是跳过1个指针指向的元素。当然指针既可以+1,也可以-1。
总结:指针的类型决定了指针向前一步或者向后走一步有多大(字节)
