C programming (5) operator and operand

C言語の特徴(2)

関数型言語

コンピュータに実行してもらう命令はすべて関数の中に記述されている。関数がプログラムの実行単位。いくつかの関数を組み合わせ、コンピュータへ命令をする。最初にコンピュータが実行する関数はmain()に決まっている。

戻り値の型 関数名(引数リスト)
{
	命令文;
}

命令文(Statement)

  • 名札付き文
  • 式文
  • 複合文
  • 選択文
  • 繰り返し文
  • ジャンプ文

式(Expression)

オペランド 演算子 オペランド...

トークン(token)

コンパイラが認識する最小単位のテキスト、トークン(token)

  • キーワード
  • 識別子
  • 定数
  • リテラル文字列
  • 演算子
  • 区切り子
#include <stdio.h>

int main() {
  printf("Hello World\n");
  return 0;
}
トークンに分解
トークン トークンの種類
int キーワード
main 識別子
( 区切り子
) 区切り子
{ 区切り子
printf 識別子
( 演算子
“Hello World\n” リテラル文字列
) 演算子
; 区切り子
return キーワード
0 定数
; 区切り子
} 区切り子

トークンの間に演算子や区切り子、または空白文字で区切りする

空白文字とは、次のいずれかの文字のことを表します。

  • スペース
  • 水平及び垂直タブ
  • 改行
  • 改ページ
  • コメント

注釈(コメント)(Comment)

/* 一行コメント1 */
// 一行コメント2

/*
main.c
山田 太郎
2012年10月25日 作成
*/

/***********************/
/* main.c              */
/* 山田 太郎           */
/* 2012年10月25日 作成  */
/***********************/

// main.c
// 山田 太郎
// 2012年10月25日 作成

演算子

算術演算子

演算子 意味
+ 加算
減算
* 乗算
/ 除算
% 剰余(余り)

代入演算子

=  代入(Assignment)

複合代入演算子

演算子 意味
+= 加算代入
-= 減算代入
*= 乗算代入
/= 除算代入
%= 剰余代入

x = x + 5;

x += 5;

入力計算例

#include <stdio.h>

int main(void)
{
  int DH, ON, wa, sa, se, sh, am;
  
  printf("1つ目の数字入力:");
  scanf("%d", &DH);
  printf("2つ目の数字入力:");
  scanf("%d", &ON);
  
  wa = DH + ON;
  sa = DH - ON;
  se = DH * ON;
  sh = DH / ON;
  am = DH % ON;
  
  printf("%d+%d=%d\n",DH, ON, wa);
  printf("%d-%d=%d\n",DH, ON, sa);
  printf("%d*%d=%d\n",DH, ON, se);
  printf("%d/%d=%d...%d\n", DH, ON, sh, am);
  
  getch();
  return 0;
}

出力結果:

1つ目の数字入力:60
2つ目の数字入力:20
60+20=80
60-20=40
60*20=1200 
60/20=3...0

演習

西暦年→和暦変換するプログラムを作る

実行例:

西暦: 2016
和暦: 平成28年です

 

C exercises (4) math and utility

数学関数

数学的な計算が必要な場合に使用する命令セットです。引数と返りは全てdouble型になります。

主なもの:

  • sin(x):角度x(ラジアン)のsinの値を返す
  • cos(x):角度x(ラジアン)のcosの値を返す
  • tan(x):角度x(ラジアン)のtanの値を返す
  • pow(x,y):xのy乗の値を返す
  • exp(x):指数関数eのx乗の値を返す
  • log(x):xの自然対数の値を返す
  • log10(x):xの常用対数の値を返す
  • sqrt(x):xの平方根の値を返す
  • ceil(x):小数第一位を切り捨てした値を返す
  • floor(x):小数第一位を切り上げした値を返す
  • round(x):小数第一位を四捨五入した値を返す

サンプル:

#include <stdio.h>
#include <math.h>     //math.hのインクルードを忘れずに
 
int main(int argc, const char * argv[])
{
     
    // insert code here...
    double value = 0.5;
    printf("sin : %f\n", sin(value)); 
    printf("sqrt : %f\n", sqrt(value));
    printf("ceil : %d\n", (int)ceil(value));
    printf("floor : %d\n", (int)floor(value));
         
    return 0;
}

 文字列を数値型に変換する関数

文字列を数値型にするときに使われる関数がatoi関数(整数型に変換する場合)とatof関数(小数型に変換する場合)があります。

サンプル:

#include <stdio.h>
#include <stdlib.h>       //stdlib.hのインクルードを忘れずに
 
