Category Archives: C programming 2

C programming 2 (14) Exam

FizzBuzz 問題

1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

ちゃんとしたプログラマであれば、これを実行するプログラムを2分とかからずに紙に書き出せるはずだ。怖い事実を聞きたい? コンピュータサイエンス学科卒業生の過半数にはそれができないのだ。自称上級プログラマが答えを書くのに10-15分もかかっているのを見たこともある。

Problem

Print integers 1 to 100, but replace multiples of 3 with “Fizz” and multiples of 5 with “Buzz” and multiples of both with “FizzBuzz”
For longer description, see: http://tickletux.wordpress.com/2007/01/24/using-fizzbuzz-to-find-developers-who-grok-coding

http://golf.shinh.org/p.rb?FizzBuzz

C programming 2 (13) C言語3級検定演習2

プログラミング演習

1) Hello World プログラムを作成せよ

2) 乱数生成プログラムを作成せよ

【要件】
1. 乱数を5個生成し、生成した数値を画面出力せよ。
2. 生成する数値は1~34の範囲とする。
(rand 関数は0~65535 の乱数を生成するものとする。)
3. 5個の数値は重複してはいけない。
4. 画面出力イメージは以下とする。(1 桁の数値は頭に0 を付けて2 桁表示すること)

1 番目の数値はxx
2 番目の数値はxx
3 番目の数値はxx
4 番目の数値はxx
5 番目の数値はxx

検定試験シミュレーション

サーティファイ検定試験シミュレーションSite

http://www.kenteisiken.com/

「模擬検」には、体験版とチャレンジ版の2つの受験形式があります。

C言語プログラミング能力認定試験 3級
チャレンジ版で行ってください。

C programming 2 (12) C言語3級検定演習1

この一年間、教科書の1-7章まで勉強したので、C言語検定試験3級に挑戦することが可能になりました!

C言語検定試験について

試験名

C言語プログラミング能力認定試験
(C-Language Programming Skills Qualification Test)

http://www.sikaku.gr.jp/ 

試験目的

C言語を駆使して応用プログラム(言語処理系、ユーティリティなど)を作成する能力を認定します。

認定基準

一級 C言語を駆使し、応用プログラム(言語処理系、ユーティリティなど)が作成できる能力を有する。また使用しているOSについて理解をしている。
二級 小規模のプログラム(500行程度)が適切に(理路整然、簡潔、正しく、速く)書ける。また各種基本アルゴリズムを理解している。
三級 C言語の概念を理解し、簡単なプログラムが書ける。

参考(3級出題範囲)

出題内容
定数 整数定数 10進定数、8進定数、16進定数
整数接尾語は符号無し接尾語(u、U)のみ
文字定数 ワイド文字定数(L’c文字の列’)を除く
拡張表記は単純拡張表記のみ
文字列リテラル ワイド文字列リテラル(L”s文字の列”)を除く
拡張表記は単純拡張表記のみ
演算子 算術演算子、インクリメント演算子、デクリメント演算子、(算術の)代入演算子、関係演算子、等値演算子、論理関係演算子、括弧演算子、コンマ演算子
型指定子 char、int、unsigned、signed
変数
  • 上記型指定子の単純変数、配列
  • 初期化の構文
基本制御文 break、continue、do、for、if、return、switch、while
プリプロセッサ機能 #define、#include
ライブラリ関数
入出力関数<stdio.h>
EOF  NULL
int printf(const char *format, …);
int scanf(const char *format, …);
int getchar(void);  int putchar(int c);
文字操作関数<ctype.h>
int isalnum(int c);  int isalpha(int c);
int iscntrl(int c);  int isdigit(int c);
int isgraph(int c);  int islower(int c);
int isprint(int c);  int ispunct(int c);
int isspace(int c);  int isupper(int c);
int isxdigit(int c);  int tolower(int c);
int toupper(int c);
その他 Cの歴史と特徴

