最初のステートメントが機能する理由と、C++で2番目のステートメントが機能しない理由を知りたい
char a[10]="iqbal"; // it works
a="iqbal"; // does not work
最初のステートメントが機能する理由と、C++で2番目のステートメントが機能しない理由を知りたい
char a[10]="iqbal"; // it works
a="iqbal"; // does not work
厳密に言えば、配列はポインタではありません!また、配列(配列のベースアドレス)を変更可能な左辺値にすることはできません。つまり、代入演算子の左側に表示することはできません。配列は、特定の状況でのみポインターに減衰します。このSOの投稿を読んで、配列がいつポインターに減衰するかを確認してください。配列とポインタの違いを説明するもう1つの素晴らしい記事があります
また、ここで左辺値と右辺値について読んで、のLHSに表示できないもののアイデアを得ることができます。=
char a [10] = "iqbal"; // できます
この場合、内部で何が起こるかは
a[0] = 'i';
a[1] = 'q';
.
.
a[5] = '\0';
したがってarray[i]
、変更可能な左辺値と同様に、すべてが正常です。
a = "iqbal"; // 動作しません
内部的には、これはほぼ同等です
0x60000(Address of a, but is a simple number here ) = Address of "iqbal"
番号に何かを割り当てることができないため、これは間違っています。
char配列aは静的であり、このように初期化すると変更できません。とにかく、cで文字列a="iqbal"を割り当てることはできません。そのためにはstrncpyまたはmemcpyを使用する必要があります。そうでなければ、文字列へのポインタを上書きしようとしますが、それはあなたが望むものではありません。
したがって、正しいコードは次のようになります。
char a[10];
strncpy(a, "iqbal", sizeof(a) - 1);
a[sizeof(a) - 1] = 0;
-1は、終了ゼロ用に1バイトを予約するためのものです。文字列がnullで終了しているかどうかを自分で確認する必要があることに注意してください。悪いAPI。これを行うstrlcpy()呼び出しがありますが、glibcには含まれていません。
最初の行はステートメントではなく、初期化された宣言です。2行目は、代入演算子を使用した式ステートメントです。
Cで配列を割り当てることはできません。
ただし、文字列リテラルの要素を使用して配列を初期化することはできます。
C++で最初のステートメントが機能する理由と2番目のステートメントが機能しない理由
それらは異なるステートメントであるため、ほとんど完全に無関係です。=
どちらも記号を使用しているという事実に惑わされないでください。ある場合には、それはオブジェクトの初期化を表します。その他の場合、代入演算子。
文字配列を含む集計を初期化することは合法であるため、最初の行は合法です。
配列に割り当てることは合法ではないため、2行目は合法ではありません。
これはC++なので、裸の配列を避けることをお勧めしますか?文字列には。を使用しますstd::string
。他のアレイの場合はを使用しますstd::vector
。そうした場合、例は次のようになります。
std::string a = "iqbal"; // it works
a="iqbal"; // so does this
char a [10] = "iqbal"と書くときは、文字配列aの要素を文字で初期化しています。int型でも同じことができます( char型の扱いが少し異なることに注意してください):int a [10] = {1,2、...};
ただし、宣言の後に次の部分を書き込むと、aはポインタのように扱われるため、無効になります。したがって、a = {1,2、...}のようなものを書く; またはa="iqbal"は意味がありません!
試す:
char a[10]="iqbal";
char *my_a = a;
my_aを使用します。
C ++ 11では、次のようにラムダを使用して初期化を行うことができます。
bool test = true;
/*const*/ char a[10] = { //Aggregate initialization
[=] //capture by value
()//no parameters
{ //start lambda
switch (test) {
case true: return *"test=true"; //*"xxx" don't return a pointer, but the 'string' itself
case false: return *"test=false";
} //switch
}()}; //}, close the lambda, (), call it, }; close aggregate initialization
std::string
これは、 NVidiaのCUDAや奇妙な組み込み環境など、環境がサポートしていない場合に便利です。ラムダはインライン化されるため、内部的には次のように変換されます。char a[10] = test?"xxx":"yyy";
std::string
固定サイズのcharバッファは基本的に悪い考えであるため、そうするオプションがある場合は、明らかに常にを使用することをお勧めします。
を使用する場合は、次を使用std::string
してそれをchar配列に変換できますchararray = mystring.c_str();
。printf
これは、 :を使用することを主張する場合に役立ちますprintf("s = %s", mystring.c_str());
。
後者の宣言後に文字列リテラルをchar配列に割り当てることはできません。
素晴らしく、シンプルで効果的な代替手段はstd::strcpy
、次のように使用することです。
struct S
{
char name[30];
};
S s;
std::strcpy( s.name,
"The moribunds salute you." );