50

偶然にも、行char s[] = {"Hello World"};が適切にコンパイルされており、 と同じように扱われていることがわかりましたchar s[] = "Hello World";。最初の ( {"Hello World"}) は char の配列である 1 つの要素を含む配列ではないので、s の宣言は と読む必要がありますchar *s[]か? 実際、コンパイラに変更するとchar *s[] = {"Hello World"};、予想どおり、コンパイラもそれを受け入れます。

答えを探して、これに言及した唯一の場所はこれですが、標準の引用はありません。

だから私の質問は、char s[] = {"Hello World"};左側が型array of charで右側が型であるのに、なぜ行がコンパイルされるのarray of array of charですか?

以下は作業プログラムです。

#include<stdio.h>
int main() {
    char s[] = {"Hello World"};
    printf("%s", s); // Same output if line above is char s[] = "Hello World";
    return 0;
}

明確にしていただきありがとうございます。

PS 私のコンパイラは gcc-4.3.4 です。

4

6 に答える 6

65

標準がそう言っているので許可されています: C99 セクション 6.7.8, §14:

文字型の配列は、文字列リテラルで初期化することができ、オプションで中括弧で囲みます。文字列リテラルの連続する文字 (空きがある場合、または配列のサイズが不明な場合は、終端の null 文字を含む) は、配列の要素を初期化します。

これが意味することは、両方とも

char s[] = { "Hello World" };

char s[] = "Hello World";

の構文糖衣に過ぎない

char s[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 };

関連する注記 (同じセクション、§11) では、C では、次のようなスカラー初期化子を中括弧で囲むこともできます。

int foo = { 42 };

ちなみに、これは複合リテラルの構文にうまく適合します

(int){ 42 }
于 2012-04-13T19:50:10.193 に答える
22

中かっこはオプションであり、式は単なる char の配列と同等です。

これを書くこともできます:

 int a = {100}; //ok

デモ: http://ideone.com/z0psd

実際、C++11この構文を一般化して、配列だけでなく非配列も一様に初期化します。ではC++11、次のものを使用できます。

int a{}; //a is initialized to zero, and it is NOT an array

int b[]{1,2,3,4}; //b is an array of size 4 containing elements 1,2,3,4

int c[10]{}; //all 10 elements are initialized to zero

int *d{}; //pointer initialized to nullptr

std::vector<int> v{1,2,3,4,5}; //vector is initialized uniformly as well.
于 2012-04-13T19:45:10.227 に答える
4

int( 、など)内の変数はchar、長さ 1 の単なる配列です。

char s = {0};

同様に動作します。

于 2012-04-13T19:46:21.660 に答える
2

私は間違っているかもしれませんが、これは文字の配列の配列ではなく、ブロックには文字の配列が含まれていると思います。int a = {1};同様に機能する場合があります。

于 2012-04-13T19:45:43.640 に答える
1

[...]実際、char * s [] ={"HelloWorld"}に変更すると; コンパイラは期待どおりにそれも受け入れます

コンパイラはそれを受け入れます。実際には、未定義のサイズの要素の2D配列を作成しており、1つの要素("Hello World"文字列)のみを格納しているためです。このようなもの:

char* s[] = {"Hello world", "foo", "baa" ...};

この場合、を省略することはできませんbracets

于 2012-04-13T20:19:44.620 に答える
1

これは、C++ 標準でも許可されています。引用:

[dcl.init.string] §1

ナロー文字型 ([basic.fundamental])、char16_t 配列、char32_t 配列、または wchar_t 配列の配列は、ナロー文字列リテラル、char16_t 文字列リテラル、char32_t 文字列リテラル、またはワイド文字列リテラルによってそれぞれ初期化できます中括弧で囲まれた適切に型指定された文字列リテラル([lex.string])。[をちょきちょきと切る]

于 2016-07-29T10:56:17.020 に答える