提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:以下是本篇文章正文内容,下面案例可供参考
一、指针是什么?
1、指针是内存中一个最小单元的编号,也就是地址
2、平时口中说的指针,通常指的是指针变量,用来存放内存地址的变量
总结:指针就是地址,口语中的指针就是指针变量
二、指针和指针类型
2.1 指针类型决定指针的步长(指针+1到底跳过几个字节)
字符指针+1,跳过1个字节
整形指针+1,跳过4个字节
三、野指针
1 野指针成因
3.1.1 先了解下什么是野指针,先看一段代码,如下
int main()
{
int *p;
*p=20;
return 0;
}
p是个局部变量,没有初始化,里面是随机数,所以这里的p就是野指针,没有明确指向一个空间.
正确代码如下:
int main()
{
int a=10;
int *p=&a;
*p=20;
return 0;
}
2.如何避免野指针
<指针初始化
<小心指针越界
<指针指向空间释放,及时NULL
<避免返回局部变量的地址
<指针使用之前检查有效性
示例代码如下:
int main()
{
int a=10;
//int *p=&a; //指针初始化
int *p=NULL; //NULL -空指针,专门用来初始化指针
//这里的p为空是不能用的,当p不为空时才能用
p=&a;
if(p!=NULL)
{
*p=20;
}
return 0;
}
四、指针运算
1、指针-指针
前提:两个指针指向同一个空间。
指针-指针的绝对值,得到的是两个指针之间的元素个数,
2、指针的关系运算
先看如下代码:
for(vp=&values[n];vp>&values[0];)
{
*--vp=0;
}
这样看起来很复杂,我们不妨优化下代码,如下:
for(vp=&values[n-1];vp>=&values[0];vp--)
{
*vp=0;
}
优化后的代码在大部分编译器上是可以完成的,但还是避免这样写,因为标准并不保证它可行。
标准规定:允许数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不与允许与指向第一个元素之前的那个内存位置的指针进行比较
五、指针和数组
1、基本概念
*指针是一种变量,存放地址的,大小4/8个字节
*数组是一组相同类型元素的集合,是可以放多个元素,大小取决于元素个数和元素类型的
*数组的数组名是数组首元素的地址,地址是可以放在指针变量中,可以通过指针访问数组
先看这样一组代码
#include<iostream>
#include<string>
using namespace std;
int main()
{
int arr[6] = { 1,2,3,4,5,6 };
int* p = arr;
cout << p << endl;
cout << *p << endl;
cout << &arr[0] << endl;
return 0;
}
运行结果如下
这里的*p其实就是指向数组arr第一个元素位置,而p就等同于&arr[0].
六、二级指针
先看如下代码
int *pa=&a;
int **ppa=&pa;
a的地址存放在pa中,pa的地址存放在ppa中。pa是一级指针,而ppa是二级指针。
对于二级指针运算有:
*ppa通过对ppa中的地址进行解引用,这样找到的是pa,*ppa其实访问的就是pa
int b=20;
*ppa=&b;//等价pa=&b
^ **ppa先通过*ppa找到pa,然后pa进行解引用操作: *pa,那找到的是a,
**ppa=30;
//等价于*pa=30
//等价于a=30