一、名词解释
指针是一个变量,其值是另一个变量的地址。
how to understand?
//我们知道,一个变量定义过程如下
int a = 3;
同样,指针作为一个变量,也有其数据类型int/double/float等等,而指针存储的值,不再是普通变量存储的该数据类型的某个数据,而是一串地址码,根据这个地址码,从而找到存放在该地址的变量。
二、指针定义
涉及到两个符号:
& 访问变量的地址
* 访问指针中地址的值(也有声明指针的作用)
int a = 1;
int& p_a; //指针声明
p_a = &a; //把a的地址赋给指针
cout << "get value directly: " << my_a
<< " get address: " << p_a
<< " get value from address: " << *p_a << endl;
三、简单应用
1、空指针
// 空指针————有时声明变量是还没有地址可以赋值(注意NULL是全大写)
int *my_nullPtr = NULL;
cout << my_nullPtr << endl;
2、指针算术运算
实现效果:
定义一个数组,用指针来指向其中的元素,接下来通过指针的算术运算,选中数组不同元素,以及进行比较的过程。
//指针算术运算:包括++ -- + -四种(这里也包含指针与数组间的运算部分)
int my_arr[4] = {1,3,5,6};
int *p_arr = my_arr; // 直接赋数组名给指针,意思是数组第一个元素地址赋给指针
//赋数组最后一个元素地址给指针 int *p_arr = &my_arr[3];
cout << p_arr << " and " << *p_arr << endl;
p_arr++;
cout << p_arr << " and " << *p_arr << endl;
// 指针比较
while(p_arr <= &my_arr[3])
{
cout << p_arr << " and " << *p_arr << endl;
p_arr++;
}
3、指针数组
实现效果:
把指针声明成一个数组,每个指针通过for遍历接收原来的变量数组中每个变量的地址,并打印输出。不同数据类型的数组用法相同。
//指针数组
int my_arr2[3] = {1,2,3};
int *p_myarr2[3]; // 把指针声明为数组,指针数组中每一个元素都是一个指向int的指针
for(int i = 0; i < 3; i++)
{
p_myarr2[i] = &my_arr2[i];
}
for(int i = 0; i < 3; i++)
{
cout << *p_myarr2[i] << endl;
}
const char *names[3] = {"li","sakuru","naruto"}; // 字符串数组同理
for(int i = 0; i < 3; i++)
{
cout << names[i] << endl;
}
4、指向指针的指针(多级间接寻址)
实现效果:
连续调用指针,指针嵌套。
第一次cout输出的是外层指针p_p_ptopa的各种形式,读者据此理解嵌套的指针使用方法;
第二次cout输出的是恒定的原变量ptopa的变量值。
// 第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置
int ptopa = 1;
int *p_ptopa = &ptopa;
int **p_p_ptopa = &p_ptopa;
cout << p_p_ptopa << " and "
<< *p_p_ptopa << " and "
<< **p_p_ptopa << endl;
cout << ptopa << " and "
<< *p_ptopa << " and "
<< **p_p_ptopa << endl;