第 1 回 復習

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

1-1. この講義について

この講義では C 言語を使って、データ構造とアルゴリズムについ て学びます。 処理系はマイクロソフト Visual Studio を使います。

C++ は複雑ですので、この講義には向きません。 C 言語に特化して講義しま す。

1-2. Visual Studio C++ について

本講義では簡単のため、主にコンソールアプリケーションを作ります。 Visual Studio C++ では次のようにします。

  1. まず Visual Studio 2010 を立ち上げます。 「スタート」→「すべてのプログラム」→「Microsoft Visual Studio 2010」→「Microsoft Visual Studio 2010」で起動 します。
  2. 一つの実行可能なプログラムを作るために、プロジェクトを次のように毎 回用意します。
  3. 「ファイル」→「新規作成」→「プロジェクト」
  4. 「新しいプロジェクト」ダイアログで、プロジェクトの種類は「Visual C++」を選び、テンプレートは「コンソールプロジェクト」を選びます。 プロジェクト名は適当につけて下さい。 場所は「参照」を選び「デスクトップ」→「コンピュータ」→「D:」を使 用して下さい。 H: では正常に動作しません(20040916)。
  5. アプリケーションウィザードで「次へ」を押します(完了を押さないよう に)。
  6. アプリケーションの種類を「コンソール アプリケーション」に、追加のオ プションを「空のプロジェクト」にチェックをつける。
  7. 完了を選びます。
  8. もし、ソリューションエクスプローラが表示されてなければ、「表示」→ 「ソリューションエクスプローラ」でソリューションエクスプローラを表示さ せておきます。
  9. ソリューションエクスプローラ中の「ソースファイル」を右クリックして、 出てきたメニューに対して、「追加」→「新しい項目の追加」を選びます。
  10. 出てきた「新しい項目の追加」ダイアログで、テンプレートで「C++ ファ イル」を指定し、ファイル名に「hello.c」など作成したい C 言語のファイル 名をそのまま入れ、「追加」ボタンを押します。
  11. 画面にそのファイルの入力欄が出てきたらプログラムを書き込みます。
  12. プログラムの入力が終ったら、「ビルド」→「ソリューションのビルド」 でコンパイルし実行ファイルを作ります。
  13. 「デバッグ」→「デバッグなしで開始」でプログラムを実行します。

なお、「プロジェクト」→「○○(プロジェクト名)のプロパティ」でプロ パティページを開き、次のように設定すべきですが、しなくても通常問題あり ません。

演習1-1

次のプログラムを実行させなさい。

#include <stdio.h>
main(){
  printf("Hello World\n");
}

1-3. C 言語の基礎

プログラムの全体の構造

C 言語のプログラムは最後が「.c」で終るテキストファイルに書きます。

構造1

#include <stdio.h>
main(){
  ここに文を書く
}

構造2

#include <stdio.h>
#include <math.h>
main(){
  ここに文を書く
}

構造 2 は平方根 sqrt() や三角関数 sin() など数学的な関数を使用する時だ け使い、通常は構造 1 を使います。

文はセミコロン「;」で区切ります。

またプログラムの任意の場所に /* で始まり */ で終るコメントを書くことが できます。

プログラムの組み立て

プログラムは宣言をするところと、手順を記述するところにわけることができ ます。

構造3

#include <stdio.h>
main(){
  宣言

  手順
}

宣言

宣言とは変数の登録をすることです。 変数には型と名前があります。 型は文字型 char、整数型 int、単精度浮動小数点型 float、倍精度浮動小数 点型 double があります。 名前は英字で始まる任意の英数字の列を使用できます。


int i,j;
float kotae1,kotae2;
char a,b,c;

また、通常の変数の他に配列変数を扱うこともできます。 これは、数学で扱う数列 a0, a1 のように、添字の番 号を指定して a[0], a[1] のように値を呼び出すことができます。 宣言する時は使用する数を与える必要があります。 但し、添字は 0 から始まりますので、5 個の配列を宣言した時、使用できる 添字は 0,1,2,3,4 になります。 手続き中の配列変数の添字には整数型の変数を使用することもできます。


