質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

5回答

8152閲覧

for文で使う変数iはどこで宣言すればいいか

N---------

総合スコア46

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2018/12/09 14:09

編集2018/12/09 14:14

下の二つのプログラムは、変数iを宣言している場所が違いますがどちらのほうが良いのですか?

c

1for(int i=0; i<max; ++i){}

c

1int i; 2 3for(i=0; i<max; ++i){}

スコープはなるべく小さくするという設計思想がありますが、それに基づくと上のプログラムのほうがいい気がします。
あと、変数がメモリに領域を確保する時間をプログラマは考慮すべきなのですか?一瞬なので考慮しなくてもいいのですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

ベストアンサー

for文内でint iを宣言した場合、そのiの値をfor文の外で使えません。

c

1for(int i=0; i<max; ++i){ 2 if (condition(i) > 0 { 3 break; 4 } 5} 6 7/* iの値はわからない */ 8

例えば、breakなどでfor文から抜けだしたときに、どこまで処理したいかを知る方法はありません。
その場合、for文の外でint iを宣言しておきます。

c

1int i; 2 3for(i=0; i<max; ++i){ 4 if (condition(i) > 0 { 5 break; 6 } 7} 8 9/* iの値はわかる */

また、for文の外でint iを宣言した場合、このプログラムを読む人はiの値をどこかで使うだろうと予測してプログラムを読みます。そういう意味でもスコープはなるべく小さくする方がいいです。

投稿2018/12/09 14:25

fu7mu4

総合スコア1088

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

N---------

2018/12/09 14:52

回答ありがとうございます。使い分けの方法も教えてくれて助かりす!
guest

0

最初のコードでは、forループの中だけが有効範囲となります

あと、変数がメモリに領域を確保する時間をプログラマは考慮すべきなのですか?

考慮する必要はありません。
ローカル変数はどこで宣言しようと、関数が始まるときに確保され、終了するときに開放されます

投稿2018/12/09 14:19

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

N---------

2018/12/09 14:24

回答ありがとうございます。 例えば、 for(int i=0; i<max; ++i){...} for(int i=0; i<max; ++i){...} という風に、変数iが2回宣言されたプログラムを書いても、実行するときにはiの領域は一度しか確保されないのですか?
y_waiwai

2018/12/09 14:26

それはコンパイラ依存となりますが、たいていは同じ領域を使い回されるようになるかと思われます
guest

0

誰も触れてなかったので

できるならfor(int i = 0;の方がいいです。

大昔のC言語(C89)はコレができないので関数冒頭でint i;としているコードがあるわけです。

なお、大昔の事を気にしてる筈なのに行コメント//を使ってるコードはよくわからないです。

投稿2018/12/09 23:15

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2018/12/10 11:54

余談ですが、 > 大昔の事を気にしてる筈なのに行コメント//を使ってるコードはよくわからないです。 行コメント (//) は比較的早い時期に(現実のコンパイラでは)サポートされていました。使い勝手が良いので、使う人、結構居ましたね。当時、抵抗した記憶がある。(非標準だったので) その一方、 for()内でのサポートは遅かったと思う。昔のコードを使いまわしている事を考えると、不思議ではありません。(感覚的には)多数派は標準なんて気にせず、便利なものを使う。
asm

2018/12/10 14:15

同時期だと勝手に思っていましたが 違いがあったのですね
guest

0

... どちらのほうが良いのですか? ...

for(int i=0; i<max; ++i)のほうが良いです。
スコープが狭くなるからです。

... 変数がメモリに領域を確保する時間 ...

ローカル変数は スタック領域を使います。 スタック領域は、malloc などでメモリ領域確保されるわけではありません。
コンパイラが、iは スタック領域のどこ(offset)使うか決定してくれるだけです。
for の外、中のどちらで i を宣言しても速度に差は出ないはずです。

実際に確認はしていませんが、次の3つはどれも同じようコンパイルされると思います。

int i, j; for (i = 0; ...) {} for (j = 0; ...) {}
for (int i = 0; ...) {} for (int j = 0; ...) {}
for (int i = 0; ...) {} for (int i = 0; ...) {}

興味があれば、 どんなふうにコンパイルされるかを実際に確認してみることをおすすめします。
参考情報

  • C言語のコードをアセンブラ出力を確認しながら最適化する

https://nagayasu-shinya.com/cpp-optimize-assembler/

投稿2018/12/09 14:54

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2018/12/10 11:48

今更ですが、 > 次の3つはどれも同じようコンパイルされる コンパイラと最適化によって異なるのではないかと。 特に最初の例は、最適化されると、i, j が使いまわされた場合、デバッグ時に注意が必要になる事あり。(古いコンパイラだけ?) 昔、そのトラップにハマり、抜けるのに数時間を費やしたことがあります。 ... 2個目の for()を抜けた場所で、break ここで、i を参照すると、jの値が表示されていた。(要するに、レジスタの使いまわし)
katoy

2018/12/10 12:56

> ... 最適化によって異なる ... はい、確かにそうですね。 とはいえ、速度に問題となるほどの差がでることはないと思います。
guest

0

あと、変数がメモリに領域を確保する時間をプログラマは考慮すべきなのですか?一瞬なので考慮しなくてもいいのですか?

C言語の場合は、ローカル変数を宣言しても、それはコンパイラに対する指示でしかなくて、(実用的な処理系の場合)コンパイルしてしまえば「メモリのこの位置」あるいは「このレジスタ」という形で、変数の保存されている機械的な位置を直接参照するようなコードが出来上がるだけですので、「変数を宣言するたびにメモリ確保が起きる」ことはありません(ローカル変数用のメモリ領域は「スタック」としてもとから確保されています)。

C++の場合、intなど普通の型はC言語と事情が同じですが、クラスなどコンストラクタデストラクタがある型の変数を作った場合は、スコープインするとコンストラクタが動いて、スコープアウトするとデストラクタが動きますので、その動作分の負荷はかかります。

投稿2018/12/09 14:32

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問