深⼊理解指针(1)
⽬录:
1.
内存和地址
2.
指针变量和地址
3.
指针变量类型的意义
4.
const修饰指针
5.
指针运算
6.
指针的使⽤和传址调⽤
正文即将开始啦!
大家是不是很
期待 呢?
长话短说,接下来我们就将进入指针的学习。
1.内存与地址
1. 内存
众所都只知,
计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数
据也会放回内存中,但是这些内存空间如何⾼ 效的管理呢?
其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。
计算机中常⻅的单位(补充):
⼀个⽐特位可以存储⼀个2进制的位1或者0
bit -
⽐特位 byte - 字节 KB MB GB TB PB
下面就是它们之间的换算:
1byte = 8bit
1KB = 1024byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB
其实理解它的时候,我们可以将每个内存单元,联想成为⼀个学⽣宿舍,⼀ 个⼈字节空间⾥⾯能放8个⽐特位,就好⽐同学们 住的⼋⼈间,每个⼈⼀个⽐特位每个内存单元也都有⼀个编号(这个编号就相当 于宿舍房间的⻔牌号),有了这个内存单元的编 号,CPU就可以快速找到⼀个内存空间。
在生活中我们将这些门牌号叫做地址,但是我们在C语言当中就被给予了一个新的名字“指针”
即指针==地址==内存的单元编号
2.地址
简单的理解为:32位机器有32根地址总线, 每根线只有两态,表⽰0,1【电脉冲有⽆】,那么 ⼀根线,就能表⽰2种含义,2根线就能表⽰4种含 义,依次类推。32根地址线,就能表⽰2^32种含 义,每⼀种含义都代表⼀个地址。 地址信息被下达给内存,在内存上,就可以找到 该地址对应的数据,将数据在通过数据总线传⼊ CPU内寄存器。
地址总线:cpu想要读取的内容可以通过这个地址总线去找到
数据总线:将读取到的内容通过它传回cpu
控制总线:cpu想要完成的任务
2.指针变量和地址
1-1 取地址操作符&,解引用操作符*
int*p=&a;//其中p是指针变量(及存放指针的变量,也可以说是存放地址的变量,毕竟在前面讲过:
指针就是地址。总体就是说(&b)就是取出b的地址放到指针变量p当中,有了地址我们就可以通过*(解引用操作符)我们可以把它理解为指示牌,指导我们去找到这个地址里面存放的数字。
我们也可以通过下面的图画来理解它:
大家看看这个图:
我们知道了pa中存放的是a的地址,然后通过*(这个指向标)找到了a
注意:int*表示的意思是pa指向的对象是int型的(即a是int型)
1-2 指针变量的大小
在前面的知识我们知道了:
32个地址线->就是32个0/1组成的,如果换算成为二进制就是32个bite=4个字节
同理:64个地址线->就是64个0/1组成的,如果换算成为二进制就是64个bite=8个字节
也就是说:
**指针变量的大小与其类型是无关的,只要指针变量在相同的平台下运行,其大小都是相同的
eg.x64--->64位环境---->8个字节
x32--->32位环境---->4个字节
3 指针变量类型和意义
3-1 指针加减整数
printf("%p\n", pi + 1);
对于pi来说,它指向的类型是int型,占四个字节,所以pi+1就是向后移动了四个字节
printf("%p\n", pc + 1);
对于pc来说,它指向的类型是char型,占一个字节,所以pi+1就是向后移动了一个字节
3-2 void指针类型
void*
类型特点:⽆具体类型的指针(或者叫泛型指 针),这种类型的指针可以⽤来接受任意类型地址。
局限性:
void*
类型的指针不能直接进 ⾏指针的+-整数和解引⽤的运算。
4.const修饰指针
变量是可以修改的,如果把变量的地址交给⼀个指针变量,通过指针变量的也可以修改这个变量。
但是如果我们希望⼀个变量加上⼀些限制,不能被修改,怎么做呢?这就是const的作⽤。
int a=1;
int*p=&a;
const有两种修饰类型:
1.修饰p (int *const p=&a;)
修饰p的时候不能再将一个新的地址去赋予给p(可以这样理解:p中存放的是a的地址,在const修饰后,这个地址就不可以改变了)
2.修饰*p (int const*p=&a或者const int*p)
修饰*p的时候不能再改变*p的值了。(
可以这样理解:p中存放的是a的值,在const修饰后,这个值就不可以改变了)
5.指针的运算
1.指针加减整数
1.int *p=&arr[0],是取出arr[0]的地址放入了指针变量p当中,
2.*(p+i),应为p和i都是整型变量,所以每加一次i,其地址向后移动4i个字节,其分别对应arr[1],arr[2],........arr[9]的地址,然后通过*对其解引用,就分别对应了arr[1],......arr[9].
2.指针减指针
通过函数调用,使abc的地址存到指针变量s当中,再将指针变量s的地址存到指针变量p当中,则*p就是abc的首元素地址,p最后的地址减去s的地址,就相当于最后p的地址减去p还未运行前的地址————>期间元素的个数。
3.指针的关系和运算
int *p=&arr[0],是取出arr[0]的地址放入了指针变量p当中,arr+sz中arr就是首元素arr[0]的地址,即它可以等价于p<p+sz-->p=0;(p<10;)p++.