プログラミング入門I
2018.11.12

Back to index page



  1. 本日の作業内容

  2. 前回の宿題について

    今回はコンパイルエラーがなかったので,採点はだいぶ楽でした.この調子で皆さんこれからもよろしくお願いします.ただ,重大な問題が以下のように出てしまっています.

    解答用紙を使用していない: b1760 ←残念ながら採点対象外です.

    解答用紙の改ざん: b1202

    以下はよくある問題ですが,なくしていくようにしましょう.

    コンパイル時の警告: b1202 b1566
    ハイフンライン無し: b1825 b1860 b1734
    解答用紙に番号と名前無し: b1807
    結果出力時の学生番号が違う: b1804 b1860
    インデント不適切: b1803 b1820 b1822 b1825 b1848 program1

    以下は例によって問題のある解答の一部です.今後の参考にしてください.

    main(void)
    {
    

    授業中に注意しましたが,今年度からは main() を作るときに int の型指定をしてください.忘れないように,解答用紙にすでに入れてあるので,勝手に変更してはダメです.

            int a = (rand()% 0700)+0100;
            int b = (rand()% 0xf000) + 0x1000;
    

    間違いではないので減点してはいませんが,外側の()は不要ですね.

            int m = rand() % 0677 + 0100;
            int n = rand() % 0xefff + 0x1000;
    

    ちょっと間違っています.これは2桁の整数の時に89が出てくるのと同じ間違いです.

            int a=100;       
    

    なんじゃこれは?ということで,むちゃくちゃな初期化で大幅減点.

            int n = rand() % 999+1;
    
            int m = rand()   % 9999+1;
    

    10進数の場合すら全くわかっていないので,却下!

            int num1 =  rand() % 900 + 100;
            int num2 =  rand() %9000 + 1000;
    

    10進数の桁数指定ではないですし.

            int a = rand() % 448 + 64;
            int b = rand() % 61440 + 4096;
    

    プログラミングは自分が楽をするために活用します.自分で手計算とかするんなら意味ないし.楽しましょう.

            int b = rand()%  447+64;
    

    で,さらに間違っているし.これも89の呪縛?

    int a =rand() % ((8*8*8)-(8*8)) + 8*8 ;
    int b =rand() % ((16*16*16*16)-(16*16*16)) + 16*16*16 ;
    

    面倒くさ!これを考えつくくらいならもっと楽する方に頭を使えばいいのに.

    ということで,以下に簡単に関節しておきます.

    10進数の場合ですが, m 桁の10進数を必要十分条件を満足して発生させるためには,以下の式でした.

    	int num = rand() % 90 .... 00 + 10 ..... 00;
    	                    ---------    ----------
    	                    0が m-1 個    0が m-1 個
    

    で,式の中にある9はその進数で使用可能な最大の数ですし,1は0ではない使用可能な最小数です.ということは, m 桁の n 進数を必要十分条件を満足して発生させることは,上の規則に従えば,以下のようになります.

    	int num = rand() % 0?[n-1]0 .... 00 + 0?10 ..... 00;
    	                          ---------      ----------
    	                          0が m-1 個    0が m-1 個
    

    n - 1とは n 進数で扱える最大の数ということですから,8進数の場合なら 7 で,16進数であれば f です.

  3. 前回の模擬テストについて

    模擬テストでしたが,結果はなかなか悲惨でした.次回の本テストまでに改善しましょう.

    解答用紙を使っていない: program1

    解答用紙を改ざん?勝手に変更した: b1848

    名前を書いてない: b1805

    コンパイルエラーは大量に出てきました.残り時間ギリギリまで回答するのではなく,最後の数分はエラー回避に次回からは時間を使ってください.

    コンパイルエラー: b1802 b1805 b1808 b1810 b1819 b1820 b1827 b1829 b1833 b1838 b1840 b1843 b1853 b1859 b1860 program2 program3 b1566 b1754

    警告: b1802 b1805 b1808 b1811 b1814 b1816 b1831 b1833 b1838 b1839 b1842 b1844 b1847 b1857 b1858 b1860 b1566 b1735 b1741 b1742 b1754 b1759 b1775

    インデントの問題も出てました.

    インデント: b1804 b1830 b1831 program3

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

            double c = rand() % 9 + 1 ;
    

    今回1年生で多く見られました.乱数を発生させる関数 rand() int 型限定です.

            printf("Area of circle: %d m^2\n",a*a*3.14);
    

    これも多く見られました.せっかく浮動小数点数にしても %d にしたら台無しです.

            printf("Volume of sphere:%4.2fm^3\n",v);
    

    上の例は小数部以外に全部の長さを4桁と指定しています.今回の例は発生する乱数によって整数部の桁数が変わるので,固定長ではなく小数部だけの桁数を指定するほうが良いです.

            c*=(float)3.14;
    

    3.14はすでに float 型ですが?

  4. 前回の復習

    乱数について,前回はその使い方をさらにいろいろ試しました.ただ,乱数以前に,小テストでは数値の型の問題が十分理解できていないことと, printf 文の中で表現する % 記法の型の理解もできていないことが判明しました.

    基本中の基本ですので,まずは,そこを抑えましょう.

  5. 式と文

    これまで, printf 文とかの言葉を使ってきましたが,この節のところをよく読んで,文の意味も理解してください.今回からは if 文が登場します.

    なお,教科書のp.47の文並びやブロックにある例は,それだけでは動作しませんので注意してください.このままエディタに打ち込んでコンパイルすると,当然ですが,変数 a などが定義されていないので,エラーとなります.

    中括弧で囲まれた部分を「ブロック」と言いますが,ブロックの中に書かれる式や文は字下げ(インデント)されますので,ご注意ください.

  6. if

    • 教科書の補足

      今回は変数などの値に従って次の処理が変わる「分岐」を扱います.分岐させるための判断として,今回は関係演算子(比較演算子)と等価演算子について学習します.値が大きい,小さい,等しい,等しくないなどの演算を行って,その結果に応じて処理が変わります.

      教科書p.49のリスト3_1ですが,肝心の if 文のところが変則的な表現になっています.

      	if(a % 2)
      	{
      		printf("Odd number\n");
      	}
      

      これは例題としてはあまりふさわしくないようです.本来であれば次のように書くべきです.

      	if(a % 2 != 0)
      	{
      		printf("Odd number\n");
      	}
      

      もしくは,

      	if(a % 2 == 1)
      	{
      		printf("Odd number\n");
      	}
      

      関係演算子や等価演算子などの演算は,結果がブール値で返ってきます.すなわち,「真」もしくは「偽」です.TrueもしくはFalseということなのですが,その値は処理系によって異なっているものの,偽の場合に0という数値を返すことはほとんどの言語で同じです.なので,動作的には正しく行われるものの,明示的に期待する結果を判断していないので,おすすめしません.

      また,教科書p.49の中頃に,以下のような記述があります.

      なお,本書では if 文の文をいつでもブロックの形で書くこととする.

      実は if 文はその式が1行だけなら中括弧無しでも動作します.

      	if(a>2)
      	{
      		printf("OK\n");
      	}
      

      のような処理は

      	if(a>2)
      		printf("OK\n");
      

      でも動作します.ただし,文が2行以上になる場合には,必ず中括弧が必要です.さらに,中括弧の位置ですが,教科書と違う以下のような位置で書くこともよく行われています.

      	if(a>2){
      		printf("OK\n");
      	}
      

      この授業ではどちらでも構わないこととします.個人的には上の書き方の方が好きですが,今後は教科書の方式に統一して例題は作成します.

      ところで,教科書のp.50にあるリスト3_2ですが,関数 main() の後の中括弧の位置がこれまでと違っています.

      これまでの例
      int main(void)
      {
      

      リスト3_2
      int main(void){
      

      どちらにあっても動作に影響は無いのですが,3_2はたまたま間違ってこうなっていると思われますので,気にしないでこれまで通りの位置で書いていきましょう.

    • 多重の if

      if 文の中に if 文を入れることも可能です.次週以降で出てくる論理演算子を使用すれば回避できる場合もありますが,使用することも多いので,少し練習しておきましょう.

      #include <stdio.h>
      #include <stdlib.h>
      #include <time.h>
      
      int main(void)
      {
      	srand((unsigned) time(NULL));
      	
      	int num = rand() % 21 - 10;
      	
      	printf("Random number: %d\n", num);
      	
      	if(num<=4)
      	{
      		if(num>=-4)
      		{
      			printf("Its absolute value is less than 5.\n");
      		}
      	}
      	
      	return 0;
      }
      

      これを実行すると,例えば,以下のようになります.

      Random number: -2
      Its absolute value is less than 5.
      

      上の例では,処理以外にもインデントのやり方にも注意してください.ブロックが出てくるたびにインデントのTABが1個増えます.

  7. 実習

    実習の演習問題は予習用の部分はすでに見えますのでしっかり予習してください.

  8. 次回の予習範囲

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

  9. 宿題

    宿題についても当日ご案内します.ただし, 宿題の問題を見ることができるのは13日以降になりますので,注意してく ださい.


目次ページに戻る