一、概念
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置为NULL
e = 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