ポインタと関数を用いたプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ゆり

ポインタと関数を用いたプログラム

#1

投稿記事 by ゆり » 15年前

提出期限が迫っていて困っています!
自分ではいまいち関数からわからないのでそこから自分で勉強しているのですが、課題に今勉強している範囲外のことが出たので質問させてください。


9匹の魚を釣りました。もし1匹でも20cmの魚であれば、それを30cm以上の魚と交換してもらえるとすると最終的な魚の大きさの平均はいくつか。ただし20以下であれば30に値を変更する関数を作ること。平均値はmain文内で算出すること。


よろしくお願いします。

たかぎ

Re:ポインタと関数を用いたプログラム

#2

投稿記事 by たかぎ » 15年前

言語不明なのでどうすることもできません。

> 平均値はmain文内で算出すること。

ということは、CやC++ではありませんね。
言語は何でしょう?

ゆり

Re:ポインタと関数を用いたプログラム

#3

投稿記事 by ゆり » 15年前

>たかぎさん

C言語なのですが…。関数として30センチ以上に交換したあと、その後main文を使って平均を算出するということだと思うのですが。。。
習った模範プログラムがあるので一応載せます。

#include <stdio.h>

void swap(int *x, int *y)
{
int temp =*x;
*x = *y;
*y = temp;
}

int main(void)
{
int a, b;

printf("aの値:\n"); scanf("%d", &a);
printf("bの値:\n"); scanf("%d", &b);

swap(&a, &b);

printf("aの値:%dです。\n", a);
printf("bの値:%dです。\n", b);

return(0);
}

これの
int main(void)
{
int a, b;

printf("aの値:\n"); scanf("%d", &a);
printf("bの値:\n"); scanf("%d", &b);

swap(&a, &b);

printf("aの値:%dです。\n", a);
printf("bの値:%dです。\n", b);

return(0);
}

の部分で平均値を計算するということかと思います。
C言語しか習ってないので、C言語だと思います。

たかぎ

Re:ポインタと関数を用いたプログラム

#4

投稿記事 by たかぎ » 15年前

> C言語なのですが…。

C言語には「main文」なるものは存在しません。
あと...

> 9匹の魚を釣りました。もし1匹でも20cmの魚であれば、それを30cm以上の魚と交換してもらえるとすると最終的な魚の大きさの平均はいくつか。ただし20以下であれば30に値を変更する関数を作ること。平均値はmain文内で算出すること。

どこからどこまでをプログラミングするのでしょうか?
そもそもプログラミングだけで済むのでしょうか?
処理系もハード構成もわかりませんので、何とも答えようがありません。

例えば、魚の大きさを計測する必要があるなら、計測器の制御プログラムを書く必要があります。
あるいは、釣った魚の大きさはユーザーに入力させるのでしょうか?
魚の大きさは、どの程度の有効桁数にすればよいのでしょうか?

規約を守って、正確な情報を提示してください。

ゆり

Re:ポインタと関数を用いたプログラム

#5

投稿記事 by ゆり » 15年前

すいません、情報を書き足します。

魚の大きさは、ユーザーに入力させます。

大学の講義の一環なのでそんなに大がかりなものではないと思います。
講義ではC言語の基礎の基礎から(printfのところから)勉強しています。
その中の「ポインタ」の単元で出された課題が上記です。

実行結果の例としては


1匹目の大きさ 10
2匹目の大きさ 20
3匹目の大きさ 30
4匹目の大きさ 40
5匹目の大きさ 50

魚の大きさの平均:36.0000


だそうです。main文云々を抜きにしたらプログラムは組めますでしょうか?

上記は問題文そのまま載せたのですが解釈としては


30以下の数字が入力されたときそれを無条件で30とし、30以上ならそのまま採用する。そしてその値の平均を求める。


というものだと思います。

有効桁数はせいぜい3ケタ位でいいです。
5匹分の大きさを入力させるようにしたいです。


言葉足らずですいません。お願いします。

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#6

投稿記事 by Dixq (管理人) » 15年前

まぁまぁ、習ったばかりでは、そこまでの事はなかなか解りませんよ;
正確な情報を伝える事は大事ですが、もうちょっと柔軟に対応してあげましょうよ^^;

>ゆりさん

こんにちは。大学の宿題ですね。
期限が迫っているということで、では頑張りましょう。

たかぎさんがmain文は無いからC言語じゃないと仰っているのは、
C言語では、main(){}の部分の事を「メイン関数」と呼ぶのであってmain文ではないからです。
まぁ一文字間違う位最初はいくらでもありますのでお気になさらず^^;
多分if文やfor文と混合されてるのだと思います。