int main(int argc, const char * argv[])
{
     
    // insert code here...
    char a[] = "20";
    char b[] = "30";
     
    printf("(cast) a + b = %d\n", (int)a + (int)b);
    printf("(atoi) a + b = %d\n", atoi(a) + atoi(b));
     
    return 0;
}

 乱数を取得する関数

  • rand() 関数 :乱数を得る (0 .. RAND_MAX)
  • srand() 関数 : 乱数を生成するためのシードを設定する

サンプル:

サイコロの目1..6 をランダムに生成

#include <stdio.h>
#include <stdlib.h>
#include <time.h>     //time関数を使うので
 
int main(int argc, const char * argv[])
{
     
    // insert code here...
    int i;
    printf("///乱数の最大値 = %d///\n" , RAND_MAX);
 
    // 現在時刻を種に設定する
    srand((unsigned)time(NULL));
     
    for(i = 0; i < 5; i++) {
        // 乱数を取得する
        int randValue;
        double randValue1;
        randValue = rand();
        randValue1 = randValue / (double)(unsigned)(RAND_MAX + 1);
        printf("サイコロの目 : %d\n", (randValue % 6 + 1));
    }
     
    return 0;
}
練習問題:
========
0.0 .. 1.0 の数を6個ランダムに生成する

 

C# exercises (4) Slot machine

Visual Studio community 2015 アカウントについて (学内専用)

スロットマシンの作成

Slot machine

スロットのプログラムに必要な3つの部品

  • 数字を表示させるための部品
    •   → ラベル (Labelコントロール)
  • スロットを開始するための部品
    •   → ボタン (Buttonコントロール)
  • 数字の書き換えを短い間隔で行うため、その間隔を計るための部品
    •   → タイマー (Timerコントロール)

これらの部品はツールボックスに入っている

デザイン

部品の貼り付け

slot2

文字の大きさの変更

フォントの大きさを72ポイント程度にする

プログラム

コントロールとプログラムの関係

  • コントロールに対して何かをすると、イベントが発生する
    • イベントに対応したプログラムを作成する
  • フォーム上のボタン(button1)をダブルクリックすると、ボタンをクリックしたときに発生するイベントに対応したプログラム(button1_Click)が自動的に生成される

slot3

Timerコントロール

一定の間隔で処理をさせたいときに使う

  • timer1:Timerコントロールの変数名
  • Start()はタイマーを開始する命令
  • Intervalに設定している間隔で、定期的にtimer1_Tick()を発生させる
  • Intervalプロパティに設定する時間はミリ秒単位
    • Intervalプロパティに100を設定すると、100ミリ秒(0.1秒)ごとにtimer1_Tick()が呼ばれる

乱数を生成するイベントのプログラムの作成

0以上10未満の乱数を生成する

Timerコントロールをダブルクリック

  • –フォームの下に貼り付いているTimerコントロールをダブルクリックすると、自動的にtimer1_Tickというイベントのプログラムが生成される
  • –その中に、以下のプログラムを書く
  • –Next()命令により、0以上10未満の乱数を生成する
  • –それをLabelコントロールのTextプロパティに代入する
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DigitalClock
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = DateTime.Now.ToLongTimeString();
            Random random = new Random();
            label1.Text = random.Next(10).ToString();
        }
    }
}

実行してみる

スクリーンショット 2016-05-12 14.55.35

機能追加

音声を追加

  • 一番最初に、using System.Media; を追加
  • button1_Clickイベントの{ } の中に
SoundPlayer sound = new SoundPlayer(@“ファイル名”);
sound.Play();

(ファイル名の指定で、””の前に@を書くと、\を2つ書かなくても良くなる)

停止機能

ボタン(開始/停止)機能

 

C言語勉強関連サイト

プログラミング言語の基礎を簡単に楽しく学べるサイト

プログラミング学習サイト

  • http://dotinstall.com/ — 講義型のプログラミング学習サイト
  • http://paiza.jp — 用意された問題を解くとプログラミングスキルを6段階に評価してくれるサービスです
  • http://judge.u-aizu.ac.jp/onlinejudge/index.jsp?lang=ja — 会津大学が提供しているプログラミング問題サイトです。お題に対して問題を解いていく形式で、提出したプログラムをオンラインで採点してくれます。
  • https://www.codeeval.com/ — 約150問程度のプログラミング問題(初級、中級、上級)が掲載されており、点数が良いと海外の企業からスカウトが来るサービスです。

オンラインコンパイラ

C言語入門