注)各級とも日本工業規格 (JIS) X3010 で出題・解答する。

LinkedIn(リンクトイン)

世界最大級のビジネスSNSLinkedIn(リンクトイン)」。2016年6月13日、MicrosoftがLinkedInを262億ドル(約2兆7770万円)買収することで合意した、と発表しました。

そんなLinkedInは、世界で4億人が使う、採用やネットワーク構築に活かせるビジネスSNSです。しかしまだまだ日本では「ハードルが高い」と思われている方も多いかもしれません。

しかしこのLinkedIn、きちんと使えばとっても役に立つと思います!

日本語にも対応していますし、要はSNSなので、難しいサービスでもありません。要はFacebookのビジネス版のようなものです。うまく使いこなせれば、色々なメリットがあります。

  • 履歴書・レジュメ代わり。ビジネスのための「自己紹介ツール」
    • 取得資格一覧
  • ビジネスに特化した、自分のつながり(人脈)を整理できる
  • 仕事に役立つ、リアルな情報を日々収集できる

C言語3級検定問題演習(1月11日)

Google Classroomを利用

https://classroom.google.com/

C programming 2 (11) Floating Types

浮動小数点型の指定

バイト数 ビット数 最小値 最大値
float 4 32 1.175494 10-38 3.402823 10+38
double 8 64 2.225074 10-308 1.797693 10+308

float型

float型は4バイト=32ビットのサイズを持ち,そのビットを次のように,符号,指数,仮数を表すために用いる.

float型の内部表現
指数部-127 が指数の値となる.仮数部は仮数の小数点以下を表している.すなわち,仮数は仮数部の先頭に 1. を付加したものになる.

float の表す値 = (-1)符号部 × 2指数部-127 × 1.仮数部

float 型の精度(有効桁数)は2進数にして 24 (=23+1) 桁であり,10進数では約 7 桁となる.

double 型

float 型に比べて,約倍の精度をもった浮動小数点型の型が double である. double 型は 8バイト=64ビットのサイズであり,その内部表現は次のようになる.

double型の内部表現
指数部-1023 が指数の値となる.仮数部は仮数の小数点以下を表している.すなわち,仮数は仮数部の先頭に 1. を付加したものになる.

double の表す値 = (-1)符号部 × 2指数部-1023 × 1.仮数部

double 型の精度(有効桁数)は2進数にして 53 (=52+1) 桁であり,10進数では約 15 桁となる.

演習

キャンパスの建物の直線距離を求めなさい

第一工業大学 東京上野キャンパス本館
〒110-0005 東京都台東区上野7丁目7−4
(@35.7138096,139.7760516,17z)

第一工業大学上野キャンパス2号館
〒110-0015 東京都台東区東上野4丁目26−5
(@35.7148652,139.7781931,17z)

第一工業大学3号館
〒110-0014 東京都台東区北上野1丁目7−4
(@35.7166289,139.7794262,17z)

ヒント:

  • Google map で経緯度を求める
  • 地球は1周で約4万km
  • 赤道の経度は1度が111km(40,000÷360)になる
  • 教科書List(7-10)参考
  • 1つ目の点の位置が x1, y1、2つ目の点の位置が x2, y2として
    #include <stdio.h>
    #include <math.h>
    
    main(void) {
       /* ... */
       long double x1 = 35.7138096;
       long double y1 = 139.7760516;
       long double x2 = 35.7148652;
       long double y2 = 139.7781931;
    
       dx = x2 - x1;
       dy = y2 - y1;
       distance = sqrt(dx * dx + dy * dy) * (40000000/360);
    }

     

  • 直角三角形の斜辺を求める定理(三平方の定理、ピタゴラスの定理とも呼ばれる)

 

C programming 2 (10) Bitwise

整数とビット演算

整数型(char、short int、long int)の場合、符号なし(unsigned)ではすべてのビットを数値の保存に使いますが、符号付き(signed)では先頭の1ビットを符号として使います。先頭ビットが0なら正、1なら負です。

