C++では、charとchar [1]の使用の違い(ある場合)は何ですか。
例:
struct SomeStruct
{
char x;
char y[1];
};
Unsigned charについても同じ理由が続きますか?
主な違いは、1つの文字にアクセスするために使用する構文だけです。
「アクセス」とは、言語のさまざまな演算子を使用して操作することを意味します。これらの演算子のほとんどまたはすべては、char
配列と比較してchar
に適用すると異なる動作をします。これにより、x
とy
がほぼ完全に異なるように聞こえます。実際には、両方とも1つの文字で「構成」されていますが、その文字は非常に異なる方法で表されています。
実装couldは、他の違いを引き起こします。たとえば、使用する構造に応じて構造を異なる方法で整列およびパディングすることができます。しかし、私はそうなるとは思えません。
演算子の違いの例は、charが割り当て可能であり、配列が割り当て可能ではないことです。
SomeStruct a;
a.x = 'a';
a.y[0] = 'a';
SomeStruct b;
b.x = a.x; // OK
b.y = a.y; // not OK
b.y[0] = a.y[0]; // OK
しかし、y
が割り当て可能ではないという事実は、SomeStruct
が割り当て可能であることを停止しません。
b = a; // OK
これはすべて、char
かどうかに関係なくタイプに関係ありません。ある型のオブジェクトと、サイズ1のその型の配列は、メモリ内の内容に関してはほとんど同じです。
余談ですが、char
とchar[1]
から「使用」する大きな違いがあり、配列が実際にはポインタであると人々を混乱させるのに役立つ場合があります。あなたの例ではありませんが、関数パラメーターとして:
void foo(char c); // a function which takes a char as a parameter
void bar(char c[1]); // a function which takes a char* as a parameter
void baz(char c[12]); // also a function which takes a char* as a parameter
bar
およびbaz
の宣言で提供される数値は、C++言語では完全に無視されます。どうやらある時点で誰かがドキュメントの形式としてプログラマーにとって有用であると感じ、関数baz
がそのポインター引数が12文字の配列の最初の要素を指すことを期待していることを示しています。
Barとbazでは、c
は配列型を持ちません-配列型のように見えますが、そうではありません。char *c
と同じ意味を持つ単なる特別な場合の構文です。そのため、「使用」に引用符を付けました。実際にはchar[1]
を使用していませんが、そのように見えます。
構成を実際に見た場合はchar y[1]
本番コードの構造体の最後のメンバーとして、 struct hack のインスタンスに遭遇した可能性がかなりあります。
その短い配列は、実際の可変長配列の代用です(c99以前はc標準にはそのようなものがなかったことを思い出してください)。プログラマーは常にそのような構造体をヒープに割り当て、割り当てが使用したい配列の実際のサイズに対して十分な大きさになるように注意します。
スティーブによって強調された使用法の表記上の違いと同様に、char [1]は例えばに渡すことができます。 template <int N> void f(char(&a)[N])
、ここでchar x = '\0'; f(&x);
は一致しません。配列引数のサイズを確実にキャプチャすることは、非常に便利で安心です。
また、実際の長さが長くなる可能性がある(dmckeeで説明されている)か、コンテンツが論理的にASCIIZ文字列(この場合は空)であるか、文字の配列(発生する)のいずれかである可能性があります。 1つの要素を持つ)。構造がいくつかの関連する構造の1つである場合(たとえば、配列サイズがテンプレート引数である数学的ベクトル、または一部のI/O操作に必要なメモリのレイアウトのエンコード)、他のフィールドとの類似性が完全にあります。配列が大きくなる可能性がある場合は、単一文字の配列を優先することを示唆し、サポートコードをより単純にしたり、より普遍的に適用したりできるようにします。