char *a と char b[] にはどのような違いがありますか

[code]

    char* a  = "AAA";
    char b[] = "BBB";
    
[/code]

上のように宣言しても

[code]

    for( int i=0; a[i]; i++ ){ cout << a[i]; }
    for( int i=0; b[i]; i++ ){ cout << b[i]; }
    
[/code]

上のように同じように利用しているので違いがわからないのですが、`a`と`ｂ`には違いがありますか




文字列がどのようなメモリに配置されるかが異なってきます。

  * `char* a = "AAA";`は、コンパイラが静的記憶期間の（プログラムの実行開始から終了までずっと存在する）メモリ領域に文字列を配置し、それへのポインタを`a`に代入するというものです。
  * 一方、`char b[] = "BBB";`は`char b[] = { 'B', 'B', 'B', '\0' };`の別表記です。配列の初期化においてのみ`""`の文字列リテラルはこのようにほかと違う取り扱いになります。

そのため、以下のように、変数の寿命を越えると差が出ます。

まず、`const char*`の変数の場合、`return`しても文字列本体は有効です。

[code]

    #include <cstdio>
    
    const char* f()
    {
        const char* a = "ABC";
        return a;
    }
    
    int main()
    {
        puts(f());
    }
    
[/code]

一方、配列を使った以下のプログラムでは、未定義の動作になります。関数から抜けると共にオブジェクト`b`が破棄されるためです。実例としては、デタラメな文字列が出力されたり、クラッシュしたりすることがあります。場合によっては、abcが出力されるものもありますが、偶然だと考えてください。

[code]

    #include <cstdio>
    
    const char* f()
    {
        char b[] = "abc";
        return b;
    }
    
    int main()
    {
        puts(f());
    }
    
[/code]

参考

  * [C FAQ 6章 配列とポインター 6.2: でもchar a[]はchar *aと同じと聞いたことがあるが。](http://www.kouno.jp/home/c_faq/c6.html#2)
  * [DCL30-C. 適切な記憶域期間を持つオブジェクトを宣言する](https://www.jpcert.or.jp/sc-rules/c-dcl30-c.html)




文字列がどのようなメモリに配置されるかが異なってきます。

  * `char* a = "AAA";`は、コンパイラが静的記憶期間の（プログラムの実行開始から終了までずっと存在する）メモリ領域に文字列を配置し、それへのポインタを`a`に代入するというものです。
  * 一方、`char b[] = "BBB";`は`char b[] = { 'B', 'B', 'B', '\0' };`の別表記です。配列の初期化においてのみ`""`の文字列リテラルはこのようにほかと違う取り扱いになります。

そのため、以下のように、変数の寿命を越えると差が出ます。

まず、`const char*`の変数の場合、`return`しても文字列本体は有効です。

[code]

    #include <cstdio>
    
    const char* f()
    {
        const char* a = "ABC";
        return a;
    }
    
    int main()
    {
        puts(f());
    }
    
[/code]

一方、配列を使った以下のプログラムでは、未定義の動作になります。関数から抜けると共にオブジェクト`b`が破棄されるためです。実例としては、デタラメな文字列が出力されたり、クラッシュしたりすることがあります。場合によっては、abcが出力されるものもありますが、偶然だと考えてください。

[code]

    #include <cstdio>
    
    const char* f()
    {
        char b[] = "abc";
        return b;
    }
    
    int main()
    {
        puts(f());
    }
    
[/code]

参考

  * [C FAQ 6章 配列とポインター 6.2: でもchar a[]はchar *aと同じと聞いたことがあるが。](http://www.kouno.jp/home/c_faq/c6.html#2)
  * [DCL30-C. 適切な記憶域期間を持つオブジェクトを宣言する](https://www.jpcert.or.jp/sc-rules/c-dcl30-c.html)