整数型の指定

整数値を扱うための型には,( signed, unsigned ) char 型と int 型とがあることは説明したが, それら以外にもある.ここで,まとめて簡単に解説する.

バイト数 ビット数 最小値 最大値
unsigned char 1 8 0 255
signed char 1 8 -128 127
unsigned short int 2 16 0 65535
signed short int 2 16 -32768 32767
unsigned int 4 32 0 4294967295
signed int 4 32 -2147483648 2147483647
unsigned long int 4 32 0 4294967295
signed long int 4 32 -2147483648 2147483647
unsigned long long int 8 64 0 18446744073709551615
signed long long int 8 64 -9223372036854775808 9223372036854775807

基本的な整数型には char, short int , int, long int, long long int の4種類があり,そのサイズは char ≦ short int ≦ int ≦ long int ≦ long long int となる.

char 型は 1 バイトであると決まっているが,あとの種類はサイズが厳密に決められたものではなく, 将来は変わる可能性がある. 実際に,数年前のパソコンは 16ビットマシンが多かったので, int 型は 16ビット=2バイトであった.

今使っているコンピュータの環境では,たまたま int 型と long int 型とは,まったく同じものとなっている.

Sizeof演算子

簡単に言うと,sizeofに渡された型や変数のメモリサイズを調べるものです.

sizeof演算子は2種類の使い方があります.

  • sizeof(型)
  • sizeof 変数や定数,あるいは式など

sizeofに変数を渡した場合,その変数名で確保されているメモリサイズを返します.

int型の場合
int data[50];
int size = sizeof(data);

// dataは配列全体

 

文字列に必要なメモリの長さを調べる
#define STR "文字列"
int size = sizeof(STR);

// defineで定義された文字列に必要なメモリの長さ

ビット演算子

ビット単位でデータ操作をするものです。対象は整数に限られます

【ビット演算子】
演算子 説明
 & ビットごとの AND
 | ビットごとの OR
 ^ ビットごとの XOR
 ~ ビットごとの反転(1 の補数)
 << 左シフト
 >> 右シフト

(1) & (and)

両方のビットが 1 のときのみ結果が 1 になるビット演算です。

0 & 0 → 0
0 & 1 → 0
1 & 0 → 0
1 & 1 → 1

必要なビット以外をOFF(0)にする処理(マスクといいます)に使用されます。

例えば、10101010 という1バイトのビット列の下位4ビットを OFF する場合、そのままにしたいビットを 1 、OFFしたいビットを 0 にした、11110000 で and することにより実現できます。

図2:ビット単位の論理積では特定のビットがONかどうかを調べられる
ビット単位の論理積では特定のビットがONかどうかを調べられる

(使用例)

unsigned char a = 0xaa;	/*     10101010 */
printf("%#xn",a & 0xf0);	/* and 11110000 */

実行結果
0xa0

(2) | (or)

いずれかのビットが 1 なら結果が 1 になるビット演算です。

0 | 0 → 0
0 | 1 → 1
1 | 0 → 1
1 | 1 → 1

必要なビットをON(1)にする場合に or は使われます。

例えば、10101010 という1バイトのビット列の上位4ビットを ON する場合、ONにしたいビットを 1 、そのままにしたいビットを 0 にした、11110000 で or することにより実現できます。

図3:ビット単位の論理和では特定のビットをONにできる
ビット単位の論理和では特定のビットをONにできる

(使用例)

unsigned char a = 0xaa;	/*    10101010 */
printf("%#xn",a | 0xf0);	/* or 11110000 */

実行結果
0xfa

(3) ^ (xor)

両方のビットが異なるときに結果を 1 にするビット演算です。

0 ^ 0 → 0
0 ^ 1 → 1
1 ^ 0 → 1
1 ^ 1 → 0

特定なビットを反転する場合に xor は使われます。

