これ
char symbols[3] = "123";
は有効なステートメントです。
1988 年の ANSI C 仕様によると、次のようになります。
文字型の配列は、文字列リテラルで初期化することができ、オプションで中括弧で囲みます。文字列リテラルの連続する文字 (空きがある場合、または配列のサイズが不明な場合は、終端の null 文字を含む) は、配列のメンバーを初期化します。
したがって、あなたがしていることは技術的には問題ありません。
文字配列は、初期化子に関する次の制約の例外であることに注意してください。
初期化されるオブジェクトよりも多くのイニシャライザがイニシャライザ リストにあってはなりません。
ただし、コードの技術的な正しさは、そのコードの「良さ」のごく一部にすぎません。この行char symbols[3] = "123";
はベテラン プログラマーをすぐに疑うでしょう。なぜなら、一見すると有効な文字列の初期化のように見え、後でそのように使用され、予期しないエラーや特定の死につながる可能性があるからです。
このルートに進みたい場合は、それが本当に望んでいるものであることを確認する必要があります。その余分なバイトを節約することは、これがあなたを巻き込む可能性のある問題に値しません。NULL シンボルを使用すると、配列を終了する明確な (ほとんどの場合) 方法が提供されるため、より適切で柔軟なコードを記述できます。
(ドラフト仕様はこちらから入手できます。)
このページの他の場所でルディのコメントを採用するために、§6.7.8 (p. 130) の C99 ドラフト仕様の 32 番目の例では、
char s[] = "abc", t[3] = "abc";
と同一です
char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
そこから、探している答えを導き出すことができます。
C99 仕様のドラフトは、ここにあります。