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

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

ただいまの
回答率

90.33%

  • C

    3995questions

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

配列

解決済

回答 6

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 705

uv-

score 18

n個のデータを配列に読み込み、平均と分散を求めるプログラムを作成して、下記のデータで試せ、という問題です。
{3.9,10.4,9.5,7.5,2.8,4.8,2.9,8.1,3.2,9.9}

次のようにプログラミングしたのですが、これだともともと10個のデータだと分かっている場合のプログラミングになってしまいます。任意の個数でだせるようにするためにはどうすればいいのか教えていただきたいです。linux,Gnome端末です。

#include<stdio.h>
int main(void)
{
double score[10];
double total=0.0 ,tempo=0.0;
double in_data;
double average, dispersion;
int i;
printf("input 10 data\n");
for(i=0;i<10;++i)
 {
scanf("%lf",&in_data);
score[i]=in_data;
total+=score[i];
}
average=total/10.0;
printf("average=%3.1f\n",average);
for(i=0;i<10;++i)
 {
scanf("%lf",&in_data);
score[i]=in_data;
tempo+=(score[i]-average)*(score[i]-average);
}
dispersion=tempo/10.0;
printf("dispersion=%5.3lf",dispersion);
return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Chironian

    2017/01/28 12:32

    無駄な改行をなくして、適切なインデントを付けましょう。読みやすくしておいた方が回答は付きやすいですよ。

    キャンセル

回答 6

+1

こんにちは。

gccならばVLA(可変長配列)が使えますので、最初に例えばint n;に個数を読み込んで、double score[n];と定義し、以下、10の代わりにnを使うことでできますよ。


【蛇足ですが】
ただ、VLAはCの標準規格では規定されていますが、C++の標準規格には存在しません。また、Visual C++はサポートしていないし、標準規格で規定されているにも関わらず「事実上の標準」にはなっていません。
あまり使わない方が良いです。今回は課題が「n個のデータを配列に読み込み」なので、使わざる得ないように思います。

インデントは例えば以下のように付けましょう。(他の付け方もありますが、for文の行頭とその中身を同じ桁にするのはどの方法でも不適切です。)
ループの範囲や条件分岐処理の範囲をひと目で分かるようにすることがポイントです。

#include<stdio.h>
int main(void)
{
    double score[10];
    double total=0.0 ,tempo=0.0;
    double in_data;
    double average, dispersion;
    int i;
    printf("input 10 data\n");
    for(i=0;i<10;++i)
    {
        scanf("%lf",&in_data);
        score[i]=in_data;
        total+=score[i];
    }
    average=total/10.0;
    printf("average=%3.1f\n",average);
    for(i=0;i<10;++i)
    {
        scanf("%lf",&in_data);
        score[i]=in_data;
        tempo+=(score[i]-average)*(score[i]-average);
    }
    dispersion=tempo/10.0;
    printf("dispersion=%5.3lf",dispersion);
    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

3通りの方法があります。

1. 動的にメモリを確保する
要素数の入力を最初に受けた後、動的にメモリを確保します。

10個 を n個 とした場合に必要なことは、配列[10]の長さをnにすること。
そのために動的なメモリ確保を行い、要素数10をすべてnに置き換えることです。
こちらは探せば具体例が見つかると思うので、malloc, freeで検索してみてください。

一番一般的な解決方法です。

2. 途中計算を逐次行う
配列を用意せず、逐次計算していける場合はこういう方法でも大丈夫です。

分散は計算式の関係上使えませんが、平均値は気にせず使えます。

    int count, i;
    double value, total=0.0, average=0.0;

    printf("input number of data:");
    scanf("%d", &count);

    if (count > 0)
    {
        i = count;
        while (i--)
        {
            scanf("%lf", &value);
            total += value;
        }
        average = total / count;
    }

    printf("ave : %lf\n", average);

3. 再帰関数を使用する
動的なメモリ確保を行わずとも、再帰的に関数を呼び出すことでスタックを使って回数を指定して取り込むこともできます。

こちらはあまり例がないと思うのでサンプルコードを載せておきます。

#include <stdio.h>

// 再帰関数
// □引数
//  org_count ... 入力全体の個数。平均計算に使用。不変
//  count ... 残りの入力数。呼び出し毎に1減らすことで再帰処理を制御する
//  total ... 入力された値の合計。平均計算に使用。呼び出し毎に加算する。
//  average ... 平均値の取り出し用
//  disp_total ... 偏差の集計用。tempo変数と同じ役割。
void calc(const int org_count, int count, double total, double *average, double *disp_total)
{
    double value;

    if (count == 0) {
        *average = total / (double)org_count;
        return;
    }

    scanf("%lf", &value);
    calc(org_count, count-1, total + value, average, disp_total);

    *disp_total += (value - *average)*(value - *average);
}

// 平均、分散を計算します。
// □引数
//  count ... 入力したい数。
//  average ... 平均値を取り出す。
//  dispersion ... 分散を取り出す。
//
// □備考
//  呼び出しやすいように整形した関数のエントリポイントです
//  初期化処理や必要な変数を確保しています
void CalculateAverageAndDispersion(int count, double *average, double *dispersion)
{
    double t = 0.0;
    double a = 0.0;

    if (count > 0) calc(count, count, 0.0, &a, &t);

    if (average) *average = a;
    if (dispersion) *dispersion = t / (double)count;
}

int main(void) {
    int count;
    double average, dispersion;

    printf("input number of data:");
    scanf("%d", &count);

    CalculateAverageAndDispersion(count, &average, &dispersion);

    printf("ave : %lf\n", average);
    printf("dis : %5.3lf", dispersion);

    return 0;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ctrl+cとかで入力されたら終了にすればいいかと。

追記
ctrl+cよりあり得ない数字でもいいかも?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

集計処理がメインの初歩的な課題だと考え

  • スコアの個数の上限を定めてよい。
  • 入力値制限がある(ありえない数値を終了判定に使える)

という仕様で考えると、以下のようにできます。

#include <stdio.h>

#define MAX_SCORE 100   // 最大個数
#define STOP_SCORE -999 // 入力終了値
int main(void) {

    double score[MAX_SCORE] = {0};
    int scoreCnt = 0;

    double in_data = 0;
    while( scoreCnt <= MAX_SCORE){
        printf("input data(%d to end) :", STOP_SCORE);
        scanf("%lf",&in_data);
        if( in_data == STOP_SCORE){  // 入力終了
            break;
        }
        score[scoreCnt] = in_data;
        scoreCnt++;
    }

    for( int i = 0; i < scoreCnt; i++){
        printf( "score[%d] = %f\n", i, score[i]);
    }
    return 0;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

c言語もLinuxもほとんど使わなくなったので、VisualStudioのC++だとこんな感じ、、、C#になれるとC/C++のメモリ管理は怖い、、、

#include <string.h>  
#include <stdio.h>  
#include <math.h>  
#include <stdlib.h>  

// ','で区切られた文字列からDouble配列を生成
int createArray(char* input,double **score)
{
    int count=1;
    for( char *c = input; *c!='\0'; c++ )
    {
        if( *c == ',' )
        {
            count++;
        }
    }
    *score = (double *)malloc( count * sizeof(double));
    {
        char seps[]   = " ,\t\n";
        char *token = NULL;
        char *next_token = NULL;
        int i=0;

        token = strtok_s( input, seps, &next_token);

        while( token != NULL )  
        {
            (*score)[i++] = atof(token);
            token = strtok_s(NULL, seps, &next_token);
        }
    }
    return count;
}


// http://home.a00.itscom.net/hatada/math/dev/stddev.html
double avg(double data[], int n) {
    int i;
    double sum = 0.0;
    for (i = 0; i < n; i++)
        sum += data[i];
    return sum / n;
}

// http://home.a00.itscom.net/hatada/math/dev/stddev.html
double dev(double data[], int n) {
    int i;
    double m = avg(data, n);
    double var = 0.0;
    for (i = 0; i < n; i++)
        var += (data[i] - m) * (data[i] - m);
    return sqrt(var/n);
}


int main(int argc, char* argv[])
{
    double *score;
    int count;
    char buf[1024];
    fgets( buf, sizeof(buf), stdin );
    count = createArray( buf, &score );
    printf("平均=%.3f, 標準偏差=%.3f", avg(score, count), dev(score, count));
    return 0;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

先頭に数字以外を入れると終了します。

#include <stdio.h>
#include <stdlib.h>
int main(void){
    char st[80];
    double *score;
    int ct;

    score = (double *)malloc(sizeof(double) * 10);
    printf("input numeric data & quit first charactor is not numeric\n");

    for(ct=0; scanf("%s",st) && isdigit(st[0]); ct++){
        if ( ct != 0 && ( ct % 10 ) == 0 ){
           if ((score = (double *)realloc(score,sizeof(double) * (ct + 10))) == NULL) {
               printf("realloc時にメモリが確保できません\n");
               exit(3);
           }
        }
        score[ct] = atof(st);
    }
    printf("input count: %d\n", ct);
    if ( ct == 0 ) return 0;
    double total=0.0 ,tempo=0.0;
    double average, dispersion;
    int i;
    for(i=0;i<ct;++i)
    {
        total+=score[i];
    }
    average=total/ct;
    printf("average=%3.1f\n",average);

    for(i=0;i<ct;++i)
    {
       tempo+=(score[i]-average)*(score[i]-average);
    }
    dispersion=tempo/ct;
    printf("dispersion=%5.3lf\n",dispersion);
    return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    3995questions

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