参考

C# exercises (3) Common Control

ディジタル時計の作成

Create Digital Clock

デザイン

ツールボックスの中で、

  • –コモンコントロール「TextBox」
  • –コンポーネント「Timer」

Formにドラッグ&ドロップする

スクリーンショット 2016-05-02 15.27.53

Timerのプロパティ(値)を変更

スクリーンショット 2016-05-02 15.28.49

timer1のプロパティ

  • Enabled⇒ True (Enabled:タイマーを実行する)
  • Interval⇒ 1000 (Interval:タイマーの実行間隔, 1000⇒1000ms(1秒))

 

TextBoxのプロパティ

  • Font :36ポイント –文字のサイズ⇒好きなサイズに
  • ForeColor :緑 –文字の色⇒好きな色に
  • BackColor :ブラック –TextBoxの背景色⇒好きな色に
  • TextAlign :Center –文字を表示する場所⇒真ん中(Center)
  • Text: 00:00:00 –表示する文字列⇒最初は00時00分00秒をあらわす

 

スクリーンショット 2016-05-02 15.34.31

 

ディジタル時計の完成

timer1をダブルクリックすると、timer処理に関する関数(メソッド)が自動生成される

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DigitalClock
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            textBox1.Text = DateTime.Now.ToLongTimeString();
        }
    }
}

 

現在の時間をテキストボックスに表示コードの追加

スクリーンショット 2016-05-02 15.44.58

 

C programming (4) puts and scanf

puts関数:表示を行う関数

書式化の必要がなく、改行もしたいの場合

puts(“ABC”);
printf(“ABC\n”);

 

scanf関数:読込みを行う関数

scanf関数は、処理の途中でキーボードから文字の入力を求め、入力されたものを処理に利用するというものです。

実例:

#include <stdio.h>
 
int main(int argc, const char * argv[])
{
     
    // insert code here...
    int input;
     
    printf("数字を入力して下さい。\n");
     
    scanf("%d", &input);
     
    printf("入力された数字は、%dです。\n", input);
    
    getch(); 
    return 0;
}

 

実行例:

数字を入力して下さい。
3
入力された数字は、3です。

  1.  テキストが出力され
  2. キーボードからの入力待ちの状態。入力してエンターキーを押しますと処理が再開
  3. 書式付き出力

scanfの2番目の引数に変数を指定する際は、「&(変数名)」というように「&」をつけてポインタとして扱って下さい。そういうルールだと思っていただいて構いません。

実践レベルの問題を考えれば、実は scanf() 関数が使われることは滅多にありません。理由はエラーチェックが十分にできないからです。十分なエラーチェックを行う必要がある入力は(商用のプログラムは十分なエラーチェックが必要であり、結果として本格的なプログラムには scanf() をあまり使わない)変換作業を行わずに、他の標準入力関数を用いて文字列として入力された情報を受け取り、入力された文字列を調べて適切な値に変換するというような作業を行います。もちろんこれらの作業は複雑になります。

Nim game

Nim game

ニム (nim) は、2人で行うレクリエーション数学ゲームの1つである。ルーツは古代中国からあるとされ、16世紀初めの西欧で基本ルールが完成したが、名前については、一般的に1901年ハーバード大学のチャールズ・L.バウトン (Charles L. Bouton) によって名付けられたとされる。

ゲームルール:

一人1個か2個か3個か4個だけ取れて、交互にやっていって、
最後の1個の石を取った人が負けとなります。

#include <stdio.h>

int main(void)
{
  int i, stone, n=0, turn=0;
  char name[2][256];

  printf("Input players' names\n");

  printf("player 1:");
  gets(name[0]);
  printf("player 2:");
  gets(name[1]);

  printf("\nnumber of stones:");
  scanf("%d", &stone);

  while (stone > 0){
    printf("\nThere are %d stones.\n", stone);
    printf("%s's turn! Take some stones:", name[turn]);
    while (n < 1 || n > 4) scanf("%d", &n); //取る石の数を制限1..4
    stone -= n;
    turn = 1 - turn;
    n = 0;
  }

  printf("\nNow winner is %s!!\n", name[turn]);

  // getch();
  // return 0;
}

課題

勝者の名前、対戦記録をファイルに記録するように改造してください。記録ファイル名は、nim.scrとする。
例:
====================================
Input players’ names
player 1:tom
player 2:mary

Now winner is mary!!
====================================
nim.c、nim.scr と実行画面のコピーを提出してください。

C exercises (3) string and ctype

標準ライブラリ関数 : 文字列操作関数