さて、模範プログラムは提示して頂きましたが、ご自分で付け足されたプログラムはありますか?
後、コードを投稿する時はタグを使ってくださいね。
詳しくは規約をご覧ください。

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#7

投稿記事 by Dixq (管理人) » 15年前

こういうのは段階を踏んで課題をクリアしていくのが一番だと思います。
こういう問題があったらどこまでこたえられますか?

問題1
整数を入力するごとに、入力した数値を画面に表示するプログラムを書きましょう

問題2
(問題1に付け足して)20以上が入力されたら「20以上です」と表示するプログラムを書きましょう

問題3
(問題2に付け足して)20以上が入力されたら30を代入するプログラムを書きましょう

問題4
(問題3に付け足して)入力する回数を10回とし、その10回の入力数値を全てたした結果を表示するプログラムを書きましょう
(20以上は30のはそのまま)

問題5
今回の課題そのもの(ただし関数化しなくてよいものとする)

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#8

投稿記事 by Dixq (管理人) » 15年前

ポインタ関連は難しいですよね。
時間も無いようですし、解り難いと思いますのでここは先にサンプルをお見せしましょう。
まず、関数に値を渡すと、関数先でどう変更しようが、呼び出し元には関係ないということはOKですか?

例えばmain関数がA君、swap関数がB君だとしましょう。
B君が「君の書類が欲しいから見せてほしい」と言ったとしましょう。
A君は自分の書類が大切なので、B君にはコピーを取って、コピーを渡しました。
そうすれば安心ですよね。B君がそのコピーを燃やそうが捨てようが、原本には全く影響ありません。

そう、関数に渡した先はコピー先なのです。
ということで、こいつを見てみましょう。

#include <stdio.h>

void swap( int a ){
    a = 30;
}

int main(){
    int a=20;
    swap(a);
    printf("a=%d",a);
}

実行結果が何になるかは、考えた上で自分で実行してみてください。

で、答えを言わないと次に進まないので、答えを言ってしまうのですが、20です。
関数先にaの値を渡していますが、関数先に渡したのはコピーなので、関数先で何しようが元の値は変わらないのです。

その一方で・・・


次に続く

たかぎ

Re:ポインタと関数を用いたプログラム

#9

投稿記事 by たかぎ » 15年前

> まぁまぁ、習ったばかりでは、そこまでの事はなかなか解りませんよ;
> 正確な情報を伝える事は大事ですが、もうちょっと柔軟に対応してあげましょうよ^^;

まあ、お約束の展開ですね。
最初の質問では、習ったばかりかどうかも書かれていませんからね。

> たかぎさんがmain文は無いからC言語じゃないと仰っているのは、
> C言語では、main(){}の部分の事を「メイン関数」と呼ぶのであってmain文ではないからです。
> まぁ一文字間違う位最初はいくらでもありますのでお気になさらず^^;

これは、ゆりさんを責めているのではなくて、出題者を責めているのです。
出題者がC言語を理解できていないと、不必要な苦労をいろいろさせられます。まあ、それも社会勉強みたいなもんですが。

それはそれとして、よくわからないのですが...

> 5匹分の大きさを入力させるようにしたいです。

9匹釣ったんですよね?
あとの4匹はどうなったのでしょうか?
また、その5匹の選び方は?

> 有効桁数はせいぜい3ケタ位でいいです。

とのことですが、

> 魚の大きさの平均:36.0000

では有効桁が6桁になっています。どちらが正しいのでしょうか?
また、入出力は全角数字を用いるということでよろしいでしょうか?

ゆり

Re:ポインタと関数を用いたプログラム

#10

投稿記事 by ゆり » 15年前

ありがとうございます
その例なら問題5まで一応かけそうです
(if文とかfor文を使えばいいですよね?)
私がわからなくなったのは関数、ポインタといったあたりなので
なんの規制もなければ上記の問題も解けると思います

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#11

投稿記事 by Dixq (管理人) » 15年前

その一方で・・・

いや、B君は実はA君の上司であり、書類をチェックしたら上司(B君)のハンコが必要だったのです。
だからコピーを渡したんじゃだめ、原本にハンコを押してもらわなければなりません。

そんな時どうしましょう?
A君とB君は恥ずかしがり屋なので、直接会って渡すことが出来ません。
なので、A君はB君にその書類を「○○番の棚においておくので持って行って下さい。」
ということにしました。

