Bootstrap

从熟练Python到入门学习C++(record 5)

1.指针

1.1指针的定义

首先解释一下int a = 10;计算机不懂什么是a,它首先在内存中找一块地方(4个字节大小),然后写入数字10。当我们打印a的值的时候,它会找到内存地址,读取之前写入的数字;

指针表示内存地址,让p指向a的内存地址。那么*p相对于读取这块内存地址的数字,如果给这块内存地址重新赋值(*p = 100),那么再打印a的值时,仍然是先找到内存地址,读取目前写入的数字;

#include <iostream>
using namespace std;

int main()
{
	int a = 10;
	int* p = &a;
	cout << p << endl;
	cout << *p << endl;

	*p = 100;
	cout << a << endl;
	cout << *p << endl;

	return 0;
}

1.2指针的占用内存

x86为4字节,x64为8字节,无论什么类型的指针;

#include <iostream>
using namespace std;

int main()
{
	int a1 = 10;
	short a2 = 20;
	long a3 = 30;
	float a4 = 1.32;
	char a5 = 'a';
	
	int* p1 = &a1;
	short* p2 = &a2;
	cout << sizeof(p1) << endl;
	cout << sizeof(p2) << endl;
	return 0;
}

1.3空指针和野指针

空指针:指向编号为0的指针,不可改变其值

野指针:指向的内存不可访问;(乱写的指针)

#include <iostream>
using namespace std;

int main()
{
	int* p1 = NULL;
	int* p2 = (int*)0x1100;
	cout << p1 << endl;
	//cout << *p2 << endl;
	return 0;
}

1.4const修饰指针

有三种情况:主要看const在哪个地方

1.const int* p-常量指针

指针指向的值不能修改;指针的指向可以修改;

简单来说就是*p不能修改,p能修改;

2.int* const p-指针常量

指针的指向不能修改;指针指向的值可以修改;

简单来说就是p不能修改,*p能修改;

3.const int* const p

什么都不能修改;

#include <iostream>
using namespace std;

int main()
{
	int a = 10;
	int b = 20;
	int* p = &a;
	cout << *p << endl;

	const int* p1 = &a;
	p1 = &b;
	cout << a << endl;   //10 
	cout << *p1 << endl; //20
	cout << b << endl;   //20
	cout << "*********************\n";
	a = 10;
	b = 20;
	int* const p2 = &a; 
	*p2 = b;
	cout << a << endl;   //20 
	cout << *p2 << endl; //20
	cout << b << endl;   //20
	cout << "*********************\n";
	a = 10;
	b = 20;
	const int* const p3 = &a;
	cout << a << endl;   //10 
	cout << *p3 << endl; //10
	cout << b << endl;   //20

}

1.5指针和数组

通过++p,或者p+1,可以找到下一个数的位置

#include <iostream>
using namespace std;

int main()
{
	int a[5] = { 1,2,3,4,5 };
	int* p = a;
	cout << "a : " << (int)a << endl;
	cout << "p : " << (int)p << endl;
	cout << "*p : " << *p << endl;
	cout << "p+1 : " << (int)(++p) << endl;
	cout << "*p : " << *p << endl;

	int b[2][3] = {
		{1,2,3},
		{4,5,2},
	};
	for (int i = 0; i < 2; ++i)
	{
		int* p = b[i];
		for (int j = 0; j < 3; ++j)
		{
			cout << *(p + j) << " | ";
		};
		cout << endl;
	};
	return 0;

}

1.6指针和函数

使用指针作为函数的参数,可以修改实参的值

#include <iostream>
using namespace std;

void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

int main()
{
	int a = 10;
	int b = 1000;
	cout << " a is : " << a << " | b is : " << b << endl;
	swap(& a, & b);
	cout << " a is : " << a << " | b is : " << b << endl;
	return 0;
}

1.7案例

封装一个函数,利用冒泡排序,对整型数组升序排列;

#include <iostream>
using namespace std;

void print(int* p)
{
	for (int i = 0; i < 10; ++i)
	{
		cout << *(p + i) << " | ";
	}
	cout << endl;
}

void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void maopao(int* p)
{
	for (int i = 0; i < 10; ++i)
	{
		int count = 10;
		for (int j = 0; j < 9 - i; ++j)
		{
			int* l = p + j;
			int* r = p + j + 1;
			if (*l > *r)
			{
				swap(l, r);
				--count;
			}
		}
		if (count == 0) {
			break;
		}
	}
	

}

int main()
{
	int arr[10] = { 4,153,134,6,543,5432,53,643, 91,4 };
	print(arr);
	maopao(arr);
	print(arr);
}

需要优化的地方为:指针可以直接使用下表访问元素;

#include <iostream>
using namespace std;

void print(int* p)
{
	for (int i = 0; i < 10; ++i)
	{
		cout << p[i] << " | ";
	}
	cout << endl;
}

void swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

void maopao(int* arr)
{
	for (int i = 0; i < 10; ++i)
	{
		int count = 10;
		for (int j = 0; j < 9 - i; ++j)
		{
			if (arr[j] > arr[j+1])
			{
				swap(arr[j], arr[j+1]);
				--count;
			}
		}
		if (count == 0) {
			break;
		}
	}
	

}

int main()
{
	int arr[10] = { 4,153,134,6,543,5432,53,643, 91,4 };
	print(arr);
	maopao(arr);
	print(arr);
	int* p = arr;
	print(p);
}

所以温习一下数组和指针,这两步都是等价的。

#include <iostream>
using namespace std;

int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int* p1 = arr;
	int* p2 = &arr[0];
	cout << arr << " | " << &arr[0] << " | " << p1 << " | " << p2 << endl;

	//
	cout << arr[1] << endl;
	cout << p1[1] << endl;
	cout << *(p1 + 1) << endl;
	cout << *(++p1) << endl;
	return 0;
}

;