89281


[苦しんで覚えるC言語](https://9cguide.appspot.com/) にてCを学んでいる中学生です。  
Cの配列についてわからないことがあったので質問をさせて下さい。

以下のコードで、はじめに入力した数列の量の分だけ配列を確保して、その数列の最大値,最小値,平均値を出すプログラムを作ってみました(`-1`と入力するとbreakします)。

しかし、[ブラウザで動く C言語実行環境](https://9cguide.appspot.com/web_picoc_em.html)
でのコンパイルでは以下のエラーが起こります。キーワードの未定義とはどういうことなのでしょうか。教えて下さいm(_ _)m

**エラーメッセージ:**

[code]

    if(suu[i]==-1)
    -main.c:19:14 キーワード: 'suu' が未定義です。スペルミスがないか再確認してください。
    
[/code]

**ソースコード:**

[code]

    /* main.c */ 
    #include<stdio.h>
    int maxmin(void);
    
    int main(void)
    {
        maxmin();
        return 0;
    }
    int maxmin(void)
    {
        int a,i;
        double he,max=0,min=1000000,suu[];
        scanf("%d",&a);
    
        for(i=0;i<a;i++){
            scanf("%lf",&suu[i]);
            if(suu[i]==-1){
                break;
            }
            printf("%d番目の数:%7.3f\n",i,suu[i]);
            if(suu[i]>max){
                max=suu[i];
            }else{
                if(suu[i]<min){
                    min=suu[i];
                }
            }
             he+=suu[i];
        }
    
        printf("最大値%7.3f,最小値7.3%f,平均値%7.3f",max,min,he/a);
        return 0;
    }
    
[/code]


CC BY-SA 4.0
2022-06-08T02:47:10.897
89278
2022-06-11T06:29:57.167
2022-06-08T04:16:58.330
3060
52948
question
c
配列について教えて下さい


正しいエラーメッセージはおそらく`definition of variable with array type needs an explicit size
or an initializer`か類似のものです。  
13章に書かれていますが、配列は宣言するときに要素数を指定するか同時に定義するかその両方が必要です。

なお、今回のような宣言するときに要素数を決められないときは19章の動的配列を使います。


CC BY-SA 4.0
2022-06-08T03:51:03.867
89281
2022-06-08T03:51:03.867
25936
89278
answer


`suu[]={}` と記述したら直りました。  
回答してくださった方ありがとうございます。

**修正前:**

[code]

        double he,max=0,min=1000000,suu[];
    
[/code]

**修正後:**

[code]

        double he,max=0,min=1000000,suu[]={};
    
[/code]

* * *

774RRさん!! これでどうだー!!!!!(宿題やりました)

[code]

    /* main.c */ 
    #include<stdio.h>
    int maxmin(void);
    
    int main(void)
    {
        maxmin();
        return 0;
    }
    int maxmin(void)
    {
        int a,i;
        double he,max=0,min;
        
        scanf("%d",&a);
        double suu[a];
    
        for(i=0;i<a;i++){
            scanf("%lf",&suu[i]);
            if(suu[i]==-1){
                break;
            }
             if(i==0){
                min=suu[i];
             }
            printf("%d番目の数:%7.3f\n",i,suu[i]);
            if(suu[i]>max){
                max=suu[i];
            }else{
                if(suu[i]<min){
                    min=suu[i];
                }
            }
             he+=suu[i];
        }
    
        printf("最大値%7.3f,最小値%7.3f,平均値%7.3f",max,min,he/a);
        return 0;
    }
    
[/code]

re>>774RRさん！２つの配列を利用したプログラムです。...効率悪い

[code]

    /* main.c */ 
    #include<stdio.h>
    int maxmin(void);
    
    int main(void)
    {
        maxmin();
        return 0;
    }
    int maxmin(void)
    {
        int a,i1,i2;
        double he,max,min;
        
        scanf("%d",&a);
        double suu1[a],suu2[a];
    
        for(i1=0;i1<a;i1++){
            scanf("%lf",&suu1[i1]);
            if(suu1[i1]==-1){
                break;
            }
            printf("%d番目の数:%7.3f\n",i1,suu1[i1]);
            he+=suu1[i1];
        }
        for(i1=0;i1<a;i1++){
            if(i1==0){
                suu2[i1]=suu1[i1];
            }else{
                if(suu1[i1]>=suu2[0]){
                    for(i2=0;i2<a;i2++){
                        suu2[i1+1]=suu2[i1];
                             i1+=1;
                    }
                    i1-=a;
                    suu2[0]=suu1[i1];
                }else{
                    suu2[i1]=suu1[i1];
                }
            }
    
        }
        max=suu2[0];
        min=suu2[a-1];
    
        printf("最大値%7.3f,最小値%7.3f,平均値%7.3f",max,min,he/a);
        return 0;
    }
    
[/code]

だめだーー失敗してるーーー


CC BY-SA 4.0
2022-06-08T04:43:31.803
89285
2022-06-11T06:29:57.167
2022-06-11T06:29:57.167
3060
52948
89278
answer


今話題にしているのは「要素数が実行時に決まる配列」で、これを可変長配列と呼びますが

[c](/questions/tagged/c "'c' のタグが付いた質問を表示")
も言語仕様の[改定](https://ja.stackoverflow.com/questions/39922/)が何回かあって

  * 初期の [c](/questions/tagged/c "'c' のタグが付いた質問を表示") (C95 まで) は可変長配列は使えません
  * C99 では可変長配列が使えることになりました（必須扱い）
  * C11 では可変長配列をサポートしなくてよくなりました

で、この可変長配列をサポートしているコンパイラかつ実行環境であるなら

[code]

    scanf("%d",&a);
    double suu[a]; // 実行文の後ろに変数宣言が書けるのは C99 以後
    
[/code]

のように書けることになっています。要素数 `a` が確定しないと配列を作ることができないので、配列の変数宣言は `scanf`
の前で行うことができません。苦Cは C89
の頃の仕様で記事が書かれているので提示のような「宣言が先、実行文があった後は宣言禁止」という太古の仕様を守っており、今見ると古臭いし、この手の可変長配列はそもそも解説されていません。

自己回答における `double suu[]={};` は不完全で、これだと配列の要素数が１個なので、誤っています（誤動作してしまいます）

あと `max` のほうは判定正しいんだけど `min` のほうは判定間違ってますので注意。どう間違っていてどう直すとよいかは宿題ということで。

* * *

この手の全探索なりソートなりでの典型的テストケースは

  * データ０件（プログラムというより仕様策定の是非が問われる）
  * データ１件（下記ソート済みの場合の一環でもあります）
  * 全部同じ値であるデータ
  * 昇順・降順にソート済みデータ
  * 真にランダムなデータ
  * アルゴリズム上もっとも不得意そうなパターンを事前に検討して作った最悪データ

提示例はソート済みデータに対して `min`
判定がバグってますよね。典型例はデータ１件の場合で、それは最大値でありかつ同時に最小値になるわけです。当初コードの `else`
がいらないわけです（これがあると最大値かつ最小値の判定がうまくない）配列２つも用意する必要はなさそうです。


CC BY-SA 4.0
2022-06-08T05:09:30.793
89289
2022-06-10T11:51:45.133
2022-06-10T11:51:45.133
8589
8589
89278
answer

[code]

    suu[]={};
    
[/code]

は配列の要素数が0になりますので、コンパイルは通っても、実行時にエラーになってしまいます。動的配列を使うか、suu[1000000]等の要素数の記入が必要です。


CC BY-SA 4.0
2022-06-08T07:05:47.180
89290
2022-06-08T07:05:47.180
24490
89278
answer