14605

[code]

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    int main(int argc, char** argv){
        cout<<strlen(&"123"[1])<<endl;
    }
    
[/code]

> 2  
>  Enterキーを押すと、ターミナルが終了します...

この書き方でなぜエラーが出ないのか全く理解ができません  
エラーが出ないからには何かしらの理解の仕方があると思うのですがさっぱりです。  
これは、コンパイラから見てどう解釈されているのですか


CC BY-SA 3.0
2015-08-18T10:24:49.487
14585
2015-08-19T02:18:41.563
10972
question
c++
strlen(&"123"[1]) この書き方はでエラーが出ないのが不思議です


以下と同じです。

[code]

    std::cout << std::strlen("23") << std::endl;
    
[/code]

"123"の配列の2番目からの文字数をカウントしています。  
このように分解すると分かりやすいと思います。

[code]

    const char str[] = "abc"; // "123"だと混乱の元なので"abc"とした
    const char* p_str = &str[1]; // "b"が格納されているアドレスを取得する
    std::cout << std::strlen(p_str) << std::endl; // p_strが指し示しているのは"b"からなので"bc"の2文字とカウントされる
    
[/code]


CC BY-SA 3.0
2015-08-18T10:34:05.017
14587
2015-08-19T00:15:12.727
2015-08-19T00:15:12.727
7214
7214
14585
answer


既に回答がついていますが、簡潔すぎるのではないかと思い補足的に書きます。

(1)`"123"`は、既に書いた時点で`char[]`のリテラルです。

[code]

    cout << strlen(&"123"[1]) << endl;
    
[/code]

は、次と同様です。

[code]

    char[] str = "123";
    cout << strlen(&str[1]) << endl;
    
[/code]

実際のリテラルの中身は、次のようになってます。

[code]

    str[0] : '1'
    str[1] : '2'
    str[2] : '3'
    str[3] : '\0'(null)
    
[/code]

(2)`"123"[1]`は、`"123"`という`char[]`リテラルの第2要素を指しています。つまり`str[1]`です。

つまり、`"123"[1]`そのものは、`str[1]`と同じなので、2文字目にある`'2'`です。

(3)`&"123"[1]`は、`&(str[1])`と同じで、`"123"`という`char[]`リテラルの第2要素のポインタ（通常は`'2'`のあるアドレス）を指しています。

(4)`strlen(&"123"[1])`は、`"123"`という`char[]`リテラルの第2要素から数えて、`'\0'`(null)が出てくるまでのcharの数なので、2（`str[1]`,`str[2]`で2つ）となります。


CC BY-SA 3.0
2015-08-18T11:07:00.140
14590
2015-08-18T15:31:02.103
2015-08-18T15:31:02.103
10492
10588
14585
answer


混乱を避けるため 123 でなくて abc としておく

`"abc"+1` だったらわかりやすかったのかも？  
悪乗りしてみるテスト  
`1+"abc"` とか  
`&1["abc"]` とか

ここに上げた例３つは全部、元質問の `&"abc"[1]` と同じ意味です。

コンパイラがどう解釈するかを [c](/questions/tagged/c "'c' のタグが付いた質問を表示")
[c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") 言語仕様書的に解説するなら  
\- `P[Q]` は `*(P+Q)` と解釈される  
\- 配列 (この例では文字列リテラルが文字の配列です) は容易にポインタ右辺値に成り下がる  
\- ポインタ右辺値と整数値の加算の場合 `P` と `Q` が入れ替わっても結果は同じ  
\- `&(*(P))` は `P` そのもの。つまり `&P[Q]` は `P+Q` になる  
ってとこでしょうか。


CC BY-SA 3.0
2015-08-19T02:18:41.563
14605
2015-08-19T02:18:41.563
8589
14585
answer