C++学习过程中的坑——持续更新

这是我在学习C++的过程中遇到的坑

坑1:

1.1 问题描述:

在用new运算符给字符数组分配内存的时候,使用cout输出时会出现乱码,代码如下:

#include <iostream>

using namespace std;

int main()
{
    
    
	char* pChar;

	pChar = new char[5];

	int i = 0;
	while (i < 5)
	{
    
    
		cin >> pChar[i];
		i++;
	}

	cout << pChar << endl;

	return 0;
}

pChar是一个字符指针,使用new运算符分配5个char长度之后,使用cin进行输入,这样pChar就是一个包含5个char的字符数组。
但是(重点来了)
在使用cout进行输出的时候,会出现乱码,虽然也能输出我们输入的字符,但是后面会跟一堆乱码。如下图:
输入fqwer,输出的前几个字符也是fqwer,但是后面跟了一堆乱码

1.2问题原因:

cout——没错,就是cout!
C++中,cout在对字符数组进行输出的时候,判断输出结束的标识是空字符,即’\0’。但是我们在输入的时候,pChar数组结尾并没有空字符,所以cout无法判断什么时候输出结束。也就是说,在输出完了pChar之后,由于找不到结尾的空字符,cout还是会接着输出pChar+4后面紧跟着的内存中的数据,那一块内存中谁都不知道有什么,可能什么都没有。所以会出现乱码。
如下图中的输出结果:
在这里插入图片描述

1.3解决方法

1.3.1 去掉循环输入

可以将代码改成这样:

#include <iostream>

using namespace std;

int main()
{
    
    
	char* pChar;

	pChar = new char[5];

	cout << "请输入5个字符:";
	cin >> pChar;

	for (int i = 0; i < 5; i++)
	{
    
    
		cout << "pChar[" << i << "]" << "的值为:" << pChar[i] << "------";
		cout << "pChar[" << i << "]" << "的地址为:" << &pChar + i << endl;
	}
	cout << "pChar的最后一个元素的后面一个内存的地址为:" << &pChar + 5 << ", 其值为:" << pChar + 5 << endl;

	cout <<"直接输出pChar的结果为:"<< pChar << endl;


	return 0;
}

这样的输出结果为:
在这里插入图片描述

原因分析:

不使用循环输入,直接将判断权交给cout。当我们在输入之后按下回车,cout会直接顺序读取5个字符存入到pChar中,即使输入长度大于pChar的长度,也还是只取5个存入到pChar中。

1.3.2 循环输入时加入空字符

代码如下:

#include <iostream>

using namespace std;

int main()
{
    
    
	char* pChar;

	pChar = new char[6];

	cout << "请输入5个字符:";
	for (int i = 0; i < 5; i++)
		cin >> pChar[i];
	pChar[5] = '\0';

	for (int i = 0; i < 5; i++)
	{
    
    
		cout << "pChar[" << i << "]" << "的值为:" << pChar[i] << "------";
		cout << "pChar[" << i << "]" << "的地址为:" << &pChar + i << endl;
	}
	cout << "pChar的最后一个元素的后面一个内存的地址为:" << &pChar + 5 << ", 其值为:" << pChar + 5 << endl;

	cout <<"直接输出pChar的结果为:"<< pChar << endl;


	return 0;
}

加入空字符的时候,需要在new分配内存的时候多分配一个char内存,用来存储‘\0’,这样cout在直接输出的时候读到‘\0’就会判断输出结束,因而不会出现乱码。
程序输出结果如下:
在这里插入图片描述
个人觉得,将控制权交给cout是一件非常不安全的行为,笔者暂时还未想出相关例证来说明这一点,但是既然是人控制计算机,控制权肯定应该在人的手中,因此笔者认为,解决方法2在末尾加入空字符更好。

坑2:

2.1 问题描述:

在使用运算符重载下标运算符时,如果对象是一个二维数组怎么办?

其实这不算一个问题,只是笔者在踩坑的时候遇到的一个非常有趣的问题,自己写的程序能正常输出,但是并不是按照自己的理解来输出。
程序代码如下:

#include <iostream>
using namespace std;

class A
{
    
    
public:
	int _ia[3][4];

	void putData()
	{
    
    
		for (int i = 0; i < 3; i++)
		{
    
    
			for(int j=0;j<4;j++)
				cin >> _ia[i][j];
		}
	}

	int* operator[](int iIndex)
	{
    
    
		return _ia[iIndex];
	}
	int operator[](int* jIndex)
	{
    
    
		return *jIndex;
	}
};

int main()
{
    
    
	A testa;
	testa.putData();

	for (int i = 0; i < 3; i++)
	{
    
    
		for (int j = 0; j < 4; j++)
			cout << testa[i][j]<<"\t";
		cout << endl;
	}

	return 0;
}

// 1 2 3 4 5 6 7 8 9 10 11 12

代码中 class A里有一个二维数组的成员变量,现在想通过重载下标运算符来实现C++对二维数组那样取值。即:

class A{
    
    };
type c = A[i][j];

这种操作会使得对于 class A的使用变得十分方便。因此必须重载下标运算符。
但是下标运算符是一个一元运算符,输入参数只有一个。那么怎么办呢?都知道二维数组可以看成是一维数组,只不过该一维数组的元素是一个指针。那么问题好办了,重载!
如下:

	int* operator[](int iIndex)
	{
    
    
		return _ia[iIndex];
	}

代码中的_ia是 class A 中的二维数组,因此对于重载的下标运算符,首先传入一个整型取得该二维数组的行元素,该行元素是一个int类型的指针。取得该指针之后,那么接着重载啊!
代码如下:

	int operator[](int* jIndex)
	{
    
    
		return *jIndex;
	}

(手动滑稽 <-<-)

第二次重载下标运算符,传入一个int类型的指针,输出该类型的值。写到这里我自己都笑了。。
好嘛,看起来正常,实际上一点都不正常,某些大佬可能看一眼就觉得看起来都不正常。
但是程序能够正常输出,输出部分代码如下:

	A testa;
	testa.putData();

	for (int i = 0; i < 3; i++)
	{
    
    
		for (int j = 0; j < 4; j++)
			cout << testa[i][j]<<"\t";
		cout << endl;
	}

既然程序看起来都不正常,那为什么还能正常输出呢?

原因如下:

testa是class A的实例化对象,因此testa [ i ]是调用A类里的重载运算符,返回结果是一个int类型的指针,而且这个指针还是testa的成员变量 _ia的元素。再然后,(_ia [ i ])[ j ]输出的就是_ia的第 i 行第 j 列的值。
至于class A中重载的

	int operator[](int* jIndex)
	{
    
    
		return *jIndex;
	}

这个下标运算符,实际上没啥用,根本就是SHIT
在这里插入图片描述
=======================分割线——以后遇到坑接着更新====================

猜你喜欢

转载自blog.csdn.net/GeomasterYi/article/details/106728267
今日推荐