int x[3]; /* 使用できる変数名は x[0], x[1], x[2] */
char word[2]; /* 使用できる変数名は word[0], word[1] */

宣言では変数の最初の値(初期値)を与えることができます。 文字型とは文字一文字のことで、文字型の定数を表すにはシングルクォーテー ションマーク「' '」で括ります。 なお、改行記号は '\n' で表します。 配列変数では 0 番目の値から順に { } の中にカンマで区切って与えることが できます。{ } で値を与える場合、使用する配列の数を与えなくても良いです。


int i=0;
char a='x', b='\n';
float y[2]={1.3 , 3.5}; /* y[0]=1.3, y[1]=3.5 */
int k[]={3, 2, 1}; /* k[0]=3, k[1]=2, k[2]=1 */

文字型の配列変数は文字列を使用するのに使うことができます。 その場合、文字列の最後に必ず特別な文字 '\0' を入れる必要があります。 また、文字型の配列変数の初期化には上記のような { } を使用する代わりに、 文字列を " " で括る方法もあります。この場合最後に自動的に '\0' が割り 当てられます。


char x[]="abc"; /* x[0]='a', x[1]='b', x[2]='c', x[3]='\0' */

手順

本講義では手順として次のものを取り上げます。

  1. 代入文
  2. printf
  3. if
  4. while

代入文

代入文は「変数名 = 式」という形式で書き、式の値が変数に入ります。 ですから、「 i = i+1 」という代入文では i+1 の値が i に入りますから、 i の値が 1 増えます。 式には通常の四則演算の他、数学関数も使用できます。 但し、演算の優先順位を与えるカッコは丸カッコ ( ) しか使用できません。 また、変数を含む式は変数の型が考慮されます。整数型の変数 a,b にそれぞ れ 7,2 が入っていた時、 a/b の結果は整数型に直され、3 になります。 なお、 a を b で割った余りを求めるには a % b と書きます。


a = ((1+2)*3+4)*5;
x[2] = sqrt(y[1]);

C 言語ではあらゆるものが値を持ちます。代入文自体も代入された値を値とし て持つので、次のような記法が可能になります。


i=j=0;

C 言語独特の記法として代入演算子やインクリメント、デクリメントがありま す。代入演算子「変数 += 式」は式の値だけ左辺の変数を増やすという意味に なります。また、インクリメント、デクリメントは i++, --i などで、それぞ れ i が 1 ずつ増減します。但し、++, -- が先頭に来る場合の式の値は増え た後の値になりますが、後に来る場合は式の値は増える前の値になります。


s+=a[i];              /* s=s+a[i]; と同じ */
--j;                  /* j=j-1; と同じ */
z[i++]=y[j++];        /* z[i]=y[j];i=i+1;j=j+1;z[i-1]; と同じ */

printf

標準出力に文字を出力するのが printf です。指定した文字を出力するだけで なく、変数の内容も表示できます。 printf の最初の引数は文字列で、基本的にはその内容が表示されます。


printf("Hello World\n");

文字列の中に 「%+文字」 が含まれると、その位置に変数の値が表示されます。 文字型変数には %c, 整数型変数には %d, 浮動小数点型には(float も double も) %f を使用します。


char x='a';
int y=5;
float z=6.2;
printf("変数 x の値は %c",x);
printf("変数 y の値は %d, 変数 z の値は %f",y,z);

文字型の配列変数の内容を全て表示するには %s を使用します。 但し、配列の最後には '\0' が割り当てられている必要があります。


char x[]="abc"; /* x[0]='a', x[1]='b', x[2]='c', x[3]='\0' */
printf("配列変数 x には文字列 %s が入っている",x);

if

if 文には次の二つの構文があります。


