東京工芸大学 工学部  電子機械学科 2年 前期 

基礎プログラミング 第2回
 2017.4.18 
藤木 文彦

http://fujiki.tv/t-kougei/kisoprog/
fujiki.kougei@gmail.com  
インデックスに戻る    


ページ最後に、先週の課題の解答例を掲げます



【今日の授業の進め方

 解説を読み、各プロジェクトを実行したのち、ページ後半にある「課題」にある指示に従ってプログラムを一部改変、実行して、指示に従って、プログラムと実行結果、考察を行ってメールを提出しなさい。

メールは、課題一つを1つのメールとして提出


【演習】の場所へ移動


変数ヘンスウカタ算術サンジュツプログラム(1)

変数名

 数学で、 " x = 1 " と代入するように、C言語でも、英文字を変数として使用できます。変数は、文字列で表す事ができますから、たとえば "number = 10 " と言うように使用できます。変数名に使用できる文字は、C言語の種類によって異なりますが、一般的には、アルファベットと、数字、一部の記号です。(先頭は、数字でにしてはいけない。)以前は、変数名は簡略なものを用いていましたが、最近は、内容が分かりやすいような変数名にすることが推奨されています。
 数を数えるときに使われることの多い、i, j, k などは、1文字で使われることも多いのですが、これも、何の数を数えるのか分かりやすくするべきだと言うスタイルもあります。(プログラミングスタイルは、人により、場合に依って違うので、本講義では、間違えない範囲で、短めの変数名を使用します。最近の言語では、長い変数名を使用するスタイルが一般的なものが多くなってきています。)
 なお、これも、一般的な約束として、変数名は小文字、定数名は大文字で表現します。(大文字小文字を厳密に区別する処理系と、同一のものとして扱う処理系があるので、注意が必要です。)



変数の型

 C言語でプログラミングを行うときに、プログラム内で使用する「変数」は、使用する前に、その「型」を宣言しておかなければなりません。
 「型」とは、「整数」「実数」「文字」というような、変数の内容が、どのような物になるのかを表すものです。具体的には、以下で掲げる様な種類があります。

 言語によっては、変数の型宣言の必要の無いものもありますが、多くの言語では、「変数を間違いなく使用するため」に、プログラムの先頭に、変数の名前と、その型を指定する必要があります。
(注) 最近のC言語では、プログラムの中で、新しい変数を型宣言して使用できるものもあります。)

 文字を扱う変数型 char は character の略、整数を扱う変数型 int は integer の略ですが、実数型は、「浮動小数点」と呼びますので、 float 、 より桁数の多い数値を扱う時には、 double を用います。
 なぜ、「浮動小数点」というのかというと、同じ桁数を扱う場合でも、大きさによって、小数点の位置を変えて表現するからです。

 整数、実数、倍精度実数では、正負の数を扱えますが、場合に依っては、正の数だけを扱うように ( unsigned ) 宣言することが出来ます。

 それぞれの型によって、printf( ) 文で出力するときの、書式制御の文字が異なりますが、別の形式の出力を指定することも出来ます。ただし、その場合の出力は望んだ結果とならない事もあります。


 型名  宣言 printf での書式    バイト長  範囲 
 文字型  char %c    1  
 整数型  int  %d  2 または
 4
-32,768〜32,767       
-2,147,483,648〜2,147,483,647
 実数型  float  %f  (%e)   4   
 倍精度実数型  double  %e (%f)   8  多桁出力では、 %lf ではなく、 % 16.10f
のように指定する。 16.10 の 16が全桁数。
10が小数点以下の桁数であるが、全桁数はあまり
関係ないようである。(上の桁が多いと調整される)

※このほかに論理型などが有ります。また、型を修飾するものとして、

 long
 short
 unsigned

などを、前に付けることの出来る型もあります。

(例)
  unsigned int      符号無し整数(0と正の整数だけ)  0〜65535

 変数を、整数型で宣言すると、小数以下の結果は、切り捨て(或いは四捨五入)されます。


 整数型変数 = 実数型変数

のように、型の違う変数どうしの演算では、代入される側の変数の型に合わせられます
 従って、演算を整数型で行い、結果を実数型に入れる場合などは注意が必要です。


Project0201