○○番の棚(いわば住所ね)にある原本を持って行ったB君がハンコを押すとどうなるかというと・・
#include <stdio.h>

void swap( int *a ){
    *a = 30;
}

int main(){
    int a=20;
    swap(&a);
    printf("a=%d",a);
}

また、実行してみてください。

30と表示されるはずです。
関数先で値を変えたのに、なぜ変わったか?
それはコピーを渡したのではなく、その書類がある住所を渡したからです。
そのデータがある住所を渡し、その住所先のデータを変更したので、元のデータが変わったのです。

コンピュータというのは、値だけを、何の情報も無く保持することはできません。
データには全て番地がふってあるのです。

1234番のデータは○○
1235番のデータは○○

という感じで。
今、

int a;

とaというデータの入れ物を作ると

1236番のデータはa

こんな感じで用意されます。
ここで、関数先にaとは直接言わず

1236番のデータ

と伝えるのです。すると、aとは言っていなくても、さしているデータは何かわかりますね?

1236番が示すデータを変えればaに入っているデータも変わるということです。

変数に「&」を付けると、「住所」になるという事は習いましたよね?
つまり、関数先には「aの住所」を渡しているのです。

そして受け取っている方は

int *a;

となっていると思いますが、この変数の前にあるアスタリスク「*」は
「住所を入れるいれものですよ」という意味を指しています。
ですから、住所が送られてくるので、「住所の入れ物用変数」で格納しているのです。

住所の入れ物用変数に入れたものは、*を付けることで、その住所がさしているデータを参照することが出来るようになします。
つまり
void swap( int *a ){

で受け取った時、「a」には「住所」が入っているのです。
そして、「*a」には「住所先が示すデータ」が入っています。
という事は、

*a = 30;

と書くことで、aに入っている住所先のデータに30を入れる事が出来るのです。
住所先のデータを変更したので、メインに戻っても値は変わったままになります。

}


さて、ここまで読めばだいぶん解ってきたのではないでしょうか?
問題6が出来たらあとは自力で課題が完成させられると思います。
できそうでしょうか?

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#12

投稿記事 by Dixq (管理人) » 15年前

問題6をどこにも書いていなかったorz


ちなみに問題6は

メイン関数内で、int型変数を宣言し、適当に何か代入します。
その変数のアドレスを関数に渡し、渡した関数先で30を代入するプログラムを作りましょう

という問題だったのですが、もろ答えが話の中で出てきたのは内緒です。

これだけ出来たら出来そうじゃないですかね?

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#13

投稿記事 by Dixq (管理人) » 15年前

> たかぎさん
> これは、ゆりさんを責めているのではなくて、出題者を責めているのです。

なるほど、失礼しました。
もし先生がこう言っているのだとすると、それは問題ですね。
最初であるからこそ、基礎をきっちりやらないと、後で困りますよね。

私は今になって色んな環境でプログラムを組むようになったので、
「windowsで動けばいい」的な投げやり方法は通用しなくなり、苦労しています^^;


後、仰るように問題にはまだ少し補足が必要そうですね。
これだけでは答えられないことが多そうです。

ゆり

Re:ポインタと関数を用いたプログラム

#14

投稿記事 by ゆり » 15年前

>たかぎさん

9匹っていうのは私のタイプミスでした
あと全角で表示ではなく半角で大丈夫です
私の授業でもらったプリントには36.000000と書いてあるのですが、
別にdouble型であれば問題ないようです

出題者は教授なんですけど
こちらも意図を正確に伝えられなかったので…すいませんでした。

講義中の教授「~だから、main文では~」
が日常茶飯事なので間違って覚えてたみたいですね

non

Re:ポインタと関数を用いたプログラム

#15

投稿記事 by non » 15年前

たびたびこのような質問があるのですが、本当に大学の先生は、教えてもいない課題を
出したり、こんな訳のわからない曖昧な問題を出すのでしょうか?
信じられない・・・・

最初の問題はどう解いていいのかさっぱり私もわかりません。

>1匹でも20cmの魚であれば
ちょうど20cmの魚ですよね。
>30cm以上の魚と交換してもらえる
30cm以上何cmあるかわからない魚と交換する。全部の魚を交換するのかなぁ?
>魚の大きさの平均
それは、無理でしょ。

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#16

投稿記事 by Dixq (管理人) » 15年前

え、ホントに教授がそう言ってるんですか?
いや~質問者さんが打ち間違えただけだと思ってましたが、
それはたかぎさんのお叱りが飛ぶのもごもっともw