例えば、10101010 という1バイトのビット列の下位4ビットを反転する場合、反転したいビットを 1 、そのままにしたいビットを 0 にした、00001111 で xor することにより実現できます。

図4:ビット単位の排他的論理和ですべてのビットをリセットできる
ビット単位の排他的論理和ですべてのビットをリセットできる

(使用例)

unsigned char a = 0xaa;	/*     10101010 */
printf("%#xn",a ^ 0x0f);	/* xor 00001111 */

実行結果
0xa5

(4) ~ (補数)

ビットの反転を行うビット演算です。

0 → 1
1 → 0

全ビットの無条件反転を行います。

(使用例)

unsigned char a = 0xaa;	/*     10101010 */
printf("%#xn",~a);

実行結果
0xff55		
(注)printf関数が unsigned char型を int型に符号拡張するために、0xff55 と表示されます。
   int型が4バイトの処理系では 0xffffff55 になります。

(5) << (左シフト)

x << n と書き、x を n ビット左へシフトします。

右側の空いたビットには 0 が入り、左側のビットは捨てられます。

左シフトは x が正の場合、x << 1 で「x * 2」を計算することと同じになります。

(例)

正の整数のとき

int x = 100;

x = x << 2;

(6) >> (右シフト)

x >> n と書き、x を n ビット右へシフトします。

左側の空いたビットには、x が符号無しなら 0 が入ります。x が符号付きなら、算術シフトを行う処理系では符号桁が入り、論理シフトを行う処理系では 0 が埋められます。 右側のビットは算術シフト、論理シフトにかかわらず捨てられます。

右シフトは x が正の場合 x >> 1 で「x / 2」を計算することと同じになります。

(例)

正の整数のとき

int x = 100;

x = x >> 2;

負の整数のとき
(算術シフトを
行う処理系の場合)int x = -100;x = x >> 2;

【参考】

  • 算術シフト:数値の演算を行うときに使用するシフト演算で、シフトの際に最上位の符号ビットを保存するシフトです。
  • 論理シフト:ビットの位置を変えるときに使用するシフト演算で、シフトの際に最上位の符号ビットを考慮することなくシフトを行います。

ビット演算どこで役立つ?

ファイルシステムやデータベースのように大量のデータにそれぞれフラグを持たせる場合に、ビットで管理するとデータ量を節約できるわけです。

このようなフラグ管理が行われている例として

  • Unix/Linuxファイルシステムのパーミッション
  • PHPのerror_reporting(出力するエラーの種類の設定)などのプログラミング言語の設定値
  • TCP/IPのサブネットマスク
  • ゲームや業務システムの状態管理

などがあります。

スイッチからの入力とLEDの点灯

演習

1)符号なし整数xのposビット目を、

  • 1にした値を返す関数set
  • 0にした値を返す関数reset
  • 反転した値を返す関数inverse

を作成せよ。(演習7-4, p193)

2)任意unsigned int型数値のビットパターンを表示

/* a9-4-2.c */
#include <stdio.h>
#include <limits.h>

void show_bit(unsigned dt);

int main(void)
{
  unsigned a;

  printf("0 〜 %#x の16進数を入力してください。> ", UINT_MAX);
  scanf("%x", &a);

  show_bit(a);

  return 0;
}

/*** ビット表示関数 ***/
/*(仮引数)dt:表示データ */
void show_bit(unsigned dt)
{
    int i, len;

    len = sizeof(dt) * CHAR_BIT;
        
    printf("%#x ---> ", dt);
    for (i = len - 1; i >= 0; i--){
        putchar(( __ >> __ & 1U) ? '1' : '0' );
    }
    putchar('¥n');
}

演習解説

C programming 2 (9) Radix conversion

第7章 基本型と数

2進数 16進数 とは

我々が日常生活で使用するのは10進数である。
なぜ10進数なのかというと、手の指が合計10本あるからではないかと言われている。 もし手の指が4本だったなら、8進数が使われていて、読者が2進数・16進数に混乱することももっと少なかったかもしれない。

