これは私が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文字の長さを割り当てた後、入力にcinを使用して、pCharが5文字を含む文字配列になるようにします。
だが(重要なポイント)
coutを出力に使用すると、文字が文字化けします。入力した文字も出力できますが、文字化けがたくさん続きます。以下に示すように:
1.2問題の原因:
費用-はい、それはカウトです!
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に転送します。入力後にEnterキーを押すと、coutは5文字を順番に直接読み取り、pCharに格納します。入力長がpCharの長さよりも長い場合でも、pCharには5文字しか格納されません。
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が「\ 0」を格納するためにメモリを割り当てるときにcharメモリを割り当てる必要があります。これにより、coutは、直接出力するときに「\ 0」を読み取ったときに出力の終わりを判断するため、表示されません。文字化け。
プログラムの出力は次のとおりです。
個人的には、coutに制御を渡すことは非常に危険な動作であると感じています。この点を説明するための関連する例はまだ考えていませんが、人々がコンピューターを制御しているので、制御は間違いなくしたがって、作成者は、ソリューション2の最後にヌル文字を追加する方がよいと考えています。
ピット2:
2.1問題の説明:
演算子オーバーロード添え字演算子を使用する場合、オブジェクトが2次元配列の場合はどうなりますか?
実際、これは問題ではありませんが、ピットを踏んだときに作者が遭遇した非常に興味深い問題です。私が書いたプログラムは正常に出力できますが、私自身の理解では出力されません。
プログラムコードは次のとおりです。
#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
コードのクラスAに2次元配列のメンバー変数があります。次に、C ++を実装して、添え字演算子をオーバーロードして2次元配列の値を取得します。これは:
class A{
};
type c = A[i][j];
この種の操作は、クラスAの使用を非常に便利にします。したがって、添え字演算子はオーバーロードする必要があります。
ただし、添え字演算子は単項演算子であり、入力パラメーターは1つだけです。じゃあ何をすればいいの?2次元配列は1次元配列と見なすことができますが、1次元配列の要素はポインタです。その後、問題は簡単に処理でき、リロードできます。
次のように:
int* operator[](int iIndex)
{
return _ia[iIndex];
}
コード内の_iaはクラスAの2次元配列であるため、オーバーロードされた添え字演算子の場合、最初に整数を渡して2次元配列の行要素を取得し、行要素はint型のポインターです。ポインタを取得したら、リロードしてください!
コードは次のように表示されます。
int operator[](int* jIndex)
{
return *jIndex;
}
(手動で面白い<-<-)
添え字演算子を2回オーバーロードし、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はクラスAのインスタンス化されたオブジェクトであるため、testa [i]はクラスAのオーバーロードされた演算子を呼び出し、返される結果はint型のポインターであり、このポインターはtestaのメンバー変数_iaの要素でもあります。次に、(_ ia [i])[j]は、_iaのi番目の行とj番目の列の値を出力します。
クラスAのオーバーロードについて
int operator[](int* jIndex)
{
return *jIndex;
}
この添え字演算子は実際には役に立たない、それはまったくたわごとです
=======================分割線-ピットに遭遇した後、更新================= ================================================== ================================================== ================================================== ================================================== =============================================== ===