アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語の問題を授業で出されたのですがさっぱり分かりません。教えて下さい。

1.キーボードから整数nを入力して、1+2+…+nを求めるプログラムを作れ。
2.キーボードから整数nを入力して、1*2*…*nを求めるプログラムを作れ。
3.キーボードから10個の実数を入力し、それらの平均を求めるプログラムを作   れ。
4.円錐の体積を求めるプログラムを作れ。 注:円錐体積V=π*r*r*h/3
5.キーボードから文字列を入力し、それを逆さまにするプログラムを作れ。例えば、”dog”を逆さまにすると”god”になる。
6.キーボードから一つの整数を入力し、それは奇数か偶数かを判断するプログラムを作れ。

ちなみに6番は
/* iftst.c */
#include <stdio.h>

void main(void)
{
int n;

printf("n=");
scanf("%d",&n);
if(n%2 == 0){
printf("偶数です\n");
}
else{
printf("奇数です\n");
}
}

で合っているのでしょうか?

A 回答 (5件)

/* iftst.c */


#include <stdio.h>

void main(void)
{
int n; /* 入力値 */
int loop_cnt; /* カウンタ */
int gokei; /* 加算合計 */

printf("n=");
scanf("%d",&n);

gokei = 0; /* 加算合計初期化 */
for( loop_cnt = 1; loop_cnt <= n; loop_cnt++ ){
gokei = gokei + loop_cnt;
}
printf("1,nの合計%d\n",gokei);
}
    • good
    • 0
この回答へのお礼

これは何番なのでしょう?ホントに初心者なのでプログラムを見てもさっぱり分からないのです…。

お礼日時:2001/07/10 11:11

naturalです。


コメント読みました。

取り敢えず最も初歩の段階から説明することにします。
以下のソースは何の処理もしませんがコンパイル出来る完全なプログラムです。

void main(void)
{
}

このような形でC言語の最小のプログラムは書けるわけです。
後は{と}の間に処理を書き連ねていけばプログラムとして色々な仕事をする様にできます。

voidと言う部分が2カ所ありますが、ちょっと解説しておきたいと思います。
最初の方は関数型と呼ばれる部分で、どんな型の値を返してくるかを指定します。
つまり人間に例えると、その関数が仕事を終えた後でどういった形で報告をおこなうかを指定する部分です。
後者の方は引数と呼ばれる部分でその関数がどんな型の値を引き受けて仕事をするかを指定します。
こちらも人間に例えると、どんな資料を与えて仕事をさせるかを指定するわけです。
このプログラムではどちらもvoid型となっていますがvoidは「特に無い」ことを示します。
つまり使用する際には返却値も引数も無いと言うことになります。

さて前述の様に{と}の間にいよいよ処理を加えたいと思います。
但し関数を使用する場合その関数を宣言しているヘッダーファイルと呼ばれるものを読み込んでやるように指定しなければなりませんのでご注意下さい。
例えばこうです。

#include <stdio.h>
void main(void)
{
  printf("Hello,world!\n");
}

上記の例で言うところの#includeで始まる行がヘッダーファイルの読み込み指定部分です。(厳密に言うと読み込みでは無いのですが便宜的にそう述べておきます)
お解りでしょうか?
printfと言う関数がどういった形で使われるべきかと言った情報がstdio.hにはあり、このファイルの情報を読み込ませることによってコンパイラーにも情報がわたり、翻訳の際に参照されるわけです。
因みに使う関数によってどんなヘッダーファイルを指定すればよいかについてですが、テキストをお持ちならば関数の仕様がどこかに解説してあるはずですのでそちらをご覧頂ければ記載されているはずです。

ここまででC言語の第一歩となるはずですが、既に理解されていたでしょうか?
もしまだならばもう一度テキストの冒頭部分を読み返してみることをお奨めします。
単位をあきらめるのはまだ早いですよ!頑張って!!p(^^)q
    • good
    • 0
この回答へのお礼

5回ほど繰り返し読んでみましたがやっぱり理解不能です。せっかく丁寧に書いていただいたのに…。ありがとうございます。

お礼日時:2001/07/10 14:57

出題者の観点から、重要と思われる点については●をつけてあります。



■1,2について
 合計はsum、階乗はfacなどとして、計算途中の値を覚えておく変数を用意する必要があります。全ての計算を終えた時、この変数が答えになります。
 1~nの範囲で計算を行うので、カウント用変数 i の値が1~nになるようforループを作り、ループ内で「sum += i;」「fac *= i;」のようにします。
●このとき重要なのは sum、facの初期値で、ループに入る前に正しく設定しなければなりません。nを4くらいに仮定して、机上でループを展開してみれば分かるハズです。

■3について
 平均は「合計÷個数」なので、合計に関しては1を参考にしましょう。n=10としてループし、中で値を入力→sumへの足しこみを行います。