if(条件){文1;}
if(条件){文2;}else{文3;}

始めの構文は条件が成立する時(0 でない時)だけ文1を実行し、成立しなかっ た時(0 だった時)はなにもしません。 二番目の構文は条件が成立する時(0 でない時)は文2を実行し、成立しなかっ た時(0 だった時)は文3を実行します。


if(0){y=1;}              /* 何もしない */
if(1){y=1;}              /* y=1; と同じ */
if(x){y=1;}else{y=2;}    /* x が 0 でない時 y=1; x が 0 の時 y=2; */

条件式

二つの値を比較をする条件式には次の書き方があります。

a == b
a と b は等しい
a != b
a と b は等しくない
a < b
a は b より小さい
a > b
a は b より大きい
a <= b
a は b 以下
a >= b
a は b 以上

これらの値は条件が成立すれば 1、成立しなければ 0 になります。


if(x>max){max=x;}

if(b==0){printf("全ての値\n");}
else{printf("解なし\n");}

二つの条件式を一つにまとめるため次の書き方があります。

(A) && (B)
A と B の両方が成り立つ(両方が 0 でない)
(A)||(B)
A か B のどちらかが成り立つ(どちらかが 0 でない)
!(A)
A が成り立たない(A が 0 である)

if((a==0)&&(b!=0)){printf("解なし");}
if((a!=0)||(b!=0)){x=-b/a;}

while

while 文の構文は if と良く似ています。


while(条件){文;}

「条件を調べて、成立すれば文を実行する」というのを繰り返します。 適切な回数だけ繰り返させるためには何らかのアルゴリズムが必要になります。

なお、for 文は while 文を読みやすくするために導入された別の書き方です。 次の for と while は同じ意味になります。


for(A;B;C){
  D;
}


A;
while(B){
  D;
  C;
}

for(i=0;i<3;i++){
  printf("あ");
}

i=0;
while(i<3){
  printf("あ");
  i++;;
}

#define

#define を使用すると、定数を使用することができます(実際はマクロの定義)。 次のように使用します。


#include <stdio.h>
#define N 3
main(){
  int x[N]={7, 3, 4};
  int i;

  for(i=0;i<N;++i){
    printf("%d\n",x[i]);
  }
}

1-4. プログラム例

  1. 
    #include <stdio.h>
    main(){
      printf("Hello World!\n");
    }
    
  2. 
    #include <stdio.h>
    main(){
      int a=1;
      float b=3.14;
      char c='a';
      char d[]="bcdef";
      printf("%d %f %c %s\n",a,b,c,d);
    }
    
  3. 
    #include <stdio.h>
    #include <math.h>
    main(){
      float a=2,b=3,c=1;
      float d,x1,x2;
      printf("%f x^2 + %f x + %f = 0 の解は",a,b,c);
      d=b*b-4*a*c;
      if(d>0){
        x1=(-b+sqrt(d))/2/a;
        x2=(-b-sqrt(d))/2/a;
        printf("%f , %f \n",x1,x2);
      }else if(d==0){
        x1=-b/2/a;
        printf("%f\n",x1);
      }else{
        x1=-b/2/a;
        x2=sqrt(-d)/2/a;
        printf("%f±%fi\n",x1,x2);
      }
    }
    
  4. 
    #include <stdio.h>
    #define N 10
    main(){
      int i,j;
      for(i=0;i<N;i++){
        for(j=0;j<N;j++){
          printf("〇");
        }
        printf("\n");
      }
    }
    

演習1-2

上のプログラム例 4 を改造して次を表示するプログラムを作りなさい。

  1. 〇〇〇〇〇
    〇〇〇〇
    〇〇〇
    〇〇
    〇
    
  2.    〇
      〇〇〇
     〇〇〇〇〇
    〇〇〇〇〇〇〇
    
  3. 〇〇〇〇〇
    〇   〇
    〇   〇
    〇   〇
    〇〇〇〇〇
    

坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科