int _tmain(int argc, _TCHAR* argv[])
{
    int a,b,c,d;
    a = 10;
    b = 3;
    c = a / b;
    d = c * b;
    printf( "a = %d b = %d c = %d d = %d\n", a, b, c, d );

    getchar();
    return 0;
}



 同じ計算を、浮動小数点型で行ってみます。出力を浮動小数点型にした場合と、指数型にした場合の両方を試してみます。

Project0202


int _tmain(int argc, _TCHAR* argv[])
{
    float a,b,c,d;
    a = 10.0;
    b = 3.0;
    c = a / b;
    d = c * b;
        printf( "a = %f b = %f c = %f d = %f\n", a, b, c, d );
        printf( "a = %e b = %e c = %e d = %e\n", a, b, c, d );

    getchar();
    return 0;
  }

 


 次のように、計算の時に整数型どうしの計算を行い、結果を実数型に入れる、というような場合は、注意が必要です。
 両方が整数の時は、結果が整数となりますが、どちらかが実数の時には実数となります。このことを、型の自動変換と言います。

Project0203


int _tmain(int argc, _TCHAR* argv[])

{
    int a,b;
    float c;
    a = 10;
    b = 3;
    c = a / b;
        printf( "a = %d b = %d c = %f\n", a, b, c );
    getchar();
    return 0;
}

 


 計算の時に、型を強制的に別の型に変換することが出来ます。このような演算を行うものを「キャスト演算子」といい、以下の例のように使用します。

Project0204


int _tmain(int argc, _TCHAR* argv[])
{
    int a,b;
    float c;
    a = 10;
    b = 3;
    c = (float) a / (float) b ;
        printf( "a = %d b = %d c = %f\n", a, b, c );
    getchar();
    return 0;
}

 


 整数型の変数を計算して、出力する例を示します。この例は、初期値を1として、順次それを2倍ずつにした数を、1000を越え無い範囲で出力します。

Project0205


int _tmain(int argc, _TCHAR* argv[])
{
    int number, count=0;
    for( number = 1; number <=1000; )
    {

// このプログラムは、そのままでも実行できるが、結果が1000以上まで表示されてしまう。
//以下のプログラムのうち、1行の入れる場所を変えなければならない。
//適切な場所を書き換えて実行してみなさい。

        number *= 2;
        count ++;
        printf( "%d %d\n" , count, number );
    }
    getchar();
    return 0;
}

 


 1文字を扱うには、文字型変数を宣言して使います。文字型変数に、文字を代入するには、 = の後に、文字を、 「’」(シングルコート) で囲って指定します。
 なお、文字型変数は、C言語の内部では、文字に割り当てられた1バイトの数値( 0〜255 )として扱われています。そのため、直接数値として出力したり、代入したりすることが出来ます。ただし、通常のアルファベットの他に特殊な動作を行わせる物があるので、数値として扱うときには注意が必要です。
 (なお、日本語は、通常2バイトを用いて表現する「2バイトコード」というもので表すが、この表現方法には、何種類かのものがあり、システムに依存するので注意が必要である。最近は、世界中の言語を表現する「ユニコード (UTF-8)」というものが標準化されているので、このコードを使うのが良いが、ユニコードは、文字の種類によって、バイト数が変化する(1バイトから6バイトまで)ので、注意が必要である。)

Project0206


int _tmain(int argc, _TCHAR* argv[])
{
    char c;
    c = 'A';
        printf("%c %d\n", c, c);
    c = 'B';
        printf("%c %d\n", c, c);
    c = 65;
        printf("%c %d\n", c, c);
    getchar();
    return 0;
}

 

(注) 上の様に、文字に直接数値を代入する方法はあまり勧められない。

 文字は、内部的には、数値で扱われるので、数値と同様に、演算を行う事ができます。アルファベットなどは、順番に並んでいます。文字に対応した数値を、「アスキーコード」と言います。

Project0207


int _tmain(int argc, _TCHAR* argv[])
{
    char c;
    for ( c = 'A'; c <= 'Z'; c++ )
    {
        printf( "%c\t", c );
        printf( "%d\n", c );
    }
    getchar();
    return 0;
}

 



文字列を扱うときは、
char *s


という宣言を使います。


ただし、文字列を扱うのは若干注意が必要です。
まずは、一例を示します。

Project0208