●気を付けなければならないのは「÷個数」の計算式の書き方です。
 10で割った結果が必ず整数になる保証は無いので、結果は小数として処理しなければなりません。つまり、平均用の変数は「double ave;」のように宣言します。
 更に、整数÷整数の結果は整数となってしまうため、単純に「ave = sum / 10;」としても、aveには正しい結果は入りません。小数の結果を得るためには、「ave = sum / 10.0」として整数÷小数とするか、「ave = (double)sum / 10;」のようにsumを小数型へキャストするようにしましょう。もちろん両者を同時に行っても構いません。
 結果の表示も、%fで小数表示するようにしましょう。

■4について
 必要なのはrとhだけですから、それぞれを%fでdouble型(またはfloat型)変数に入力させ、計算します。
●おそらく求められているのは、処理の関数化でしょうね。
  double calc_volume_cone(double r, double h);
のようなプロトタイプで処理するようにすると良いでしょう。

■5について
 文字列を逆さまにする関数はないので、入力された文字列の終端を調べ、1文字ずつ処理を行います。
 ただ、とにかく逆さに表示すればよいのか、文字列を格納した文字配列の中身自体を反転するのか分かりません。naturalさんは表示のみ、brogieさんは別配列への格納を解説されているので、文字配列内部の反転について書きます。

  char *strrev(char *str) {
    int n1, n2;
    char ch;

    n1 = 0;
    n2 = strlen(str) - 1;
    while (n1 < n2) {
      ch=str[n1]; str[n1]=str[n2]; str[n2]=ch;
      n1++; n2--;
    }
    return str;
  }

 引数として渡された文字列strの、n1番目とn2番目を交換していくことで反転を行います。よってn1の初期値は0、n2の初期値は文字列終端に合わせます。(strlenで求めた「文字数」は1から数えたものであり、0から数える配列添字に直すため1を引いています。)
 n1は0から後ろに、n2は終端から前に調べていくため、ループの条件を「n1 < n2」とし、文字の交換後、「n1++;(後ろへ)」「n2--;(前へ)」を行います。
 戻値で文字列strの先頭アドレスをそのまま返しているのは、「puts(strrev(s));」のような使い方ができるようにするためで、文字列処理では一般的な方法です。

■6について
 ikuchanさんの回答でOKです。
 欲を言えば、if文の条件を直接「n % 2 == 0」とせず、マクロで
  #define iseven(n) ((n) % 2 == 0)
のように定義し、
  if (iseven(n)) {
のようにすると良いでしょう。まぁ関数にしても良いですが。
    • good
    • 0
この回答へのお礼

用語についても分からないのでとっても難しいです。まだはじめたばかりだし苦手なので、この文を読んでも分かっていないのですが、とりあえずがんばってみます。ありがとうございます。

お礼日時:2001/07/10 11:19

ヒントです。

これ以上は書けません。ご自分で考えてください。
6.の解答が出来ているではありませんか?
宣言やmain関数も省略しています。

1.について
for(i = 1;i<=n;i++){
   s+=i;
}

2.について
ans=1;/*これ必要です*/
for(i=1;i<=n;i++){
   ans*=i;
}

3.について
for(i=1;i<=10;i++){
   scanf("%d",&n);
   asn +=n;
}

4.略(簡単)

5.について
#include <string.h>  /*strlen()のプロトタイプ宣言*/
char str1[256],str2[256];
scanf("%s",str1);
len1=strlen(str1);
for(i=len1;i>0;i--){
   str2[len1-i] =str1[i];
}
以上です。参考まで(^^)
    • good
    • 0
この回答へのお礼

これをどこにどういう風に入れていいかさえも分かりません。やっぱり私にはC言語は理解不能です。この授業の単位はないと思われます(ToT)ありがとうございました。

お礼日時:2001/07/10 11:23

1番及び2番に関しては関数分割しなくて良いのなら、単純に入力された数を元にfor文でカウンタをインクリメント、または元の数からデクリメントしていけば出来ます。


ループ内部の処理は単純計算ですから判りますよね。
3番では問題に書かれている通り「実数」を使用するのがポイントです。
用意する変数、入力時、出力時それぞれ実数を意識してやればOKです。
10回分の入力は勿論ベタで書いてはいけません。
構文を使えば簡単ですよね。
4番も3番と同じく実数を使用することで簡単に出来るはずです。
5番は入力された文字列を逆順で出力するだけですから、入力された文字列の末尾を見つけます。(つまりヌル文字の前の文字を見つけるわけです)
文字列の長さを測る関数の使用が許されているならばそれを使えば良いのですが、そうでない場合は構文を使ってヌル文字を検索しその場所が何番目か判れば良いわけです。
そこから一文字ずつ先頭文字まで改行しないで出力していけばOKです。
6番は、上記のやり方で大丈夫でしょう。(^_^)
    • good
    • 0
この回答へのお礼

う~ん…。読んでも分からないです。初心者だし苦手だし将来必要なものでもないのでホントにさっぱり分かりません。でもありがとうございます。

お礼日時:2001/07/10 11:15

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