C言語で副作用を持つ演算を含む場合は、その副作用が実行されるタイミングが未定義となっているようですが、
以下のコード
int a[10];
int i;
while (i < 10)
a[i++] = i;
では、
a[i++] = i;
の代入演算子(=)の結合規則が右から左であるため、aのインデックスとしてiが参照されるよりも早くiの値を代入しているため、未定義にならないと思うのですが、実際はどうなのでしょうか?
(a[i] = i++; の場合は完全に未定義になる。)
実際にこのようなコードを書くことは無いと思いますが、気になったもので。
もしご存知の方がおいででしたら教えていただけないでしょうか。
よろしくお願いします。
No.1ベストアンサー
- 回答日時:
未定義ですね。
このURLを参考にしてください。
http://www.em.edu.waseda.ac.jp/~moriya/education …
参考URL:http://www.em.edu.waseda.ac.jp/~moriya/education …
ずばりとありがとうございました。
やはり値の評価に関する優先順位は定まっていないと見るべきなのですね。
疑問が解決しました。ありがとうございます。
No.3
- 回答日時:
演算子の優先順位にはいくつかの例外があり、後置インクリメント演算子もその1つです。
a[i++] = i; の i++ は優先順位が代入演算子よりもさらに低いので、a[i] = i; を実行したあとで i++ が実行されてしまいます。
また、未定義というのは「ゼロ」ではありません。
質問文は、「未定義の i に対して ++ を実行すると1が入る」という前提で話されていますが、特にC言語の場合は間違いです。
未定義値とは、本当に何が入っているか分からない値のことを指すので、もしかしたら、実行された段階で i の中に10とか50000とか3000とかが入っているかもしれないのです。
(VCの場合だと、作為的に 0x5F を入れたりしてるみたいですが)
その場合、質問文中のプログラム自体が動作しないことになりますよね。
i=0;
を記載するのを忘れていました。
すみません。
No1の方の内容で解決してしまいましたので、補足する間もありませんでしたが、お礼申し上げます。
ありがとうございました。
No.2
- 回答日時:
サンプルプログラムを組んで、確認してみるといいですね。
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
を出力しました。
ありがとうございます。
ただ、副作用の作用順序の優先順位はANSIでも定まっていないと聞いていたので、恐らく処理系によって違うのだと思います。
No1の方の内容で解決してしまいましたので、補足する間もありませんでしたが、お礼申し上げます。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- 高校 合成関数の定義域につきまして 1 2022/05/18 17:26
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Excel(エクセル) 別シートの表の値を参照したい 2 2022/03/30 15:11
- 作詞・作曲 或る曲の楽譜のコード進行の中に"F onA"なるものがありました。これはどんな和音ですか? 7 2023/05/22 00:34
- 英語 セキュリティーの英語的ニュアンス 3 2022/04/08 23:43
- 日本語 <代名詞><指示詞>という誤り 4 2022/04/01 11:06
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
long型の定数の末尾にLを付ける...
-
DWORDの実際の型は何でしょうか
-
構造体の要素すべてに対する四...
-
typedef enumの使い方を教えて...
-
visualstudio C# テキストボッ...
-
C++のfor文について
-
関数の実体定義にヘッダファイ...
-
2重定義って??
-
変数の型を定義しなかった場合...
-
C言語 宣言した変数になにも代...
-
直接アドレス指定のポインタの...
-
void func( void )について
-
C言語でmain関数でのreturnとexit
-
main.c:7:43: warning: implici...
-
【#define】 defineで定義した...
-
GCCで暗黙の型変換の警告を出し...
-
不正な構造体の演算
-
引数で argc argvが使用され...
-
intとINTの違いは?
-
構造体のvectorを引数として関...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DWORDの実際の型は何でしょうか
-
visualstudio C# テキストボッ...
-
2重定義って??
-
long型の定数の末尾にLを付ける...
-
C++のfor文について
-
typedef enumの使い方を教えて...
-
関数の実体定義にヘッダファイ...
-
変数の型を定義しなかった場合...
-
ハンドルされていない例外が発...
-
C++でboolにintの値を代入する...
-
main.c:7:43: warning: implici...
-
プログラムの中で別のmainを呼...
-
【#define】 defineで定義した...
-
void func( void )について
-
構造体の要素すべてに対する四...
-
C++の(左辺値)参照を参照渡し
-
構造体の宣言でエラーが出ます。
-
main()とint main(void)の違い
-
intとINTの違いは?
-
エラー「invalid conversion fr...
おすすめ情報