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

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

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

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

Q&A

解決済

4回答

543閲覧

このwhile文において、while文より先に初期値を定義しないのはなぜですか。

jerryfish2357

総合スコア2

C++

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

0グッド

1クリップ

投稿2024/09/05 10:20

#include <iostream>

int main() {
while (true) {
int x, y;
std::cin >> x >> y;

   if (x == 0 and y == 0) break;

  if (x < y) {   std::cout << x << " " << y << std::endl;    } else {   std::cout << y << " " << x << std::endl;    }

  }

return 0;
}

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

上のソースコードは模範解答です。

2つの整数 x, y を読み込み、それらを値が小さい順に出力するプログラムを書きたいです。
while文を書く前に、x,yの初期値を設定しようと思ったのですが、この問題には必要がありませんでした。

初期値の定義が必要な時とそうでないときの違いをご教授いただければ幸いです。

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

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

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

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

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

guest

回答4

0

初期値の定義が必要な時とそうでないとき

初期化していない変数の値というのは不定(値がどうなってるのかわからない).
で,ある変数の値を用いる処理を実施するタイミングで,その変数の値が「どうなってるのか不明」っていうのだと,まぁ普通は 困る/意図した動作を達成できない/etc... よね,っていうだけの話.

なので「変数の値を使うよりも前の段階でちゃんと値を入れておきましょうよ」と普通は考える.
その手段が「初期化」とか「代入」.
だから,「俺は 絶対に この変数の値を用いるよりも前の段階で何か値を代入するぜ!」っていうコードを書くのであれば,初期化は必須ではない.

C++

1int x; //初期化しないけども… 2... 3x = 42; //まず何か値を代入してから… 4std::cout << x; //xの値を用いるのならば問題無い

あなたのプログラムの場合だと,最初に変数 xy の値を用いた処理をしているのは

if (x == 0 and y == 0) break;

というところだけど,この時点までにおいて変数 xy を{初期化しておらず,且つ,一度も値の代入もしていない}としたら,この時点での値は上記の「不定」な状態なわけなので,
そしたら「たまたま両者の値が0だったならばこの if の条件を満たしてしまうし,そうでないならば満たさない」という(予測不能な)動作をすることになる.

で,この if よりも前の段階でこれらの変数に値を入れている処理がありますか? っていうと,該当するのは

std::cin >> x >> y;

になるけども,この処理って必ず成功するわけじゃないよね.
例えば Hello とか何とかてきとーな入力が成された場合はどうなるのか?
入力次第では xy への値の代入というは行われないかもしれないよね.

……というわけで,このプログラムに関して言えば,
「入力の失敗はあり得ない/そういうイレギュラーは考えない」という前提としても良いという話なのであれば,初期化は無くても良いということになるだろう.
そうでないならば(:あらゆる入力があり得るという前提であれば)変数 xy には何かしらの 適切な初期値 というのを与えておくとか,あるいは入力処理の失敗を判定して何か手を打つ(:未入力の xy が用いられないようにする)だとか,相応の対応を入れる必要がある.

投稿2024/09/06 00:19

編集2024/09/06 00:22
fana

総合スコア11942

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

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

jerryfish2357

2024/09/06 01:04

詳しい解説をありがとうございます! プログラムを使う側の人がこちらの書いたプログラムが予期していない入力をしても、 毎回戻る場所(初期値)があれば、プログラムの安定な動作につながるというわけで、、、 それでも、今回僕が解いていた問題には、使う側が数字しか入力しないことを前提にされているから、 初期値が必要なかったということですね! 本来、本当に第三者に使ってもらうことを前提にプログラムを書くならば、 もっと複雑な条件式や定義が必要になるのですね、、 内容の理解だけでなく、 プログラムの世界をもっと深く知ることができました! ありがとうございます!
fana

2024/09/06 01:54

まぁ,今回のやつだと cin のところで何かしら入力にしくじった場合, cin に対して何か適切な対処(エラー状態のクリアや入力バッファに残っている入力内容の除去)をしてやらないと「安定な動作」とはならないでしょうけども. (質問コードのままで Hello とか入力すると無限ループになるハズ)
jerryfish2357

2024/09/06 07:05

そうなんですか、! 実際にプログラムを動かすということができる環境はないので(与えられた問題を解いている状態)、 分かりませんでしたが、実際は除去するなどの後処理(?)も行わなければならないんですね、、。 プログラミングは、本当に意識する部分が多いんですね、、。
fana

