48778

[code]

    #include <stdio.h>
    int main()
    {
        int end = 0;
        char d[5];
        int digits = 0;
        d[digits++] = digits;
        printf("digits=%d\n",digits);
        printf("d[0]=%d\n",d[0]);
    
        do{
            printf("if enter 1, end.");
            scanf("%d",&end);
        }while (end = 0);
    
        return 0;
    }
    
[/code]

\---実行結果---  
digits=1  
d[0]=1  
if enter 1, end.

\---僕の理想の実行結果---  
digits=1  
d[0]=0 ←ここが0  
if enter 1, end.


CC BY-SA 4.0
2018-09-28T00:13:26.797
48777
2018-09-28T01:06:56.427
20666
question
c
d[digits++] = digits;と書くと、インクリメントは式が終わったあとって聞いたんですけど、なってないみたいです。誰か説明してくれませんか。


式が終わった後にインクリメントされてるから`d[0]`に`1`が入ってるんですよ。

インクリメントは値を返した後に行われます。  
つまり、`digits`の値を`d[digits++]`に使った後には加算済み。  
なので、左辺の処理が終わった後には`digits`は加算済みで、その後右辺が処理され、代入処理がうごいていると思われます。

ただ、この左辺と右辺の演算順は定義されていなかったんじゃないかな？  
なのでビルド環境を変えると、右辺処理して、左辺処理して、インクリメント、代入と所望の動きが得られるものもあるんじゃないかと思います。

Cでは定義されていない仕様もあって、その場合の結果は処理系に依存してしまいます。  
要は、コンパイラなどのバイナリを出力する過程で使われるプログラムによって、出力結果が変わってしまう事があるということですね。  
関数の定義などを見ていても、`～の場合は未定義`と説明されているのを見かけた事があるんじゃないでしょうか？

どのビルド環境だとそうなるという解は持ち合わせていませんが、処理系に依存するプログラムを書いていると、移植などを行う際に想定外の挙動が起きたりするのでオススメ出来ません。


CC BY-SA 4.0
2018-09-28T00:43:21.627
48778
2018-09-28T00:50:56.403
2018-09-28T00:50:56.403
2383
2383
48777
answer


[EXP30-C. 副作用が発生する式の評価順序に依存しない](https://www.jpcert.or.jp/sc-
rules/c-exp30-c.html)が参考になるでしょうか。

>
[code]

>     d[digits++] = digits;
>  
[/code]

C言語では、演算子の結合順序は定められていますが、評価順序は一部を除いて定められていません。`=`の左右どちらを先に評価するかは未定義です。

### 左辺値を先に評価した場合

`d[digits++]`が評価されます。`d[0]`を得つつ`digits`が`1`にインクリメントされます。次に`digits`が評価されます。`digits`は`1`です。最後に`=`が評価され`d[0]`は`1`となります。

### 右辺値を先に評価した場合

`digits`が評価されます。`digits`は`0`です。次に`d[digits++]`が評価されます。`d[0]`を得つつ`digits`が`1`にインクリメントされます。最後に`=`が評価され`d[0]`は`0`となります。

* * *

「一部を除いて」とは、よく知られているように`&&`や`||`、`,`は左辺値を先に評価することが定められていますし、`?:`も条件式が先に評価されます。


CC BY-SA 4.0
2018-09-28T01:06:56.427
48779
2018-09-28T01:06:56.427
4236
48777
answer