int _tmain(int argc, _TCHAR* argv[])
{

// 宣言と内容の設定を同時にやるときは以下のようにする。こうやって宣言された文字列は 「書き直しできない」

    char *s="Tokyo Kougei Univ 東京工芸大学";
        printf("%s\n",s);

// 宣言と内容の設定を別にやるときは以下のようにする。こうやって宣言された文字列は 「書き直せる」が、変数への文字列の代入時に、*をつけてはいけない。

    char *s2;
     s2 = "基礎プログラミング"; 
     printf("%s\n",s2);

//この場合は内容書き換えができます。
     s2 = "実習室026"; 
     printf("%s\n",s2);

//  以下のようにするとエラーになる  (ここを書き直して結果の報告にする)
//  char *s3;
//  *s3 = "基礎プログラミング";     
//        printf("%s\n",s3);

        printf("%s\n",s);


    getchar();
    return 0;
}

 


 ここでは、文字列 "Tokyo Kougei Univ." という文字列を、文字型変数に代入していますが、前の例では、文字型変数には、1つの文字しか入れる事が出来なかったはずです。
 そこで、ここでは、 "*" という記号を用いて、 s という変数を、「文字型変数へのポインタ」という形式で宣言すると同時に内容の文字列を設定しています。この「ポインタ」というものについては、後日改めて説明しします。

(注意)文字列変数については、中の文字を書き換えることが出来るものと、書き換えられないものとがある。ここで用いた形式は、書き換えられないものである。無理に書き換えようとすると、プログラムが誤動作をすることがある。

 いままで扱った変数型が、それぞれ、何バイトを用いているのかを知るためには、C言語に備えられている " sizeof( ) " 関数を使用します。(繰り返すが、どの型が、何バイトを用いるかは、処理系依存である。)


主要な処理系では、次のバイト数を用いています。
char = 1 byte
int = 4 (2) byte
float = 4 byte
double = 8 byte

Project0209


int _tmain(int argc, _TCHAR* argv[])
{
    printf("char = %d byte\n",sizeof(char));
    printf("int = %d byte\n",sizeof(int));

    getchar();
    return 0;
}

 


 整数型で扱える数値には、上限、下限があります。
 たとえば、4バイトで扱える整数は、正負の数で、
-2,147,483,648〜2,147,483,647
 の範囲です。
 2バイトですと、
-32,768〜32,767
 になります。
 整数のバイト数は処理系に依存しますので、プログラム上不都合が生じないように、どちらを使うか明確にするためには、 int 型のかわりに、 long (4バイト) short (2バイト) を指定します。

 整数型の場合は、演算中にこの範囲を越えると奇妙なことが起こります。正の数をどんどん大きくしていったはずなのに、最大値を越えると、負の数になってしまう、と言うような事が起こります。(場合によっては、エラーとなる場合もある。)
 その理由については、教室で説明します。

 この説明は、演習問題の最後で報告することになって居ますので、必ず、書き留めておいてください。

Project0210


int _tmain(int argc, _TCHAR* argv[])
{
    short i;
    for( i = 1; i >0; i *=2)
    {
i *=2
        printf( "%d\n" , i );
    }
    getchar();
    return 0;
}

 


文字列の簡単な入出力 cin cout


第7回に詳しい解説がありますが、次のようにします。

たとえば、
Project0201

 を、次のように変更します。(赤字部分)


// cout を使うためには、以下の2行を入れる。
#include <iostream>
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
    int a,b,c,d;
    a = 10;
    b = 3;
    c = a / b;
    d = c * b;
//    printf( "a = %d b = %d c = %d d = %d\n", a, b, c, d );
    cout << a; cout << b; cout << c; cout << d;

    getchar();
    return 0;
}



cout を使うと、「とりあえず出力」ができますが、数字の間隔をそろえたりするためには、特別な制御コマンドを入れなければなりません。(それでもたぶん、 printf() よりは簡単です。)詳細は第7回を参照。











【演習】


 メールの1、2行目に、学籍番号と、氏名を書いてから、以下の演習に対する解答などを書きなさい。

メールの先頭には毎回、
学籍番号
氏名

を書くこと。


【注意】以下のプログラムで、実行中に、長時間表示が停止してしまったり、逆に、表示が出続けて止まらなくなったときには、 CTRL キーと C を同時に押して、実行を停止しなさい。