2024/09/06 07:28

> 実際にプログラムを動かすということができる環境はないので(与えられた問題を解いている状態) なんだその状況… まぁ背景事情はわかりませんが,実際の動きを見てみることができないというのは不便ではないですか? オンラインで動かせるような場所でも使ってみたらどうです?(paiza.io だとか ideone.com だとかみたいな. 探せば他にもいろいろあると思うけど)
guest

0

その変数を参照する前に値を代入してるなら、初期化の必要はないです。
値を代入する前に、その変数を参照する可能性がある場合、初期化は必須です

投稿2024/09/05 10:30

y_waiwai

総合スコア87981

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

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

jerryfish2357

2024/09/05 10:31

変数を参照するとは具体的にどういう状態でしょうか、、、?
guest

0

「初期化」とは曖昧な言葉です。普通には「変数に対しての最初の代入」ですかね。
宣言と同時に値を与えることのみに限定して使う人もいるようです。
int x=10;だけ書くのと、 (あらかじめint x;しておいて)x=10するのと、両方を初期化というか、前者のみを初期化というかの違い。

このコードだと、std::cin >> x >> y;が宣言後の初めての代入なので(=は使ってませんが)、強いて言うと、これが初期化でしょう。私個人はこの場合にそういう言葉は使いませんが。

int x,y;でなくint x=-1, y=99;のように書くのは、その直後にcinで代入するので意味ないかというと、
std::cinに対して、EOF(Unix/LinuxだとCtrl-Dを押す)が来ると、代入は実行されないのでx-1y99のままで、全く意味が無いわけでは無いです。
が、それを積極的に利用するのは良いとは思いません。

int x=0;の直後にx = 10;とか書いてあるようなコードの場合は、「int x=0;0にどんな意味を込めて書いたのか?」と聞いてみたいですが、何も考えてないでしょうね。

初期値の定義が必要な時とそうでないときの違いをご教授いただければ幸いです。

変数から値を取り出すという処理(例えば、std::cout << x;xとか、a = x + y;xyとか)の前には、その変数への値の代入が必要です。代入してない変数から値を取り出すと、言語によって違いますが、エラーになる場合もあるし、そのときたまたま変数の位置のメモリーに入っていた値(0とは限らない)が参照されて、エラーにならない場合もあります。
やるべき事は、「使う前には代入しましょう」というそれだけです。
宣言と同時でも良いし、別でもよい。どちらにするかは開発のルール次第ですかね。
(宣言と同時の場合には「代入」とは呼ばないケースもありますが、意味的には同じです)

投稿2024/09/06 03:14

otn

総合スコア85607

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

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

0

自己解決

反復処理の値なのか、自由な値なのかによって、whileの前に定義するかどうかを決めるんだと気が付きました!
お騒がせいたしました!

投稿2024/09/05 10:30

jerryfish2357

総合スコア2

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

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

thkana

2024/09/06 04:31

> 反復処理の値なのか、自由な値なのか あなたの理解のコトバであって一般的な表現でないので感覚的だけれど、なんか違っているのではないかという気がする... その変数が何かの値であることが期待されることがあるなら、その期待される時までに確実にその値になっているようにする、というそれだけの話なのだけれど。
jerryfish2357

2024/09/06 06:59

感覚的に理解してしまうのが僕の悪い癖です 反復処理の中で、変数が何かの値になってしまう(1、2、など)なら、 それを初期値に戻してあげなければ、変数が(値になってしまったため)見つからなくなり、 動作不良を起こすということでしょうか?!
thkana

2024/09/06 11:13

> 反復処理の中で... 今回の質問に対して、初期化云々と反復処理は本質的には関係ありません。 そして、 > 変数が(値になってしまったため)見つからなくなり というのは「あなたが作り出した(実在しない)ストーリー」に思えます。 「感覚的に理解している」のではなく、無理矢理適切でない(場合によってはあなたが無から生み出した)理由(これを「感覚」と呼んでいる?)と結びつけてわかったつもりになってしまって、実際には理解出来ていない、ということになっていたりしないでしょうか。
jerryfish2357

2024/09/09 07:39

初期化と反復処理は本質上関係ないのですね、! 僕の理解力が足りず申し訳ないです 確かになっているかもしれないです! 一度仮定して分かったつもりにしてから、 別の問題で壁に当たった時に都度自分の理解に修正を加えています
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.39%

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

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

質問する

関連した質問