アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語で副作用を持つ演算を含む場合は、その副作用が実行されるタイミングが未定義となっているようですが、
以下のコード

int a[10];
int i;

while (i < 10)
a[i++] = i;

では、
a[i++] = i;
の代入演算子(=)の結合規則が右から左であるため、aのインデックスとしてiが参照されるよりも早くiの値を代入しているため、未定義にならないと思うのですが、実際はどうなのでしょうか?

(a[i] = i++; の場合は完全に未定義になる。)

実際にこのようなコードを書くことは無いと思いますが、気になったもので。
もしご存知の方がおいででしたら教えていただけないでしょうか。
よろしくお願いします。

A 回答 (3件)

未定義ですね。


このURLを参考にしてください。

http://www.em.edu.waseda.ac.jp/~moriya/education …

参考URL:http://www.em.edu.waseda.ac.jp/~moriya/education …
    • good
    • 0
この回答へのお礼

ずばりとありがとうございました。
やはり値の評価に関する優先順位は定まっていないと見るべきなのですね。
疑問が解決しました。ありがとうございます。

お礼日時:2004/03/23 13:12

 演算子の優先順位にはいくつかの例外があり、後置インクリメント演算子もその1つです。



 a[i++] = i; の i++ は優先順位が代入演算子よりもさらに低いので、a[i] = i; を実行したあとで i++ が実行されてしまいます。

 また、未定義というのは「ゼロ」ではありません。

 質問文は、「未定義の i に対して ++ を実行すると1が入る」という前提で話されていますが、特にC言語の場合は間違いです。
 未定義値とは、本当に何が入っているか分からない値のことを指すので、もしかしたら、実行された段階で i の中に10とか50000とか3000とかが入っているかもしれないのです。
(VCの場合だと、作為的に 0x5F を入れたりしてるみたいですが)

 その場合、質問文中のプログラム自体が動作しないことになりますよね。
    • good
    • 0
この回答へのお礼

i=0;
を記載するのを忘れていました。
すみません。

No1の方の内容で解決してしまいましたので、補足する間もありませんでしたが、お礼申し上げます。
ありがとうございました。

お礼日時:2004/03/23 13:15

サンプルプログラムを組んで、確認してみるといいですね。



sample1()
{
  int a[10] ;
  int i ;

  for (i= 0 ;i<10 ;i++) a[i] = 100 ;
  i = 0 ;
  while ( i < 10 ) a[i++] = i ;
  for (i=0 ;i<10 ;i++) printf("a[%d] = %d\n",i,a[i]);
}

sample2()
{
  int a[10] ;
  int i ;

  for (i= 0 ;i<10 ;i++) a[i] = 100 ;
  i = 0 ;
  while ( i < 10 ) a[i] = i++ ;
  for (i=0 ;i<10 ;i++) printf("a[%d] = %d\n",i,a[i]);
}

sample1は
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
a[8] = 9
a[9] = 10

sample2は
a[0] = 0
a[1] = 1
a[2] = 2
a[3] = 3
a[4] = 4
a[5] = 5
a[6] = 6
a[7] = 7
a[8] = 8
a[9] = 9

を出力しました。
    • good
    • 0
この回答へのお礼

ありがとうございます。
ただ、副作用の作用順序の優先順位はANSIでも定まっていないと聞いていたので、恐らく処理系によって違うのだと思います。

No1の方の内容で解決してしまいましたので、補足する間もありませんでしたが、お礼申し上げます。
ありがとうございました。

お礼日時:2004/03/23 13:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!