指针
概念∶指针就是地址。我们口头上说的指针其实指的是指针变量。指针变量就是一个存放地址的变量。
大小∶指针在32位机器下是4个字节,在64位机器下是8个字节。(指针的大小与类型无关)
指针-指针∶指针-指针的绝对值指的是两个指针之间元素的个数。
前提:两个指针必须指向同一空间
指针的运算关系∶指针与指针之间比较大小就是指针的关系运算。
例如:定义int* p1,数组int arr[5],p1>&arr[5]。
但是要遵循一个标准:允许指针指向数组元素和指针指向数组最后一个元素后面的位置进行比较,不允许指针指向数组元素与指针指向数组第一个位置的前面进行比较。
指针变量的初始化
指针变量在定义后需要先赋值再引用。在定义指针变量时,可以同时对它赋初值。例如:
int a;
int *p1 = &a; /* 在定义指针p1的同时给其赋值,使指针p1指向变量a */
int *p2 = p1; /* 在定义指针p2的同时对其赋值,使p2和p1的值相同,都指向变量a */
注意:
·在指针变量定义或者初始化时变量名前面的“ * ”只表示该变量是个指针变量,它既不是乘法运算又不是间接访问符。
·把一个变量的地址作为初始化值赋给指针变量时,该变量必须在此之间已经定义。因为变量只有在定义后才被分配存储单元,它的地址才能赋给指针变量。
·可以用初始化了的指针变量给另一个指针变量作初始化值。
·不能用数值作为指针变量的初值,但可以将一个指针帮你初始化为一个空指针。
二级指针
二级指针就是存放指针地址的指针变量。就像有三个抽屉第一个抽屉的钥匙放在第二个抽屉,第二个抽屉的钥匙放在第三个抽屉。例如:int a=10;int* p1=&a;int** p2=&p1;对int* * 做解释:第一个*号代表指针指向的类型是int*的,第二个*代表这个是指针。
指针数组
定义:存放指针的数组(int* arr[])。我们知道有整型类型的数组int arr[],还有字符类型的数组char arr[],指针数组就是指针类型的数组。
include<stdio.h>
int main()
{
int a = 0;
int b = 1;
int* p1 = &x;
int* p2 = &y;
int* arr[] = { p1,p2 }; //指针数组
int* arr[] = { &x,&y }; //指针数组
return 0;
}
数组指针
- 定义: 指向数组的指针int (*)[]。
- 应用:遍历整个二维数组
野指针
定义:野指针是指向位置随机的(乱指一气),错误的指针,系统无法对其进行操作。野指针指向的值是非法的内存地址,指向的内存是不可用的。
产生原因:
1.局部指针变量没有初始化
我们如果没有手动去初始化全局变量,全局变量会自动初始化为0,而局部变量不会。所以如果我们不将局部指针变量手动初始化为NULL,那么这个局部指针将会是一个野指针,指向一块非法内存地址,系统无法对其进行操作。
2.使用已经释放过的指针
这个错误常见于动态开辟的内存空间,我们使用malloc等动态内存函数后,都要用free函数对其开辟的动态内存空间进行释放,并将其置为空指针,如果我们用了free函数把那块动态内存空间释放了(还给操作系统了),但是还没置将指针变量为空指针就去使用该指针,就会造成非法访问内存。
3.指针指向的变量在使用之前就被销毁了
最常见于“返回栈空间地址”这一问题,在函数中,如果我们返回局部变量指针,就会造成问题,因为函数调用结束后,局部变量就会被销毁。