それはちとひどいですね。
次授業中に言ったら突然挙手して指摘してあげてください!w

> nonさん

多分「教えたつもりになっている教授」と「教えてもらった覚えはない学生」との行き違いではないでしょうかね・・。
私もそうでした。
ポインタ関連、授業の最後にサラッと説明して課題が出ましたが、意味不明でした。
今回の場合はわかりませんが、
確かにほとんど教えていないも同然のような授業でいきなり課題が出る事はよくありました。
まぁ「きっかけを教えてもらったなら後は自分で調べなさい」ということになるでしょうけど。

特にプログラム関連はよく出来た授業であったとしても、授業聞いていただけではなかなか解らないものですからね・・。

ゆり

Re:ポインタと関数を用いたプログラム

#17

投稿記事 by ゆり » 15年前

> >1匹でも20cmの魚であれば
> ちょうど20cmの魚ですよね。

たびたびタイプミスですごめんなさい;
1匹でも20cm以下であれば、です

> >30cm以上の魚と交換してもらえる
> 30cm以上何cmあるかわからない魚と交換する。全部の魚を交換するのかなぁ?

これも
30cmの魚と交換~
でした;

値はscanfとかで直接代入して
その際の20以下の値は全て30にして、ということだと思います

なんとなくわかってきたような気がします
しばし試行錯誤…

ゆり

Re:ポインタと関数を用いたプログラム

#18

投稿記事 by ゆり » 15年前

わからないでs…


#include <stdio.h>

void swap(double *a,double *b,double *c,double *d,double *e){
if(*a<=20)*a=30;
if(*b<=20)*b=30;
if(*c<=20)*c=30;
if(*d<=20)*d=30;
if(*e<=20)*e=30;
}

int main(void){
double a,b,c,d,e;
printf("a:");scanf("%lf",&a);
printf("b:");scanf("%lf",&b);
printf("c:");scanf("%lf",&c);
printf("d:");scanf("%lf",&d);
printf("e:");scanf("%lf",&e);

swap(&a,&b,&c,&d,&e);

printf("ave=%lf",(a+b+c+d+e)/5);

return(0);
}


(ちゃんと見れるかしら)
を実行してみると

a:10
b:20
c:30
d:40
e:50
ave=36.000000


となりました

本当にわからなくてあれなんですが
値を入力するときに
この例でabcdeを使用したところに
配列やfor文を使いたいんですが…

もう少し試行錯誤…

Dixq (管理人)

Re:ポインタと関数を用いたプログラム

#19

投稿記事 by Dixq (管理人) » 15年前

上でも言いましたが、コードを投稿する時はタグを使ってください。

で、関数については・・。

私が出した問題は解答に繋がるように作った物なので、それを見ながら順を追って作ってみてください。
関数の仕様が私が言ったものと全く違うものになっています。

まずは、私が出した問題を配列とfor文で解いてみてください。
「解けます」ではなく、コードをここに張り付けてみてください。
自分では思わぬ間違い等があるかもしれません。
(量が多くなりそうなら解る一番最後の解答だけでもいいです)

今回の課題は無理やり配列やforを使わずにやる方法もありますが、
綺麗ではないので、順を追って作り、完成させましょう。

重複しますが、私が出した問題を順々に解けば出来ます。
解らない部分があればどこが解らないか教えてください。

配列やループについて解らなければ
この辺で勉強して下さい。
http://www5c.biglobe.ne.jp/~ecb/c/c00.html

例えば配列を使うとこんな感じになりますが、
とりあえずこれをfor文で表示するようにすることから始めてみましょう。
#include <stdio.h>

int main(){
    int Val[5];
    Val[0] = 1;
    Val[1] = 2;
    Val[2] = 3;
    Val[3] = 4;
    Val[4] = 5;

    printf("Val[0] = %d\n",Val[0]);
    printf("Val[1] = %d\n",Val[1]);
    printf("Val[2] = %d\n",Val[2]);
    printf("Val[3] = %d\n",Val[3]);
    printf("Val[4] = %d\n",Val[4]);

    return 0;
}
 
課題締め切りが明日までとかだったら、その旨教えてください。

たかぎ

Re:ポインタと関数を用いたプログラム

#20

投稿記事 by たかぎ » 15年前

タイプミスがかなり多かったようですので、一度ここまでの内容をまとめて、改めて正しい質問内容を書いてみてください。

閉鎖

“C言語何でも質問掲示板” へ戻る