目录
一、什么是指针
二、指针和指针类型
2.1 指针+-整数
2.2 指针的解引用
三、野指针
3.1 野指针形成原因
3.2 如何规避野指针
四、指针运算
4.1 指针+-整数
4.2 指针-指针
4.3 指针的关系运算
五、指针和数组
六、二级指针
七、指针数组
一、什么是指针
指针是内存中一个最小单元的编号,也就是地址。平时所说的指针指的是指针变量,是用来存放内存地址的变量。
指针变量:通过&(取地址操作符)取出变量的内存起始地址,将地址存放到变量中,这个
变量就是指针变量。
int main()
{
int a = 10;//在内存中开辟一块空间
int *p = &a;//p为指针变量,使用&取出变量a的地址
return 0;
}
指针变量用来存放地址,地址是唯一标识一个内存单元的,指针的大小在32位平台是4个字节,在64位平台是8个字节。
二、指针和指针类型
指针变量都有相应的类型
char *pc = NULL; //字符型,存放字符类型变量的地址
int *pi = NULL; //整型,存放整型变量的地址
short *ps = NULL; //短整型
long *pl = NULL; //长整型
float *pf = NULL; //单精度型
double *pd = NULL; //双精度型
2.1 指针+-整数
int main()
{
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
return 0;}
指针的类型决定指针向前或向后走一步有多大(距离)。
2.2 指针的解引用
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
int *pi = &n;
*pc = 0;
*pi = 0;
return 0;
}
指针的类型决定对指针解引用时能操作几个字节。例如:char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
三、野指针
3.1 野指针形成原因
1. 指针未初始化
int main()
{
int *p; //局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
2. 指针越界访问
int main()
{
int arr[10] = {0};
int *p = arr;
int i = 0;
for(i=0; i<=11; i++)
{
//当指针指向的范围超出数组arr的范围,p成为野指针
*(p++) = i;
}
return 0;
}
3. 指针指向的空间释放
3.2 如何规避野指针
1. 指针初始化
2. 注意指针越界
3. 指针指向的空间释放,及时置NULL
4. 避免返回局部变量的地址
5. 指针使用前检查有效性
int main()
{
int *p = NULL;
//....
int a = 10;
p = &a;
if(p != NULL)
{
*p = 20;
}
return 0;
}
四、指针运算
指针运算包括指针+-整数、指针-指针和指针的关系运算。
4.1 指针+-整数
int main3()
{
float values[5];
float* p;
for (p = &values[0]; p < &values[5];)
{
*p++ = 0;
}
}
4.2 指针-指针
int my_strlen(char* s)
{
char* p = s;
while (*p != '\0')
p++;
return p - s;
}
int main()
{
char arr[] = "abc";
char* p=NULL;
p = arr;
printf("%d", my_strlen(p));
return 0;
}
4.3 指针的关系运算
for (p = &values[0]; p < &values[5];)
{
*p++ = 0;
}
五、指针和数组
除特殊的两种情况外,数组名表示的是数组首元素的地址。
可以将数组名当成地址存放到一个指针中,使用指针来访问。
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0; i<sz; i++)
{
printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p+i);
}
return 0;
}
p+i 计算的就是是数组 arr 下标为i的地址。
六、二级指针
int a=10;
int *p=&a;
int **p1=&pa;
a的地址存放在p中,p的地址存放在p1中,p为一级指针,p1为二级指针。
二级指针解引用
int a=10;
int *p=NULL;
int **p1=&pa;
*p1=&a; //等同于 p=&a
*p=20; //等同于a=20
**p1=20 //等同于*p=20-->a=20
七、指针数组
指针数组是存放指针的数组。
示例
int* arr[3];