指针那些事儿

1.野指针(也叫悬摆指针,迷失指针)

野指针是导致BUG的罪魁祸首之一。对指针调用Delete后(释放掉了它指向的内存,野指针还是指向原来的地址),如果没有重新赋值就使用它,将导致难以预料的后果。因为此时操作野指针,它指向的内存地址可能已经分配给其他变量在使用了。

所以指针在Delete之后,如果不再使用,一定要赋值Nullptr。


2.const指针之一:指针本身是常量 or 指向的对象是常量

	int iValOne = 111, iValTwo = 222, iValThree = 333;
	//示例1.指针指向的内容是常量
	const int *pValOne = &iValOne;
	//*pValOne = iValTwo; //错误,不能修改指针指向的内容:iValOne值不能被修改
	pValOne = &iValTwo; //正确,可以修改指针本身的地址:iValTwo的地址赋值给指针
	

	//示例2.指针本身是常量
	int * const pValTwo = &iValTwo;
	*pValTwo = iValThree; //正确,可以修改指针指向的内容:iValTwo的值修改为iValThree的值
	//pValTwo = &iValThree; //错误,不可以修改指针本身的地址:pValTwo的地址只能是iValTwo的地址

	
	//示例3.指针本身及其所指向的内容都是常量
	const int * const pValThree = &iValThree;
	//*pValThree = iValOne; //错误,不能修改指针指向的内容:iValThree值不能被修改
	//pValThree = &iValOne; //错误,不可以修改指针本身的地址:pValThree的地址只能是iValThree的地址
常量指针,指针常量容易搞混淆,有一个比较好的办法,在星号(*)右边画一条竖线,

const在竖线左边:不能修改内容(内容为常量),如以上代码中示例1

const在竖线右边:不能修改指针本身(指针本身为常量),如以上代码中示例2

const在竖线两边:不能修改指针本身及其指向的内容,如以上代码中示例3

3.指针和数组

3.1指针和一维数组

	int a[10];
	for (int i = 0; i < 10; i++)
	{
		a[i] = i;
	}
	int *p = a;//同:int *p = &a[0];
	for (int i = 0; i < 10; i++)
	{
		cout << *p << endl;
		p++;
	}

数组地址与指针

	int a[10];
	for (int i = 0; i < 10; i++)
	{
		a[i] = i;
	}
	int *p;
	p = &a[0];
	cout << *(a + 1) << endl;//输出1
	cout << *(p + 2) << endl;//输出2


3.2指针与二维数组

二维数组的内存地址是连续的,可以将二位数组看做一维数组。

	int iArrayOfTwoDim[3][4] = 
	{
		{1,2,3,4},
		{5,6,7,8},
		{9,10,11,12}
	};
	//输出二维数组
	for (size_t i = 0; i < 3; i++)
	{
		for (size_t j = 0; j < 4; j++)
		{
			cout << setw(5)<< iArrayOfTwoDim[i][j];
<span style="white-space:pre">			</span>//同:<span style="font-family: Arial, Helvetica, sans-serif;">cout << setw(5)<< </span><span style="font-family: Arial, Helvetica, sans-serif;">*(*(iArrayOfTwoDim + i) + j)</span><span style="font-family: Arial, Helvetica, sans-serif;">;</span>
		}
		cout << endl;
	}
	//转换为一维数组
	int iArrayOneDim[12];
	for (size_t i = 0; i < 3; i++)
	{
		for (size_t j = 0; j < 4; j++)
		{
			iArrayOneDim[i * 4 + j] = iArrayOfTwoDim[i][j];
		}
		
	}
	for (size_t i = 0; i < 12; i++)
	{
		cout << setw(3) << iArrayOneDim[i] << endl;
	}

输出:

    1    2    3    4
    5    6    7    8
    9   10   11   12
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
请按任意键继续. . .
二维数组通过指针访问地址输出,验证结果:二维数组在内存中是连续的

	int iArrayOfTwoDim[3][4] = 
	{
		{1,2,3,4},
		{5,6,7,8},
		{9,10,11,12}
	};
	int *pVal = iArrayOfTwoDim[0];//同:int *pVal = &iArrayOfTwoDim[0][0];
	//输出二维数组
	for (size_t i = 0; i < 3; i++)
	{
		for (size_t j = 0; j < 4; j++)
		{
			cout << "Value(Address " << pVal << "): " << *pVal++ << endl;
	
		}
		cout << endl;
	}

输出:

Value(Address 002EFBEC): 1
Value(Address 002EFBF0): 2
Value(Address 002EFBF4): 3
Value(Address 002EFBF8): 4

Value(Address 002EFBFC): 5
Value(Address 002EFC00): 6
Value(Address 002EFC04): 7
Value(Address 002EFC08): 8

Value(Address 002EFC0C): 9
Value(Address 002EFC10): 10
Value(Address 002EFC14): 11
Value(Address 002EFC18): 12

请按任意键继续. . .


4.指针与字符串

	//连接两个字符串 
	char cArrayOne[50], cArrayTwo[50];
	cout << sizeof(cArrayOne) << endl;
	char *pStr1 = cArrayOne, *pStr2 = cArrayTwo;
	cout << sizeof(pStr1) << endl;

	cout << "Please input str1:";
	gets_s(cArrayOne);
	cout << "Please input pStr2:";
	gets_s(cArrayTwo);
	while (*pStr1 != '\0')
		pStr1++;
	while (*pStr2 != '\0')
		*pStr1++ = *pStr2++;
	*pStr1 = '\0';
	cout << "str1 + str2:";
	pStr1 = cArrayOne;//将pStr1重新指向cArrayOne
	puts(pStr1);//同:puts(cArrayOne);

输出:

50
4
Please input str1:I am
Please input pStr2:fond of Cplusplus!
str1 + str2:I am fond of Cplusplus!
请按任意键继续. . .

Char*与Char[]的区别

char*指向常量时,内容不能修改;char[]可以修改;

	char *pStr = "I love c++!";
	pStr[0] = 'U';//编译时没问题,运行时error
	cout << pStr << endl;
用char[]

	char cArray[50] = "I love c++!";
	char *pStr = cArray;
	pStr[0] = 'U';//Ok
	cout << pStr << endl;




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值