指针是什么?
内存空间将自身分为最小单位 字节 来对自身进行管理 当要使用空间时,按照所使用的空间大小,分配于所使用的程序。如何寻找到目标空间?划分成为了字节的小空间有所对应的唯一编号,这个编号称之为地址——又称为指针。
上图是一个简单的使用方法,此刻,pa便是存放了变量a的地址 。
总结来说:指针就是地址 (存放在指针中的值都当作地址处理)
地址是如何产生的?
32位机器上,有32根物理电线,通电后产生电信号,转换为数字信号后,反馈过来的信息为0或者1,则组合方式有2^32种方式,这种序列就作为了内存单元的编号。(64位同理) 64为机器管理内存的能力强于32位机器。 2的32次方所管理的空间为:
指针与指针类型
任一指针类型的大小是相同的 那指针拥有类型的意义是?
下两图片对比:
指针类型可以决定指针的解引用时可以访问多少个字节(指针的权限)
下图所表示:
指针类型决定指针+或-1时,操作的步长
整形指针+1跳过了4个字节 字符指针+1跳过了1个字节
跳过的时:n*sizeof(type)多个字节。
野指针
//野指针
int* p;//局部变量不进行初始化,,内容为随机值
*p = 200;
成因
如上图所示,数组空间为10,但是循环插入数据次数为12次,当空间使用完时,继续循环指针出现非法访问,便成了野指针。
如何规避野指针
指针的运算
指针的运算有三中情况:
1.指针+-整数 2.指针-指针 3.指针的关系运算
指针+-整数
我们来看以下代码
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
//不使用下标访问数组
int* p = &arr[0];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
p = arr;
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));//p+i
}
执行的结果如下:
p指针指向了arr数组的第一个数据的地址,第一组循环为p赋值,存储进arr数组,第二个循环输出这一数组。证明指针可以通过+-整数来进行地址的指向移动
int *p=arr; arr为数组名,数据名是数组首元素的地址——也就是指针,那么
*(p+i) == arr[i];这样的表达形式以及*(arr+i) == arr[i]实际上成立。(对p+i的解引用)
指针-指针
我们来看一下代码的实例:
int main()
{
int arr[10] = { 0 };
printf("%d\n", &arr[9] - &arr[0]);
return 0;
}
而这行代码的执行结果为:
得到的数值的绝对值就是两个指针之间有多少的元素个数。
前提是:两指针指向了同一块区域,否则毫无意义
指针的关系运算
实际上是指:指针之间的比较大小:其规则是
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
指向第一个元素之前的那个内存位置的指针进行比较。
二级指针
指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
二级指针便是指向指针地址的指针
int a = 10;
int* p = &a;//p是一级指针变量,指针变量也是变量,变量是在内存中开辟空间的,是变量就有地址
int** q = &p;//pp就是二级指针变量,二级指针变量就是用来存放一级指针变量的地址
通过对二级指针的解引用,实际上访问一级指针所标记的地址。
指针数组
实际上是存储指针的数组