■指针的概念
■指针的基本类型
■野指针
■指针和数组
■二级指针
■指针运算
**
一.指针的概念
**
指针也就是内存地址,指针变量是用来存放内存地址的变量,描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。
**
二.指针的基本类型
1.指针变量决定了:指针进行解引用操作时可以访问几个字节(权限)
char*: 解引用时访问一个字节
int : 解引用时访问四个字节
double:解引用时访问8个字节
int main()
{
int a = 0x11223344;
int*pa = &a;
*pa = 0;
/*char* pc = &a;
*pc = 0;*/
return 0;
}
2.指针类型决定了指针的步长,及(向前,向后,走一步多大距离)
int* 指针加1,表示跳过一个整型,意思是向后走4个字节;
char指针加1,表示跳过一个字符,意思是向后走1个字节;
double指针加1,表示跳过一个double,意思是向后走8个字节;
short*指针加1,向后走2个字节;
int main()
{
int a = 0x11223344;
int* pa = &a;
char* pc = &a;
printf("pa=%p\n", pa);
printf("pc=%p\n", pc);
printf("pa+1=%p\n", pa -1);
printf("pc+1=%p\n", pc -1);
return 0;
}在这里插入代码片
**
三.野指针
**
野指针产生的原因(C语言中常见)
1.局部指针变量没有初始化
#include <stdio.h>
int main()
{
int *p;//局部变量指针未初始化,默认为随机值
*p = 20;
return 0;
}
2.指针越界访问
#include <stdio.h>
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.就是指针指向的空间未释放
常见的还有以下:
/*int main()
{
int* p;//p就是野指针
*p = 20;
return 0;
}*/
int main()
{
int arr[10] = {0};
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
for (i = 0; i <= sz; i++)
{
*p = i;
p++;
}
return 0;
}
如何规避野指针
1.定义创建一个指针变量时一定要记得初始化
2.动态开辟的内存空间,free()释放内存后,一定要马上将对应的指针置为NULL空指针
3.不用再函数中返回栈空间的指针(地址)或局部变量的地址
4.注意在动态开辟内存后,对其返回值做合理判断,判断其是否为空指针
#include <stdio.h>
int main()
{
int *p = NULL;
//....
int a = 10;
p = &a;
if(p != NULL)
{
*p = 20;
}
return 0;
}
**
四.指针和数组
首先我们以如下例子来举例:
#include <stdio.h>
int main()
{
int arr[5] = {1,2,3,4,5};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
return 0;
}
运行结果如下:
我们就可以得出结论:数组就是首元素地址,数组名是数组第一个元素的地址,也是数组的首地址。
*
而以下情况除外:
1.&数组名 ----->表示的是整个数组
2.sizeof数组名 ----->计算的是整个数组的大小
五.二级指针
把一个指向指针变量的指针变量称为多级指针变量,对于指向处理数据的指针变量称为一级指针变量,简称一级指针,而把指向一级指针变量的指针变量称为二级指针变量,简称二级指针
对于二级指针的运算有:
1.*ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .
int b = 10;
*ppa = &b;//等价于 pa = &b;
2.**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .
**ppa = 10;
//等价于*pa = 10;
//等价于a = 10;
六.指针运算
有下三种情况:
指针± 整数
指针-指针
指针的关系运算
6.1 指针±整数
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4};
int *p = arr;
*p = 10;
printf("%d\n",*p);
p++;
*p = 20;
printf("%d\n",*p);
return 0;
}
结果为:
6.2指针-指针
int main()
{
//两个指针相减的前提是:指针指向的同一块连续的空间
int arr[10] = {0};
printf("%d\n", &arr[9] - &arr[0]);
printf("%d\n", &arr[0] - &arr[9]);
int a = 10;
char c = 'w';
printf("%d\n", &a - &c);//err
return 0;
}
6.3指针的关系运算
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。
总结:指针可以相减,也可以和立即数加或者减,两个指针相减可以理解为两个指针的距离,但是两个指针相加后将会是一个毫无意义的地址。最后,希望对大家有所帮助!