【課題1−4】

 メールのタイトルを "Project0201" などとします。

 上に掲げた Project0201 〜 0204
 を入力して実行し,

 プログラムの主要部分と、その実行結果の表示部分のコピー(方法は、第1回目に解説必要ならこのリンクを読むをメールに貼り付けて送りなさい。



 ただし、各プログラムとも、このページに書かれている例題を入力実行後、以下の指示のように手直しをしてから、実行し、それをコピーすること。

■Project0201
  a = 20; と書き直して実行し、
結果から、整数型の演算結果は、切り捨てになるか、四捨五入になるかを考察して、どちらになるかを答えなさい。

■Project0202
 a=12.3456789;
 b=1.23456789;

と書き直して実行し、a,bは、それぞれ、
   小数点以下、何桁まで表示されたか
   有効数字は、小数以下何桁か答えなさい。

(Printf 文の書式設定の %d などを適切な設定に変更すること。)


■Project0203
 変数 a,bのどちらかを  float 型宣言に変更
して実行し、

   c の出力が、
   小数点以下、何桁まで正しく表示されたか
   有効数字は、小数以下何桁か答えなさい。

■Project0204
    a = 33.3333;
と変更して実行して見なさい。正しく期待通りの答え(11.1111)が表示されるように、必要な場所に変更を加えて実行しなさい。





【課題5−8】

 上に掲げた Project0205 〜 0208
 を入力して実行し,

 プログラムの主要部分と、その実行結果の表示部分のコピー(方法は、第1回目に解説必要ならこのリンクを読むをメールに貼り付けて送りなさい。



 ただし、各プログラムとも、このページに書かれている例題を入力実行後、以下の指示のように手直しをしてから、実行し、それをコピーすること。

Project0205

  for ループの部分を、以下のように書き直します。

for( number = 1; number <=1000;number *= 2 )
    {
        count ++;
        printf( "%d %d\n" , count, number );
    }


 プログラムと、その実行結果をコピペし、
 最初の表示とどこが違ったか答えなさい。


■Project0206
    c = 65;

を、
    c = 'D' - 'A' + 'a';
と書き直して実行してみなさい。


 プログラムと、その実行結果をコピペし、
 ここで、 -'A' + 'a'
 の部分は、何を意味しているか説明しなさい。(ヒント、アスキーコード)


■Project0207
 小文字の、 'a' 〜 'z' を逆順で(つまり、 z y x ... b a のように)出力するプログラムにしなさい。
 プログラムと、その実行結果をコピペしなさい。


■Project0208


 プログラム中の、
//  以下のようにするとエラーになる  (ここを書き直して結果の報告にする)
 に続く3行のコメントをはずし (//を消す) 実行して見なさい。
 エラーとなるはずです。エラーにならずに、ちゃんと文字列が表示されるように、必要な場所を書き直し、
 プログラムと、その実行結果をコピペしなさい。



【課題9−10】

 上に掲げた Project0209 〜 0210
 を入力して実行し,

 プログラムと、その実行結果をコピペし、
 プログラムの主要部分と、その実行結果の表示部分のコピー(方法は、第1回目に解説必要ならこのリンクを読むをメールに貼り付けて送りなさい。

■Project0209

 で、 float型と double型についても、何バイトか表示するように書き加え、
 プログラムと、その実行結果をコピペし、
 それぞれ、何バイトだったか書きなさい。

■Projet0210
実行すると、ある数を超えると、正の数から負の数に表示が変わって終了する。
本当なら、i の値は大きくなり続けて、終了しないはずである。

 プログラムと、その実行結果をコピペし、
 正の数から、負の数に変わったときの、正の数を答え、
 なぜ、数値を加え続けたにもかかわらず、あるところで、負の数になったのかを考察して書きなさい。






【応用課題11−12】

 これは、補充課題です。余裕があればやってみましょう。(やらなくても構いません。)

 出来たところまで、画面表示をコピーして メール "Project0211" として出してください。


● Project0211

 1 + 1/2 + 1/3 + 。。。 + 1/10 

 の値を、出来るだけ正確に求めて表示しなさい。


● Project0212

 文字を AaBbCc....Zz    のように表示するプログラムを作りなさい。(勿論、プログラムに全部並べて書くのではなく、繰り返しを使う。)




 以上です。


先週の課題の解答例


演習課題1】

 プロジェクト名  "Project0101"

 画面上に、整数の1から10までを表示するプログラムを作りなさい。





【演習課題2】

 新規プロジェクトを、  "Project0102" という名前で開きなさい。

 画面上に、次のように、 "*" が、1つから、5個まで並んだものが表示されるプログラムを作りなさい。

 
*
**
***
****
*****




inserted by FC2 system inserted by FC2 system