string.hのヘッダファイルをincludeする

主なもの:

strcpy(ss,st):文字列(文字型の配列)ssに文字列stをコピーする
strlen(st):文字列stの長さを求める
strcat(ss,st):文字列ssの後ろに文字列stを連結する
strncpy(ss,st,n):文字列ssに文字列stの先頭n文字をコピーする
strncat(ss,st,n)文字列ssの後ろに文字列stの先頭n文字を連結する

サンプル:

#include <stdio.h>
#include <string.h>       //string.hのインクルードを忘れずに
 
int main(int argc, const char * argv[])
{
     
    // insert code here...
    char str[40];
    char alpha1[] = "ABCDE";
    char alpha2[] = "VWXYZ";
    int length;
     
    printf("alpha1 : %s\n", alpha1);
    printf("alpha2 : %s\n", alpha2);
     
    strcpy(str, alpha1);
    strcat(str, alpha2);
    printf("str : %s\n", str);
     
    length = (int)strlen(str);
    printf("str's length : %d\n", length);
         
    return 0;
}

実行結果:

alpha1 : ABCDE
alpha2 : VWXYZ
str : ABCDEVWXYZ
str’s length : 10

練習問題:
========
(1)文字列に自分の名前を代入して表示してみよう。
(2)(1)で自分の名前の長さの文字列の長さを表示してみよう。
実行例:
自分の名前を半角英数字で入力してください
[Daiichi Koudai]
私の名前はDaiichi Koudaiです
文字数は14です

ヒント:

  1. printf
  2. gets, scanf

標準ライブラリ関数 : 文字操作関数

ctype.hのヘッダファイルをinclude

主なもの:

isalnum(c):文字cが英数字(A-Z, a-z, 0-9)なら真を返す
isalpha(c):文字cが英文字(A-Z, a-z)なら真を返す
isdigit(c):文字cが数字(0-9)なら真を返す
islower(c):文字cが小文字(a-z)なら真を返す
isupper(c):文字cが大文字(A-Z)なら真を返す
tolower(c):文字cが大文字だった場合に小文字に変換して返す
toupper(c):文字cが小文字だった場合に大文字に変換して返す

サンプル:

#include <stdio.h>
#include <ctype.h>        //ctype.hのインクルードを忘れずに
 
int main(int argc, const char * argv[])
{
     
    // insert code here...
    char lo = 'a';
    char up = 'A';
     
    if(islower(lo)) {
        printf("%c を大文字変換 -> %c\n", lo, toupper(lo));
    }
     
    if(isupper(up)) {
        printf("%c を小文字変換 -> %c\n", up, tolower(up));
    }
     
    return 0;
}

実行結果:

a を大文字変換 -> A
A を小文字変換 -> a

練習問題:
(3)(1)で自分の名前を大文字で表示してみよう。
実行例:
自分の名前を半角英数字で入力してください
Daiichi Koudai
私の名前はDAIICHI KOUDAIです
文字数は14です

ヒント:

  1. http://chenlab.net/2016/04/18/c-exercises-2-stdio/

回答:

#include <stdio.h>
#include <ctype.h>        //ctype.hのインクルードを忘れずに
#include <string.h>       //string.hのインクルードを忘れずに
 
int main(int argc, const char * argv[])
{
     
    // insert code here...

  char name[128];
  int i;
  
  printf("自分の名前を半角英数字で入力してください");
  gets(name);
  
    for (i = 0; name[i] != '\0'; i++) 
    {
        name[i] = toupper(name[i]); 
    }
  
    printf("私の名前は%sです\n", name);
    printf("文字数は%dです\n", (int)strlen(name));
    
  getch();
    return 0;
}

 

C programming (3) Veriables

変数と宣言 代入

int a, b;
a = 19;
b = -20;

変数初期化

int a = 1;
int b = 10;
int c = 4;

image

変数の演算

a = b + c;

image

(練習1)変数と宣言のサンプル

#include <stdio.h>
 
int main(int argc, const char * argv[])
{
     
    // insert code here...
    int a;
    int b;
    int result;
     
    a = 4;
    b = 2;
     
    result = 4 + 2;
    printf("4と2の和は %d\n", result);
     
    result = 4 - 2;
    printf("4と2の差は %d\n", result);
     
    result = 4 * 2;
    printf("4と2の積は %d\n", result);
     
    result = 4 / 2;
    printf("4と2の商は %d\n", result);
     
    result = 4 % 2;
    printf("4と2の余りは%d\n", result);
     
    return 0;
}

