「夫を成功」へ導く妻の秘訣 座談会

以下のコード1では、”値が割り当てられていないローカルな変数 'key' に対して参照が行われました。”という警告が出ますが、コード2では出ません。

コード2でも値が割り当てられていないと思うのですが、どうして警告が出ないのでしょうか?

お分かりの方、お教えくだい。

あと、かなり省略してしまったので、意味の無いコードになってしまいましたが、この2つのコードでkeyの意味合いはどう違うのでしょうか?

よろしくお願いいたします。

<コード1>
int in_dt()
{
int *key;
scanf( "%d", key );///ここで警告が出る
return 1;
}

int main( void )
{
int code;

code = in_dt( );

return 0;
}

<コード2>
int in_dt( int *key)
{
scanf( "%d", key );
return 1;
}

int main( void )
{
int code,key;

code = in_dt( &key);

return 0;
}

このQ&Aに関連する最新のQ&A

A 回答 (5件)

>結局、コード2は正しいのでしょうか?


>それともおかしいのでしょうか?

正しいです。
ちゃんと
int code,key;
のところで、keyのデータを入れるところが宣言されています。

これがもしコード2で、
>int code;
>int *key;
>code = in_dt( key);
とするとエラーが出ます。理由はコード1と同様です。
(#1の最後は舌足らずでしたね。すみません。)

要するにコード1とコード2の違いは、
int *key;となっているかint key;となっているかでして、
int *key;宣言の直後には、データの本体を記憶するべき場所が(まだ)存在していません。
前記のようにしないと使えないということです。
「値が割り当てられてない」というのはそう言うことを行っています。
    • good
    • 0
この回答へのお礼

回答ありがとう御座います。

大変良く判りました。
これまでの理解は、80%にとどまっており、今回残りの20%が判ったという感じです。

ところで、省略してしまったのでコードの中にはありませんが、code = in_dt( &key);のあとで 変数keyを用いた処理を行います。

この時、コード2は期待通り動きますが、コード1は動きません。
(引数でkeyを渡しているかいないかの差)

自分でも大体判っているつもりですが、何となく漠然としており、少し詳しく教えていただけたらうれしいのですが。

お礼日時:2003/08/29 10:26

お書きになられたことであっていると思いますよ。


関数内で何かしらの処理を行い (今の場合はscanfですね)
それをmainで使えるようにするために引数としてポインタで渡しているのでしょう。

プログラムの書き方は人によって様々で、
何がいいかなんて余り言えませんが、
大体の場合、

int in_dt( void )
{
int key;
scanf( "%d", &key );
return key;
}

int main( void )
{
int key, code = 1;

key = in_dt();
//keyを使った処理
return 0;
}

と書くかな?と思うのですが…(^^;。
だってcodeって関数の戻り値は常に1でしょ?。

最後に
>mainで値が決まっていないkeyをin_dtに渡していることが不自然に感じられました。
繰り返しになりますが、引数で渡しているのはintで宣言した変数のポインタです。
int宣言時にポインタとしてはメモリアドレスを既に持つことになります。
ですから、keeは確かに値が決まっていませんが、
*keyの値は既に決まっています。
説明…余りうまくないかもしれませんが、
VitaminBBさんの書かれた内容であっているということです
    • good
    • 0
この回答へのお礼

回答ありがとう御座います。

これですっきりしました。

正しいことをどうして正しいのですか?といった類の質問でしたのでちょっと質問に困りました。

いろいろ質問している最中に段々判ってきました。

>だってcodeって関数の戻り値は常に1でしょ?。
文法的に正しいコードとして例に挙げました。
プログラム的には意味が有りませんが。。。(^^;。

お礼日時:2003/08/29 13:32

?#2の回答に書かれたご質問の意味がよくわからない…(^^;。


コード1で処理できないとは、
main関数の中で処理できないということでしょうか?
それはそうですよね。
コード1でのkeyは int in_dt()のローカル変数なので…。
それより、コード1を実行してscanf関数の実行時によく
例外処理が発生しませんでしたね?(^^;。
(逆に発生しないほうが怖い…)
先ほども回答しましたように
コード1のポインタ変数の値は不定です。
つまり何処のアドレスを指しているか解らない。
ですから、keyは???な状態ですから、これを処理することは出来ません。
若しかしたらうまく実行されるかもしれませんが、
それは本当に偶々のことです。
引越し屋さんを呼んで引越し作業をさせているが、
何処に引っ越すのか住所を言っていないようなものです。
荷物は何処に行くのか解りませんよね?(^^;。

蛇足ですが、
値渡しと参照渡しというのはご存知ですよね?。

よく使われる例文に
void swap( int a, int b ){
int c;
c = a;
a = b;
b = c;
}

int mai( void ){
int a = 1, b = 2;
swap(a, b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
というのがあって、swap関数のなかでa,bの値を変えようというものです。
が…swapの中ではa,bの値は変わりますが、mainの中では変わってはいません。
main君が上司、swap君が部下としましょう。
main君はswap君をいまいち信用していません(^^;。
変数a, bの入れ替えを命じますが、いちいちコピーを取ってそのコピーをswap君に渡します。
上司が部下に書類を渡すのに全て書類のコピーをとり、
そのコピーを部下に渡すものです。
部下はその書類に一生懸命書き込んで上司に報告しても
所詮コピーなので、上司の書類を書き換えたりすることなんて出来ません。
引数を渡されてもmainの変数を書き換えることなんて出来ないのです。

が、上司からコピーじゃなくて書類のある「場所」を教えてもらったらどうでしょう?。
部下は場所がわかるので、自分で書類を取ってきてその書類を書き換えることが出来ます。
これがポインタで渡すということです。
つまり
void swap( int* a, int* b ){
int c;
c = *a;
*a = *b;
*b = c;
}

int main( void ){
int a = 1, b = 2;
swap(&a, &b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
とすればmainでも値が変わっているぞ…と…。
てか、質問からかなり外れた答えだったでしょうか?。

この回答への補足

改めて端的に書くと、

コード2において

何も代入されていない変数keyをわざわざ引数で渡しているのはどうしてか?

ということです。

補足日時:2003/08/29 12:52
    • good
    • 0
この回答へのお礼

質問者の私のほうが質問の手を抜いて、回答者の方に気を使わせてしまい申し訳ありません。

回答頂いた内容は基本的には理解できています。
漠然として、何か引っかかることが有ったのですが、何を聞けばよいか
ようやく明確になりました。

教えて頂いたコード3のようにmainの中で、a = 1として値が代入された後に、swapに渡している構文は私にとって自然なのですが、

コード2はmainで値が決まっていないkeyをin_dtに渡していることが不自然に感じられました。
(今はコードを見慣れてきたため、不自然に感じられなくなってきましたが)

結局、mainでkeyを使った処理をするためには、keyをグローバル変数的に使うために(ちょっと表現が変?)、
引数として渡す必要がある。という理解をしています。

私の理解がおかしくないか、あるいは何かアドバイスや考え方の訂正等あればご意見をお願いいたします。

<コード2>
int in_dt( int *key)
{
scanf( "%d", key );
return 1;
}

int main( void )
{
int code,key;

code = in_dt( &key);
//keyを使った処理
return 0;
}
<コード3>
void swap( int* a, int* b ){
int c;
c = *a;
*a = *b;
*b = c;
}

int main( void ){
int a = 1, b = 2;
swap(&a, &b);
printf("a = %d, b = %d\n", a, b);
return 0;
}

お礼日時:2003/08/29 12:41

ポインタ変数はアドレスを値としてもつ関数ですよね。


コード1の場合、int型のポインタ変数を宣言していますが、
その値としてアドレスを代入していません。
これが関数内でも
int key;
scanf("%d", &key);
としたなら警告は出ないはずです。

コード2はint型の変数を宣言して、
関数にポインタとして渡していますね。
int型の変数を宣言した時に、
既にこのアドレスは決まっています。
(メモリ上のどこかにint型変数が作られるのですから、
当然ですよね。)
コード2でも
int* key;
を宣言して、関数にポインタとして渡した場合は
警告が出るはずですよ。

要はポインタ変数を宣言しただけでは何処のアドレスを指しているかわからず不定の値となる。int型の変数などを宣言してポインタとして使っても、
その変数のアドレスがわかっているので不定とならない ということです。
コード1のように引数をvoidとしたいなら

int in_dt( void )
{
int key;
scanf( "%d", &key );
return 1;
}

と書きましょう。
…scanf関数自体…お勧めできませんが…(^^;。
    • good
    • 0
この回答へのお礼

回答ありがとう御座います。

大変良く判りました。

#2のほうに追加質問をしました。
出来ればアドバイスお願いします。
(ちょっと判り辛い質問になってしまいましたが。。。)

お礼日時:2003/08/29 10:29

ポインタは、「住所が書かれたメモ用紙」です。


住所そのものではありません。
最初に*keyと宣言したところでは、住所用のメモ用紙が作られただけです。どんな値が入っているかわかりません。

もしかすると、他の重要なデータのある住所(アドレス)が、
たまたま入っているかもしれません。
そうなったら大変で、データを壊してしまいます。
他人の住んでいる家に、勝手に土足で踏み込むようなものです。

先にデータを入れる場所を宣言し、
int *key;
int key_data;
key = &key_data;
のようにしなければいけません。

関数の引数で*keyとしている場合には、それ以前の状況を調べることができないので、警告が出ません。
    • good
    • 0
この回答へのお礼

>関数の引数で*keyとしている場合には、それ以前の状況を調べることができないので、警告が出ません。

コード2で警告が出ない理由はわかりました。


>先にデータを入れる場所を宣言し、
>int *key;
>int key_data;
>key = &key_data;
>のようにしなければいけません。

結局、コード2は正しいのでしょうか?
それともおかしいのでしょうか?

お教えください。お願いします。

お礼日時:2003/08/29 09:10

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC#にて別クラスの関数を使いたい

C#にて、別クラスの関数を使用する方法を教えてほしいです。

下記のような、構造体を受け取るメソッドを作りました。

*****************************
private struct MyPoint
{
public int x;
public int y;
}

private void proc1(MyPoint pt)
{
MessageBox.Show("座標:" ; pt.x + "," + pt.y + "実行結果");
}

private void button1_Click(object sender ,System.EventArgs e)
{

MyPoint pt;
pt.x = 10;
pt.y = 20;
proc(pt);
}
*****************************

別のフォームのクラスから、proc1を呼び出したいのですが、やり方がわかりません。
どうか、教えてください。

Aベストアンサー

同じ定義をしたとしても別の名前空間に書いた構造体は同一とはみなされません。

呼び出し先クラスでの構造体を private では無く、public で宣言して下さい。

呼び出し元では、

MyClass.MyPoint pt;

のようにして実体を作ります。

QC#「オブジェクト参照が必要です」(初心者)

Visual C# 2008を学習中なんですが、とりあえず何か作ってみようと思って、パラパラマンガに挑戦してみました。
Form1にpictureBox1を作り、waitを入れてイメージを書き換えるという単純なものです。
ところが実行しようと思ったら、「静的でないフィールド、メソッド、またはプロパティ’WindowsFormApplication1.Form1.pictureBox1’でオブジェクト参照が必要です」というエラーが出ます。その際のフォーカスは、main()内の
Form1.pictureBox1.image = Image.FromFile("motion1.png");
”Form1.pictureBox1”に当てられています。

何が原因と考えられるでしょうか。
もし情報不足であればご指摘いただくか、あるいはこの目的においてやらなければいけないこと、を大雑把に教えていただくだけでも幸いです。
よろしくお願いします。

Aベストアンサー

main()内に記述されているとのことですので、たぶん、
Form1.pictureBox1.Image=Image.FromFile("motion1.png");
Application.Run(new Form1());
と書いているのではないでしょうか?

連載 改訂版 C#入門 第3章 クラスとインスタンス
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_003/cs2_003_01.html#cs0302

ここであるように、オブジェクト指向にはクラスとインスタンスという概念があります。
今のコードでは、Form1クラスを操作しようとしているのでそのようなエラーが出ます。

具体的な解決方法としては、PictureBoxに初期画像を設定する処理をForm1のコンストラクタでやるのがいいと思います。
その際、redfox63さんがおっしゃられるように
this.pictureBox1
と記述することが必要です。(thisは自分自身のインスタンスを指します)

後は、Windowsフォームで一定間隔での処理をするための「Timerコンポーネント」について調べてみたらいいと思います。

タイマにより一定時間間隔で処理を行うには?(Windowsタイマ編)
http://www.atmarkit.co.jp/fdotnet/dotnettips/372formstimer/formstimer.html

MSDNライブラリ Timerクラス
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.timer.aspx

参考URL:http://www.atmarkit.co.jp/fdotnet/csharp_abc2/index/

main()内に記述されているとのことですので、たぶん、
Form1.pictureBox1.Image=Image.FromFile("motion1.png");
Application.Run(new Form1());
と書いているのではないでしょうか?

連載 改訂版 C#入門 第3章 クラスとインスタンス
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_003/cs2_003_01.html#cs0302

ここであるように、オブジェクト指向にはクラスとインスタンスという概念があります。
今のコードでは、Form1クラスを操作しようとしているのでそのようなエラーが出ます。

具...続きを読む

Q戻り値の意味がわかりません…

戻り値とはどういう値なのか簡単な例文で教えて頂けますか?

Aベストアンサー

バカくさいかもしれませんが簡単な例えをだしてみます。
2人の子供がいて、名前をそれぞれ太郎・花子にしましょう。この2人の子にある役割を決めます。
・花子は飴をもらうと、それをチョコにする役割。(できるかは別として)
・太郎は花子を呼んで飴をあげる役割。

さてこの例では太郎の飴が引数(ひきすう)になり
花子のチョコが戻り値になります。

このイメージを元に次の文を読んでみてください。

「プログラム中の関数やサブルーチンが処理を終了し
呼び出し元に処理の結果として返す値。」

これが戻り値の正しい定義です。
そのほかにはNo1さんのような役割指すときも、それを「戻り値」と呼んだりします。

Q#if 1 #elseの意味について

#if 1
 文 
#else 
 文
#endif
という表記に関して、「#if 1」が「必ず有効」という事はわかるのですが、ここでの「#else」とは「1」でない時ということで、「#if 0」と同じ意味と考えていいのでしょうか?

Aベストアンサー

>「#if 0」と同じ意味
「#if~#endif」がすこーぷの範囲ですから、似ていますが、正確には違います。

「#if 1」であれば、「#if 1~#else」の間の処理が有効、「#else~#endif」が無効、
「#if 0」であれば、「#else~#endif」の間の処理が有効、「#if 0~#else」が無効
と排他になります。

QC# 配列の変数宣言について。

C#についての質問です。

新たなint型の配列dataを作るため変数宣言文を、以下のように書きました。

int[] data;

すると、以下のような警告文が出ました。
『フィールド'IntArray.data'は割り当てられません。常に既定値nullを使用します。』
そこで調べてみたところ、「newしていないからこのような警告文が出る」ということがわかったので、以下のように書き換えました。

private int[] data = new int[];

すると今度は
『配列を作成するには、配列のサイズまたは配列の初期化子を指定する必要があります。』
というエラー文が出てしまいました。
このとき、配列のサイズも初期化子も指定したくない場合には、どのようにプログラムを書けば良いのでしょうか?

お分かりになる方がいらっしゃいましたら、ご助言をお願いします。

Aベストアンサー

private int[] data = null;
としてやれば警告は消えますよ

実際に使う段になって
data = new int[5];
などとインスタンス(実体)化してやりましょう
# new側の引数は 変数でもかまいません

Q日付型のフィールドに空白を入れる方法を教えてください

ASP(VBScript)でSQLサーバにINSET INTO文を使ってデータを格納しているのですが、日付の部分がNULLの時、「1900/1/1」が入ってしまいます。
そのまま、空白を入れる方法はどうやったらよろしいのでしょうか?

TABLE1の内容は
番号|内容|日付です。

INSERT INTO TABLE1 VALUES ( 1, 'あいう', '')

結果
1|あいう|1900/1/1

Aベストアンサー

あとは、プログラムの書き方次第ですね、、、


If hensu=Null Or hensu="" Then
dt = "NULL"
Else
dt = "'" & hensu & "'"
End IF

E_SQL = "INSERT INTO TABLE1 VALUES & _
"( 1,'あいう', " & dt& ")"
の様に書きます。

Q関数とメソッドの違い

初歩的な質問なのですが、
関数とメソッドの違いが分からず悩んでいます。
書籍や人によって、
関数とメソッドは同じ物として書いている物もあれば、
メソッドはクラスに関連付いた関数としていたり、
クラスでもpublic関数だけとか、
引数のある物がメソッド、
逆に無い物がメソッド等々…で、
どれが正しいのか良く分からないのです。

関数とメソッドの違いを教えていただけますよう、
お願いいたします。

Aベストアンサー

正解だけ先に言っておきましょう。オブジェクト指向での定義は
「メソッドとは、オブジェクトに送られてきたメッセージを処理するモノ」
「関数とは、メソッドの実装」
ついでに、
「メッセージとは、オブジェクトに何かしらお願いするために送られるモノ」
です。メッセージとメソッドと関数は明確に違うのですよ。


上記の通りなんですが、質問の文について、なにが正しいか、という解答は「文脈による」としか言いよ
うが無いんです。
解説書の一部分だけ抜き出して考えるのは非常に危険な行為です。
文脈を色々変えてみます。例えばオブジェクト指向の話をしているとしたら、

>1. 関数とメソッドは同じ物として書いている物もあれば、
バツ。意味的に全く異なります。
'\0'と""とNULLと0くらい違います。等価なんていってしまったら石が飛びます。(私が投げます:-p)

> 2.メソッドはクラスに関連付いた関数としていたり、
サンカク。C++での実装はそうでしょうが、オブジェクト指向を考える上で、その考え方は危険です。

> 3.クラスでもpublic関数だけとか、
> 引数のある物がメソッド、
> 逆に無い物がメソッド等々…で、
バツ。引数の数でメソッドで無くなる?そんなバカな!
例えprivateでもメソッドですよ。


オブジェクト指向言語C++のことを考えよう!という文脈ならば、
1.サンカク。実装は確かにそうなってます。ですが、上記の通り意味的に違うんです。
2.○。C++において、メソッドは「クラスに関連ついた関数」として実装されてます。
3.そんなわけないでしょう。

オブジェクト指向?なにそれ?構造体に関数がくっついただけでしょ?と乱暴極まりない文脈なら、
1.○。当然!
2.なにいってるの?
3.サブルーチンとファンクションの違いだ!


と、文脈で全然変わるんですよ。これに関しては、本一冊だけだとなかなか気付きにくいです。
是非とも多数の本を読み比べることをお勧めします。

正解だけ先に言っておきましょう。オブジェクト指向での定義は
「メソッドとは、オブジェクトに送られてきたメッセージを処理するモノ」
「関数とは、メソッドの実装」
ついでに、
「メッセージとは、オブジェクトに何かしらお願いするために送られるモノ」
です。メッセージとメソッドと関数は明確に違うのですよ。


上記の通りなんですが、質問の文について、なにが正しいか、という解答は「文脈による」としか言いよ
うが無いんです。
解説書の一部分だけ抜き出して考えるのは非常に危険な行為です...続きを読む

QC#で構造体の配列を持った構造体を使いたいのですが

C#で構造体の配列を持った構造体を使いたいのですが
Cならば
struct xyz {
struct abc _abc[32];
int index;
};
struct abc {
int a;
int b;
int c;
};

struct xyz _xyz[8];
xyz[0]._abc[3].b = 1;

のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません
うまくやる方法をどなたかご存知ないでしょうか

Visual Studio 2005行った場合
コンパイルで
構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するには、次元指定子を変数の識別子の前に指定します。固定サイズ バッファ フィールドを宣言するには、フィールド型の前に fixed キーワードを使用します
となり

fixed をつけると

固定サイズ バッファの型は次のうちの 1 つでなければなりません: bool、byte、short、int、long、char、sbyte、ushort、uint、ulong、float または double

となってしまいます

C#で構造体の配列を持った構造体を使いたいのですが
Cならば
struct xyz {
struct abc _abc[32];
int index;
};
struct abc {
int a;
int b;
int c;
};

struct xyz _xyz[8];
xyz[0]._abc[3].b = 1;

のような使い方で という感じで やっていた事を C#で 同じような事をやろうとしても うまくいきません
うまくやる方法をどなたかご存知ないでしょうか

Visual Studio 2005行った場合
コンパイルで
構文エラーです。不適切な配列の宣言子です。マネージ配列を宣言するに...続きを読む

Aベストアンサー

C# では、配列は「単なる連続したメモリ領域」ではなくて「添字によってオブジェクトを格納できるオブジェクト」であることに注意しなくてはいけません。つまり、C では配列は一種の構造体でしたが、C# では配列は参照型のオブジェクトです。
よって、C のように予めサイズを固定しておくということは基本的にできません。配列の大きさは配列のインスタンスが作られるときに動的に決まります。

C# では、参照型のオブジェクトを構造体のメンバにすることはあまりありません。null 値の扱いが面倒だからです。
また、C# では構造体の大きさは大きくとも 20 バイト程度までにします。C# では基本的に「構造体へのポインタ」はありません。巨大な構造体をそのまま扱うのはメモリの使い方の観点からいって非効率的です。

今回の件では、構造体ではなくクラスにするのがよいかと思われます。

Qポインタへの値の代入時の警告の原因

私は現在、事務職をやっており、プログラミングとは全く別の畑に居ます。
真剣に転職を考えておりC言語を独学にて勉強中なのですが、ポインタの勉強中、どうしても理解できない点がありましたので質問いたしました。

ポインタを理解するために下記1~3のような処理をさせました。
1.文字変数s に 'a' を代入
2.ポインタp を宣言し、変数s のアドレスを代入
3.最終的にpの値を確認する。

#include<stdio.h>

int main (void)
{
char  s;
char  *p;

s = ' a ';
p = & s;        //←ここが9行目です

printf (" pは %c です\n " , *p);

return 0;
}

すると、

『 pは a です 』

と、期待通りの表示がされました。

次に、9行目を
*p = s
と書き換えた所、コンパイル時に
『値が割り当てられていないローカルな変数’p’に対して参照が行われました』
と言う警告が表示されました。
実行してみた所、
『pは a です』
と、結果は期待通りのものが表示されたのですが、この警告がなぜ表示されたのかが分かりません。
参考書を読んでも、このような(*p = sのような)書き方は載ってましたし、私自身、『「ポインタ変数pの値*p」に「変数sの値」を代入した。』と認識している為、間違いでは無いと考えております。
この警告がなされた原因について、どなたかご存知でしたら、宜しくお願いいたします。

私は現在、事務職をやっており、プログラミングとは全く別の畑に居ます。
真剣に転職を考えておりC言語を独学にて勉強中なのですが、ポインタの勉強中、どうしても理解できない点がありましたので質問いたしました。

ポインタを理解するために下記1~3のような処理をさせました。
1.文字変数s に 'a' を代入
2.ポインタp を宣言し、変数s のアドレスを代入
3.最終的にpの値を確認する。

#include<stdio.h>

int main (void)
{
char  s;
char  *p;

s = ' a ';
p = & s;   ...続きを読む

Aベストアンサー

char *p;
と宣言しただけでは どこのメモリーも参照していません
# 実行時にポインタpに割り当てられたメモリの内容に依存します

ポインタ変数は必ず 初期化作業が必要です

p = &a;
とすることで ポインタpが 変数aを指すポインタとして機能します

どこを指しているかわからないポインタに対して その中身を書き換えると 思わぬところを書き換えてしまいます
下手をすると OSを壊してしまったりしますので注意が必要です

また Cでは ポインタとポインタの示す先を関連付けて管理しませんので以下のようなソースはコンパイルできるものの 実行時におかしな動作をする場合があります

char buf[256];
char *p = buf;
*(p+257) = 'a';

pが指している bufは256しか確保していないので p+257はbufで確保した領域を超えています
別の変数など領域を書き換えてしまうことになります

Q最大値と最小値を表示したいのですが・・・

double numに入っている数字から最大値と最小値を求めたいのですが、このままだと両方とも1.000になってしまうんです・・・
どうやったらちゃんと最大値と最小値が表示されるのでしょうか??
初心者なものでスイマセンが教えてください!!


#include<stdio.h>

int main(void)
{
int i,j;
double num[]={4.5,3.1,7.0,9.2,1.0,5.7,9.3,2.3,0.3,1.0};
double max,min;

for(i=0; i<10; i++)
{
for(j=0; j<10; j++)
{
if(num[i]>num[j])
max=num[i];
}
}

for(i=0; i<10; i++)
{
for(j=0; j<10; j++)
{
if(num[i]<num[j])
min=num[i];
}
}
printf("最大値は%fです。",max);
printf("最小値は%fです。",min);

return 0;
}

double numに入っている数字から最大値と最小値を求めたいのですが、このままだと両方とも1.000になってしまうんです・・・
どうやったらちゃんと最大値と最小値が表示されるのでしょうか??
初心者なものでスイマセンが教えてください!!


#include<stdio.h>

int main(void)
{
int i,j;
double num[]={4.5,3.1,7.0,9.2,1.0,5.7,9.3,2.3,0.3,1.0};
double max,min;

for(i=0; i<10; i++)
{
for(j=0; j<10; j++)
{
if(num[i]>num[j])
max=num[i];
}
}

for(i=0; i<10;...続きを読む

Aベストアンサー

なぜforループが2重になっているのかよくわかりませんが、
考え方として、
・とりあえず配列の最初の値を暫定の最大値としてセットする
・forループで配列を調べていき、配列の値が暫定の最大値より大きな場合、それを暫定の最大値とする。
・forループを抜けると、暫定の最大値は暫定ではなく、その配列の最大値となっている。
という流れが普通のやり方です。

以上を踏まえてコーディングを手直しすると、以下のようになります。

#include<stdio.h>

int main(void)
{
int i;
double num[]={4.5,3.1,7.0,9.2,1.0,5.7,9.3,2.3,0.3,1.0};
double max,min;

max=num[0];
for(i=0; i<10; i++)
{
if(num[i]>max)
max=num[i];
}

min=num[0]
for(i=0; i<10; i++)
{
if(num[i]<min)
min=num[i];
}

printf("最大値は%fです。",max);
printf("最小値は%fです。",min);

return 0;
}

なぜforループが2重になっているのかよくわかりませんが、
考え方として、
・とりあえず配列の最初の値を暫定の最大値としてセットする
・forループで配列を調べていき、配列の値が暫定の最大値より大きな場合、それを暫定の最大値とする。
・forループを抜けると、暫定の最大値は暫定ではなく、その配列の最大値となっている。
という流れが普通のやり方です。

以上を踏まえてコーディングを手直しすると、以下のようになります。

#include<stdio.h>

int main(void)
{
int i;
double num[]={4....続きを読む


人気Q&Aランキング