コンピュータ内部では、通常2進数が使用される。何故かというと、10進数よりも2進数の方がコンピュータにとって扱いやすいからである。 なので、気がつかないかもしれないが、入出力の時に10進数←→2進数の変換が陰でこっそり行われているのだ。

/* バイトとビット */

コンピュータは 0 または 1 のデータを取り扱う。これを「ビット(bit)」と呼ぶ。 ひとつのビットだけでは、表現できる状態が2つしかない。

2進数の一桁では状態数が少なすぎるし、ひとつの値を表すのに桁数が多くなるので、通常は8個のビットをひとまとまりとして取り扱う。これを「バイト(byte)」と呼ぶ。

(1960 年代には、1 バイトが 7 ビットや 9 ビットのマシンが存在していました。その後 1 バイトは 8 ビットに統一されている。)

1バイトで表現可能な範囲は、2進数で書けば 00000000 から 11111111 まで。
10進数で書けば 0 から 255 までとなる。

1 バイトの構造を下記に示します。

ビット 7 6 5 4 3 2 1 0

一番左のビットを最上位ビット ( MSB: Most Significant Bit )、一番右のビットを最下位ビット ( LSB: Least Significant Bit ) と呼びます。

各ビットには 0 か 1 が入ります。その様子を表したものを、ビットパターンといいます。

unsigned char 型のデータは1バイトです。0 から 255 迄の 256 通りのデータを表すことができます。unsigned char 型のデータがビットパターンでどのように表現されるかを、下記に示します。

10進数 ビットパターン
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1
2 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 1 1
4 0 0 0 0 0 1 0 0
5 0 0 0 0 0 1 0 1
6 0 0 0 0 0 1 1 0
7 0 0 0 0 0 1 1 1
8 0 0 0 0 1 0 0 0
16 0 0 0 1 0 0 0 0
32 0 0 1 0 0 0 0 0
64 0 1 0 0 0 0 0 0
128 1 0 0 0 0 0 0 0
255 1 1 1 1 1 1 1 1

2進数で表記すると桁が多くなりすぎるので、2進数の4桁をひとまとまりにして、通常は16進数を用いる。
0から9までは通常の数を用い、10~15は ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘F’ を用いる。
小文字(’a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’)で表記してもよい。

16進数1桁は4ビットに相当する。

 10進数  2進数  16進数
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F

Nビットの数値を16進数に変換すると、(Nが4の倍数であれば、)N/4桁の16進数で表記できる。

C言語での 16進数表記

C言語において、ソースコード中に直接16進数を使用したい場合は 0x または 0X に続けて16進数を記述する。
10以上の値は ‘a’~’f’ または ‘A’~’F’ で記述する。

    int a = 0x100;       //  a に 16進数の 100, すなわち 10進数の 256 を代入
    int b = 0xab;         // b に 16進数の ab, すなわち 10進数の 171 を代入

C言語による16進数表示

    • Cの printf文で変数の値を10進数表示する場合は %d を使用する。
    int x = 100;
    printf("x = %d\n", x);        //    10進数表記

実行結果:

x = 100
    • Cの printf文で変数の値を16進数表示する場合は %x を使用する。
    int x = 100;
    printf("x = 0x%x\n", x);        //    16進数表記

実行結果:

x = 0x64

演習問題

  1. 10進数の100を、2進数、16進数に変換してみなさい
  2. 2進数の 01011010 を 10進数、16進数に変換してみなさい
  3. 32ビットの数値を16進数に変換すると何桁になるか?
  4. 4桁の16進数を2進数に変換すると何桁になるか?

C programming 2 (8) Google Classroom

Google Classroom

https://classroom.google.com/

Googleクラスルームログイン方法

  • ID : 15TE123@daiichi-koudai.com
    PW : 15TE123@daiichi-koudai.com

(初期PWは、最初のログインで変更すること)

演習コードの提出する方法

