C++总结笔记(二)——指针

一、概念

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值