(練習2)printf関数:書式化して表示を行う関数

// test4.c 
#include <stdio.h>
int main(void ) 
{ 
 int a,b,c;
 /* これは加算のプログラム コメント
   名前:stdio.h
  C:\borland\bcc55\Include */
   a=3;   b=4;
   c=a+b;
   					
   printf("c= %d\n",c); /* Cの値を書式化して表示 */
   
   getchar( );
   return 0;
}

書式指定文字列:

「””」で囲まれた文字列のことを指します。

変換指定文字列:

  • %d 10進数で出力
  • %s 文字列として出力

拡張表記:

一般的にはエスケープシーケンスと呼ばれています。

エスケープシーケンス 意味
\n 改行
\t タブ
\0 文字列の終了を表す

C exercises (2) stdio

標準ライブラリ関数 : 標準入出力関数

標準入出力関数には(C言語プログラミング)で説明した printf() や scanf() の他にも 下のように 1文字専用の入出力関数と 1行専用の入出力関数が用意されている。

標準入力から文字入力 getchar 関数
標準出力から文字出力 putchar 関数
標準入力から文字列入力 gets 関数
標準出力から文字列出力 puts 関数
標準入力から書式付き入力 scanf 関数
標準出力から書式付き出力 printf 関数

標準入力関数(参考)

getchar() int getchar(void); 標準入力(キーボード)からの入力値を「EOF」まで1文字づつ取得します。エラー時は「EOF」を返します。
gets() char *gets(char *str); 標準入力(キーボード)からの入力値を「EOF」※1まで1行づつ取得して、その文字列の先頭アドレスを引数のchar型ポインタ(*str)に渡すと共に戻り値としても返します。エラー時は「EOF」を返します。
但し現在では読み込む長さを指定できる「fgets()」の使用が推奨されています。
fgets() char *fgets(const char *str, int n, FILE *stream); 「*stream」で示されるストリーム※2から「n-1」文字を取得し「\0」を付加して、その文字列の先頭アドレスを引数のchar型ポインタ(*str)に渡すと共に戻り値としても返します。
scanf() int scanf(char *format,…) ; 標準入力(キーボード)からの入力値を書式指定した文字列として取得します。
第2引数以降は書式指定文字列※3の変換指定子の数だけ変数を指定します。
戻り値は成功時には入力データの数を返し、失敗時はEOFを返します。

標準出力関数(参考)

fputc() int fputc(int c, FILE *stream); キャラクタ(ASCIIコード)c をストリーム※2に出力します。
putc() int putc(int c, FILE *stream); 「fputc」と同機能のマクロです。
putchar() int putchar(int c); キャラクタ(ASCIIコード)c を標準出力(画面出力)します。
fputs() int fputs(const char *str, FILE *stream); 文字列 s をストリーム※1に出力します。
puts() int puts(const char *str); 文字列 s を標準出力(画面出力)します。
fprintf() int fprintf(FILE *stream, const char *format,…); 書式指定文字列※2をストリームに出力します。
第2引数以降は出力元となる変数を変換指定子の数だけ指定します。
printf() int printf(const char *format,…); 書式指定文字列を標準出力(画面出力)します。
第2引数以降は出力元となる変数を変換指定子の数だけ指定します。

例題1:

キーボードから「Ctrl+Z」を入力することによりループを終了させることができます。

入力した数値を加算、「Ctrl+Z」を入力すると、集計を出力

#include <stdio.h>

void main(void)
{
  int n;
  int sum = 0;
  
  printf("整数を入力して下さい\t");
  while (scanf("%d", &n) != EOF) {	// …「Ctrl+Z が入力されるまで」という意味
  
    sum = sum + n;
  }
  printf("sum = %d\n", sum);

  fflush(stdin); 
  getchar(); 
}

例題2:

「Ctrl+Z」を押されるまで、文字列を入力し、入力した文字列のスペースの箇所で、改行して表示する。

/* a6-1-3.c */
#include <stdio.h>

int main(void)
{
  char str[256];
  int i;
                    // 
  puts("文字列を入力してください。(終了条件:Ctrl+Z)");
  while (gets(str) != NULL) 
  //gets(str);
  {	puts("入力文字列をスペースで改行して表示します。");
    for (i = 0; str[i] != '\0'; i++) 
    {	/* スペースで改行 */
      if (str[i] == ' ') 
        putchar('\n');
      /* スペース以外はそのまま表示 */ 
      else {
        putchar(str[i]);
      }
    }
    putchar('\n');
  }

  return 0;
}