プログラミング入門I
2021.11.29

Back to index page



  1. 本日の作業内容

  2. 前回の宿題について

    残念ながら今回もコンパイルエラーのプログラムが提出されました.原因は単純なミスタイプなのですが,提出前に自分で確認すればわかるはずです.残念です.

    コンパイルエラー: b2141

    それから,頑なに解答用紙の使用を拒否する人がいますが,これまでの提出分全て採点していませんので,単位の取得はちょっと難しいでしょう.どうして解答用紙を使用しないのでしょうか?

    解答用紙不使用: b1923

    解答用紙を使ってプログラムを作る際には,まず学生番号と名前を自分のものに変更してから,落ち着いてプログラミングを始めましょう.島根太郎さんはこの授業の履修者ではありません.

    名前の間違い: b1734 b2157

    学生番号の間違い: b2157

    そして,相変わらず出て来る不適切なインデントです.少しは解答例や教科書を参考にして修正する気になりませんかね?TABキーを使用しないで適当な数スペースを入れるスタイルの人もいつまでの意地を張っていないで素直にTABを使って見た目の綺麗なソースコードにしましょう.

    インデントの不備: C008 b2115 b2118 b2128 b2129 b2130 b2134 b2139 b2144 b2157 b2158 b2165

    前回のWebテキストで書いたように,下のような悪意があるとしか思えないインデントのまったくの無視は今回から採点しません.b2158さん,いい加減インデントを理解してください.

    int 
    main(void) {
    
    int a,b,i;
    srand((unsigned)time(NULL));
    
    a=rand()%100+1;
    b=rand()%100+1;
    if(b<a){
    i=a;a=b;b=i;
    }
        printf("Numbers between %d and %d\n",a,b);
    for(i=a+1;i<b;i++){
        printf("%d ",i);
    }
    printf("\n");
    
    
    
        printf("\n-------------------------\n\n");
        return 0;
    

    さて,以下は例によって問題のあるプログラムの例です.参考にしてください.

        int i = rand() %100 + 1;
    

    毎年良く出てくるのですが,変数で i, j, k, l, ... という1文字の簡単な変数名は for() 文の中で使用することに限定しましょう.世間一般では基本的にはそういう風に使っていますので,無用の混乱をもたらすようなことはやめてください.また,このところ,変数名について特に注意喚起していなかったので,また意味のない a, b, ... などの変数名を使用する人が出てきました.変数名は読む人にその意味が伝わるよう適切なものをつけてください.

        int small = rand() % 90 + 10;
        int large = rand() % 90 + 10;
    

    今回は,乱数は2桁の正の整数ではなく,1から100までの整数でしたので,これからも問題をきちんと見るよう注意しましょう.

        if (num1<=num2)
        {
            printf("Numbers between %d and %d\n", num1, num2);
            for (i = num1+1; i <=num2-1; i++)
            {
            printf("%d ", i);
            }
        }
        else
        {   
            printf("Numbers between %d and %d\n", num2, num1);
            for (i = num2+1; i <=num1-1; i++)
            {
            printf("%d ", i);
            }
        }
    

    今回非常に多かったパターンです.一度 if() 文を覚えてしまうと,何でもかんでも場合分けする癖がついてしまうのですが,なるべく簡単なソースコードや処理になるようもう少し考えてください.ブロックの中にある for() 文の処理は if と else の両方で共通していますね.だったら,中に入れる必要は無い,と考えてみましょう.

    だから,問題の下のヒントのところに「値の入れ替え」と書いておいたのですが...
        if (num1<=num2)
        {
            first  = num1,
            second = num2;
        }
        else
        {
            first  = num2,
            second = num1;
        }
    

    これもいくつか見られたパターンです.変数の無駄遣い的なちょっと惜しい書き方です.

        num_a = rand() % 100 + 1;
        num_b = rand() % (100 - num_a) + num_a + 1;
        aida = num_a;
    

    num_b は1から100までの整数のどれかではありますが,範囲が限定されていて,出題の意図から外れてしまいます.

        int i, num1, num2;
    
        num1 = rand() % 100 + 1;
        num2 = rand() % 100 + 1;
    
        if(num2 < num1)
        {
            i = num1;
            num1 = num2;
            num2 = i;
        }
    

    上でも説明したように,変数名 i はこんなことで使用しないで下さい.

        for(i=a+1;i<b;i++)
        {
            printf("%d",i);
        }
    

    こういう人も何人かいました.printf() の中が "%d" となっているので,出力結果が下のようになります.

    Numbers between 9 and 90
    1011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
    

    非常に見づらいですよね.自分でも見本と違うことには気づいたはずでしょうから,それくらいは直して下さい.

        int i, num1, num2;
        
        num1 = rand() % 100 + 1;
        num2 = rand() % 100 + 1;
    
        printf("Numbers between %d and %d \n", num1,num2);
    
        for(i=num1+1; i<num2; i++)
        {           
            printf("%d ", i);   
        }
        
        printf("\n");
    

    num1 の値が num2 よりも大きかったら何も表示されませんよね.自分で気づきませんでしたかね.

        int i , large , small , a;
    
        large = rand() % 100 + 1;
        small = rand() % 100 + 1;
    
        if(large < small)
        {
            large = small;
            small = a;
            a = large;
        }
    

    if() 文のブロックの中の2行目で変数 a の値を変数 small に代入していますが,その変数 a の値はまだ定まっていません.環境によっては(例えばLinuxのCコンパイラ)不定の値が入りますので,結果が変なことになってしまいます.値の入れ替えは大事ですので,今回の解答例を見て,きちんと理解してください.

    今回は反復処理としては最初の課題だったので,簡単なものを用意したつもりだったのですが,なんか変な風なこんがらがった処理を書いた人が結構いました.教科書とWebテキスト,そして実習の解答例などで基本的なところをしっかり学習してください.いきなりネットなどで検索すると,変なものが見つかるので注意しましょう.

  3. 前回の復習

    for 文の基本を学習しました.まず, for 文が以下の構成からなることをしっかり理解してください.今後もどんどん出てきます.

        for(式1; 式2; 式3)
        {
            文;
        }
    

  4. for 文その2

    for 文については,さまざまな使い方があります.そのいくつかについて,今週は試します.

    • 式1~3の省略

      上の for 文の基本で紹介した式1~3ですが,必ず必要という訳ではありません.例えば,全部省略すると,「無限ループ」となりますが,文法的な間違いではありません.

    • 式2の誤解

      ときどき式2のことを「終了条件」と間違えて覚えている人がいます.式2は終了条件ではなくて,「実行条件」です.すなわち,式2が「真の間」実行します.

      これまで以下のような間違いを何度も見てきました.

          for(i=1; i>5; i++)
          {
              文;
          }
      

      変数 i の値が5になったらループを終わるというつもりでしょうが,これでは1回も実行されません.注意してください.

    • 式3について

      毎回一定数増えるような使い方ではない場合には,式3は空欄の場合もありえます.その場合には処理の中の文のところで,変数の値をどのように変えていくのか,記述する必要があります.ただし,このような場合には次週出てくる while 文の方が向いていることが多いです.

    • その他

      while 文の方が良いこともある場合は他にもたくさんありますが,あえて for 文で作ることもあります.例えば,以下の例は別に for 文で作る必要はありませんが,大体の人が for 文の方に馴染みがあるので,作っても構いません.

          num = rand() % 90 + 10;
          printf("%d\n", num);
          
          for(; num>0; )
          {
              num -= rand() % 9 + 1;
              printf("%d\n", num);
          }
      

  5. 実習

    今回も for 文です.演習問題でしっかり学習しましょう.

  6. 次回の予習範囲

    教科書のp.61まで予習をしてきてください.

  7. 宿題

    レポート提出システムにアクセスして提出してください.公開は原則として当日の18:00以降です.また,提出期限は次の月曜日の10:00です.


目次ページに戻る