一、什么是指针?
1. 指针是内存中一个最小单元的编号,也就是地址
2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
1、创建一个整型指针变量
指针变量是用来储存地址的变量,所以在创建的时候需要“&”来获取变量的地址
int a=10;
int* p=&a;
int *p=&a;
以上两种创建变量的方法都是可以的,都是创建一个整型变量指针p指向a的地址或者说用来存放a的地址。
Int* p=&a;可以看作是创建一个int* 的指针变量p指向a;
int *p=&a;可以看作是创建一个指向整int型量a的指针变量*p。
二、指针的类型及大小
我们知道C语言中有多种数据类型,同样的也有不同类型的指针用来指向不同类型的数据变量。
char* pa=NULL;
short* pb=NULL;
int* pc=NULL;
long* pd=NULL;
float* pe=NULL;
double* pf=NULL:
这里NULL是空指针,不指向任何地址。
我们知道,不同数据类型的变量的大小是不一样的,那么不同类型的指针变量大小也不同吗?
x86环境下的指针大小
64位环境下
由此我们可以得出指针变量的大小在32位操作系统下的大小是4个字节,在64位操作系统下的大小是8个字节。
这是因为:
在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。
那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。
那既然不同类型的指针大小都是一样,那分不同类型的指针的意义是什么呢?
这里我们申明三个不同类型的指针变量指向同一个整形变量,打印出解引用后的值观察它们解引用后的值
此处是32位操作系统下大端字节存储模式(数据的低位保存在内存的高地址中;数据高位保存在低地址位中)(详情可参考前面的文章C语言的数据存储_c语言如何存储数字_MIKASA877的博客-CSDN博客https://blog.csdn.net/qq_60868586/article/details/132502704?spm=1001.2014.3001.5501),
由此我们可以得出指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
例如int*类型的指针一次性访问四个字节的数据、char*类型的指针一次性访问一个字节的数据、short*类型的指针大小一次性访问一个字节的数据......(访问的字节数与数据类型的大小一致)。
三、指针的解引用
指针的解引用:
指针的解引用就是在创建一个指针并指向一个变量后,在指针变量前面加上一个“ * ”就可以直接调用所指向地址中的数据
例如:
注意!在声明指针变量时我们也会用到“ * ”
int a=10;
int* p=&a;
int *p=&a;
这里的“ * ”是用来表示创建指针变量(上有解释),不要和解引用混淆。
并且,我们可以通过解引用来改变指针指向变量的值
四、野指针
概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
为何会出现野指针?
1、指针定义时未初始化,有可能会让指针指到一个未知的地方
2、指针越界访问
下列代码为何会报错?
因为数组arr[10]一共有十个元素arr[0]--arr[9],*p指向arr(数组名代表数组首元素),在每次for循环中*p为数组中的每个元素赋值,可for循环一共会执行12次,超出了arr定义范围,指向了未知的地方,因此p就是一个野指针。
3、指针所指向的空间已经被释放(暂时按下不表)
那么我们在创建指针变量时,就应该注意以下几点来规避野指针:
1. 指针初始化
2. 小心指针越界
3. 指针指向空间释放即使置NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性
五、指针的运算
1、指针+-整数
声明一个int* 类型的指针pi和一个char* 类型的指针pc同时指向整形变量n的地址
可以发现pi和pc所保存的地址都是一样的,保存的都是n的地址
不同的是,当pi和pc +1后的地址不同 可以发现pc+1只跳过了一个字节的地址,而pi+1跳过了四个字节的地址
我们可以得出结论,当指针和一个整数相加时,计算结果和指针本身的类型有关(与上面访问不同的字节数相同)。
2、指针-指针
指针-指针=两个指针指向的间地址的差
六、指针与数组
由此可见,arr数组名就是数组的首地址,可以通过指针指向数组的首元素或数组名,并通过与整数的运算来实现对数组中的元素进行访问。即p+i==arr[i]。
七、二级指针
指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?这就是 二级指针 。
(当然二级指针pp也有地址,但我没写,可以一直套下去)
并且,由图可知解引用*p是p指向地址所存的值,即*p=10
那么解引用*pp就是pp所指向地址所存的值,即*pp=p
若对*pp再一次解引用即**pp==*(p)=10
对C语言的指针先初步介绍到这里,如有不足或是纰漏还望及时指出。