一、概念
1.1 指针的原理
找到一个比较精练的概述指针原理的句子:
指针变量就是在内存中保存变量的地址,然后通过地址来访问数据。
int a = 1;
int* p = &a;
cout << p << endl;
009DFEB4
可以知道变量p在内存中的值就是a的地址,地址一般是16进制数。
然后我们可以通过解引用的方式来输出a的值。所谓解引用,就是通过指针的值即a的地址来找到a的值,具体方法就是在指针变量前加*。
cout << *p << endl;
可以知道,*p的值为1。
1.2 常量修饰指针
常量修饰指针分为常量指针、指针常量、常量指针和指针常量叠加。
1.2.1常量指针
常量指针通过const关键字修饰指针。
它的特点是指针变量指向的值不可以进行修改,但指向可以修改。
int a = 1;
int b = 2;
const int* p = &a;
*p = 2;//错误
p = &b;//正确
cout << *p << endl;
可以知道,*p的值为2。
1.2.2指针常量
指针常量是通过const来修饰指针变量p。
它的特点是指向的值可以进行修改,但指向不可以修改。
int a = 1;
int b = 2;int* const p = &a;
cout << *p << endl;
cout << p << endl;
//p = &b;错误
*p = 2;//正确
cout << *p << endl;
cout << p << endl;
1
0102FBE0
2
0102FBE0
可以看到,指针的值即指向的地址没有改变,其指向的值发生变化。
1.2.3常量指针和指针常量叠加
那const也可以既修饰指针又修饰指针变量的值,那么指向的值不可以进行修改,指向即地址也不可以修改。
const int* const p = &a;
其实简单的总结:const后面的值不能发生改变。
1.3 野指针
野指针是指指向非法的内存空间的指针。
1.指定义指针时未做初始化,因而不明确所指向的位置。
int * c = (int*)0x1234;//给指针自定义地址名,没有初始化,会变成野指针
int* d;//没有初始化,也为野指针
2.指new赋值的指针释放后没有归NULL
int* e = new int(1);cout << *e << endl;//只有指针b是正常的,现在将b释放,也会发生报错if(e != NULL){delete e;//此时e为野指针,需要将e置为NULLe = NULL;}
3.指针操作超越了作用域
1.4 this指针
C++中this指针指向的是被调用的成员函数所属的对象。
class Person
{
public:Person(int age){this->age = age;}int age;
};
1.5 空指针
是指指针指向内存编号为0的空间,相当于初始化,不可以访问。
int *p = NULL;
二、程序应用
2.1 在数组中应用指针
2.1.1 一维数组
我们发现数组的变量名其实就是地址,所以不需要用&来取地址。
int a[3] = {1, 2, 3};int* p = a;//p表示数组a中第一个元素的地址,p[0]则表示地址中的值即1。cout<<a<<endl;cout<<p[0]<<endl;for (int i = 0; i < 3; i++){cout << *p << endl;p++;//++相当于从首地址依次加4个字节到下一个数组元素的地址}
2.1.2 二维数组
int a[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
cout << a << endl;
int* p = a[0];//指向第0行。
int* p1 = a;//错误,二维数组的数组名表示的是第一个元素的地址,第一个元素是值数组的第0行,
所以不能指向整行,只能指向整行的元素。
cout << *p << endl;//也表示0行的第一个元素。
cout << p[0] << endl;//表示0行的第一个元素。
00B1FA0C
1
1
3
2.2 在函数中应用指针
int delete_1(int* p1, int* p2)
{int temp = *p1;*p1 = *p2;*p2 = temp;return *p1 - *p2;
}
int main()
{int a = 1;int b = 2;int c = delete_1(&a, &b);cout << a << endl;cout << b << endl;cout << c << endl;
}
2
1
1
与值传递不同,指针传递可以通过改变内存中的值的方法来改变实参。
2.3 实现冒泡排序
void Sort(int* p, int len)
{//实现冒泡排序for (int i = 0; i < len - 1; i++){for (int j = 0; j < len - i - 1; j++){if (p[j] > p[j + 1]){int temp = p[j];p[j] = p[j + 1];p[j + 1] = temp;}} } //交换int var = p[0];p[0] = p[2];p[2] = var;//输出for (int k = 0; k < len; k++){cout << p[k];}
}
int main()
{int a[5] = {13, 1, 2, 5, 14};int len = sizeof(a) / sizeof(a[0]);Sort(a, len);
}
5211314