ソースコード(.cファイル)を課題の詳細ページより、添付で提出する。

先週の演習コードの提出は間違いが多いから、問題点をリスト
1)添付ファイルなし
2)空白の添付ファイル
2)ソースコード(.cファイル)以外のものを提出

提出した演習コードの修正する方法
1)提出を取り消し
2)提出内容の確認、修正
3)再提出

C programming 2 (6) Scope and Storage class

変数の通用範囲

自動変数のことを局所変数、外部変数のことをグローバル変数(大域変数)ともいいます。

変数のスコープの範囲を図で表してみます。

c_09_03

赤色で囲った部分がグローバル変数の有効範囲です。
青色で囲った部分がローカル変数の有効範囲です。

この図ではローカル変数の寿命を関数内と説明しましたが、正確にはブロック内です。
ブロックとは、{}で囲まれている範囲のことを指しています。

記憶クラス

Cで扱う記憶領域は一般に、プログラム領域、静的領域、スタック領域、ヒープ領域の 4つに大別されます。

記憶クラスには、4つあり、自動、静的、外部、レジスタがあります。

記憶クラス 記憶領域 スコープ 記憶クラス指定子
自動変数 スタック { } の内側 auto( 不要 )
静的変数 静的領域 { } の内側* static
外部変数 静的領域 全域 extern**
レジスタ変数 レジスタまたはスタック { } の内側 register
  • * { }の外側で宣言された時は、その行以降
  • ** 他のファイルにある時、externを付け、その変数を宣言(メモリを確保)しているファイルでは何も付けない。

自動変数は使う前に何らかの値を代入します。このことを、初期化するといいます。

静的変数は初期化の式がなくても、コンパイル時に0に初期化されます。

変数の名前

変数は名前を付けなければ、使えません。C言語では、名前(識別子)は、英字または’_’(アンダースコア)で始まり、英数字または’_’が0個以上続くという決まりになっています。’_’一つまたは二つで始まる変数は、システムに密着したデータに使います。例えば、コンパイラのプログラム等で使われます。

変数に名前を付ける時、外部変数は定義されている所から遠い所でも使われるので、その変数の用途を想像できるような名にすることが推奨されています。

    例:timetable, itemindex, thisyear

自動変数は通用範囲が狭いので、何の変数かがすぐわかるので、タイピングの手間を省く意味でも、短くて良いとされています。

    例:i, j, m, x, c

その場合でも、その変数がなんであるかを、瞬時に連想できるものが良いとされています。例えば、整数ならば、i、j、k、n、浮動小数点数ならば、x、y、z、文字ならば、cなどです。

#include <stdio.h>

void Func(void);        /* プロトタイプ宣言 */
void main(void);

/* 静的変数 i と自動変数 j の値を表示する */
void Func(void)
{                       /* i の値を読み書きできるのはこの関数の中でだけ */
                        /* i はずっと存在し続け、 */
        static int i;   /* func(  ) が呼ばれる度に1増える */

        auto int j;     /* 自動変数は初期化しないと */
                        /* ゴミの値が入っている */
                        /* j はゴミの値が表示される */
                        /* 幾つになるかはわからない */
                        /* auto は付けなくてもよい */
                        /* というより、普通は付けない */

        printf("i = %d  j = %dn", i, j);        /* i, j の値を表示 */
        i++;        /* 値を1増やす */
        j++;        /* 値を1増やす */
}                   /* 関数を抜けたこの時点で、j は破壊される */

void main(void)
{

        Func(  );        /* 呼び出す度に i の値は 1 増える */
        Func(  );
        Func(  );
}

演習

演習1

静的記憶域期間が与えられたdouble型配列の全要素が0.0で初期化されることを確認するプログラムを作成せよ。

ヒント:

(教科書p165のList6-19を参考に)

演習2

呼び出される回数を表示する関数put_countを作成せよ。(教科書p165)

ヒント:

(上のサンプルコードを参考に)