Cプログラミング入門

コンピュータは計算機である.
計算機に最低限必要な要素は,入力,出力,四則演算,メモリ(記憶)である.

ここでは,プログラムの骨格をなす入出力,変数,代入,四則演算をまとめて一挙に説明するので,まずは全体像をつかんでほしい.
細かな内容については,まだ暗記する必要はない.
プログラムにおいてどのような機能が利用されるか概要を理解しよう.


計算機(電卓)に必要な要素.

目次(クリックで開閉)

目次

  1. プログラムの基本形
  2. 変数
  3. 代入
  4. 出力・・・printf()

  5. 四則演算
  6. 入力・・・scanf()

プログラムの基本形

ソースコードの構造

まずは,Hello World のC言語プログラムのソースコードを眺めてみよう.
参考までに,他のプログラミング言語では,このような記述となる.

mainfunc.png

練習問題

注:「練習問題」は提出不要.cppファイル名は,自由に設定して良いが,半角文字を使用すること.フォルダ名も同様.

今日の予習として,以下の円の面積の計算プログラムを入力・保存・コンパイルして,実行してみよう.
各行の意味についてはまだわからなくてもよい.

ファイル名を,例えば test.cpp としてみよう.

大文字と小文字,各種記号に注意して1字1句間違いなく入力すること.
#include <stdio.h>

int main(void)
{
    float pi = 3.1415;
    float r = 10;

    float A = r * r * pi;
    
    printf("r= %.3f, Area = %.3f \n", r, A); 

    return 0;
}

実行結果:
????? 何が出力された?

変数

計算中に使う値や,計算結果の数値や文字を記憶しておく箱(=メモリ)を,プログラム中では 変数 と呼ぶ.
(これに対して, -100, 0.98 のような表記を「定数」と呼ぶ.)

C言語では

というルールがある.
C言語では,「定義」していない変数は使うことができず,コンパイル時にエラーとなる.

変数の「型」の種類

変数は,扱える数などの種類によりさまざまな 型(かた) が決められている.
C言語では,あらかじめ,整数型浮動小数点(実数)型 と, 文字型など,組み込み型(プリミティブ型という)と呼ばれる型の種類が用意されている.

プログラムでの処理において,どのような文字・数値を扱うかをあらかじめ計画し,適した型を宣言・定義してから使う必要がある.
以下にC言語の主な組み込み型を示す.

当面は,整数型 int,浮動小数点型 float(またはdouble),文字型 char を使う,と覚えておけば良い.

読み方

int
integer,イント型,インテジャー型,整数型
float
floating point,フロート型,実数型,単精度型
double
double precision (floating point),ダブル型,倍精度型
char
character,キャラクター型,チャー型,文字型など

色々な型

C言語では,様々な型がはじめから用意されている.これらを組み込み型(プリミティブ型)と呼ぶ.
丸暗記をする必要はないが,プログラムを設計するにあたり,表現できる値の範囲について覚えておく必要がある.

型名一覧
種類 名前 サイズ
(byte)
値の範囲
整数型
char 1 -128 ∼ 127
文字に割り当てられる.
unsigned char 0 ∼ 255
int 2 or 4 or 8
システムにより異なる.
unsigned int
short 2 -32,768 ∼ 32,767
unsigned short 0 ∼ 65,535
long 4
(8の場合もある)
-2,147,483,648 ∼ 2,147,483,647
unsigned long 0 ∼ 4,294,967,295
long long 8 -9,223,372,036,854,775,808 ∼ 9,223,372,036,854,775,807
unsigned long long 0 ∼ 18,446,744,073,709,551,615
 浮動小数点型(実数)  float 4 -3.4E38 ∼ 3.4E38 (Eは10の累乗)
double 8 -1.7E308 ∼ 1.7E308

接頭辞について

最近の整数型について補足
整数型について 整数型は,そのサイズ(=バイト数)が時代とともに変わってゆくものがあり,互換性の点で問題が生ずることがあった.(int型は昔は16bit,最近は32bitなど.)
そこで,最近のC言語規格(C99)では,整数型の名前が拡張されており,以下のようにビット数が固定されたわかりやすい名前になっている.
これらの変数を使用時するには,#include <stdint.h> が必要.

変数名のつけ方・・・命名規則

変数の名前は下記の文法ルールにさえ従えば,自由につけて良い.
ただし,実際にはプログラムを書いている本人や読む人に,意味・役割がわかる名前を付けるべきである.

変数名の付け方ルール.

C言語のおもな予約語一覧
auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while
正しい変数名 誤った変数名
int a12;
int break_1;
int 12a;(変数名が数字から始まっている)
int break; (breakは予約語)
float Return; float return; (予約語は変数名には使えない.大文字はOK)
double ab_c; double ab-c; ( - が減算とみなされる)

代入

ある変数にたいして,定数や別の変数の値をコピーすることを 代入 とよび, 記号 = で表す(代入演算子という).
数学の「等しい」とは異なる用法なので注意!!!

例1:   /* この区間を「コメント」という.コンパイラには無視される. */
int a;        /* 整数型変数 a の宣言・定義 */
a = 10;       /* 代入 */

これは,変数 a を定義して,aに定数 10 を代入する という意味となる.
数学の「等しい」とは異なり, 右辺から左辺への一方通行であるため,次のような書き方は,コンパイルエラーとなる.

10 = a ;   /* これはエラー */

例2:変数に別の変数の値を代入
float b, c;       /* 実数型変数 b,c の宣言 */
b = -9.81;        /* 変数への定数の代入 */
c = b;            /* これもOK */

いろいろな変数宣言と代入(初期化)の書き方

以下はどれも正しい変数の宣言(定義)方法である.

二つの変数を宣言する int a;
int b;
int a, b; /* まとめて宣言してもOK */
一つの変数の宣言と代入(正確には初期化という) int a; /* 変数宣言 */
a = 2; /* これは代入 */
int a = 2; /* 変数宣言+初期化 */
二つの変数の宣言と初期化 int a; int b;
a = 2; b = 3;
int a=2, b=3; /* OK */


コメント欄について プログラム中の の部分は「コメント」と呼ばれ,覚書やメモ書きを自由に記述できる.
この部分は何を書いてもコンパイラは単に無視するだけであるから,実行ファイルには,何ら影響を及ぼさない.
どういう意図でプログラムを書いたか,あるいは(未来の自分も含め)ソースコードを読む人に向けたメッセージを書いておくと良い.
このテキスト内では,各コードの説明文を書くことが多いので,読んでおくこと.

出力

printf()関数の使い方・・・画面への表示,出力

計算機の内部でどんなに興味深い,意味のある計算を行っていても,人間が理解できる形で出力しなければ意味が無い.
そこで,まずは画面に文字や数値,および変数の値を表示するprintf()関数について学ぶ.

書式:printf(書式指定文字列, ...)

書式指定文字列はフォーマット指定子とも呼ばれ,表示したい文字,および,後述の特別な記号を組み合わせて使う.
printf()関数は,単に文字を画面に出力するだけでなく,変数に格納された値を表示することができる.

例:以下のプログラムを入力・保存・コンパイルして,実行してみよう
  #include <stdio.h>

int main(void)
{
    int a;            /* 整数型の変数 a を使用します!と,宣言 */
    a = 10;           /* a に10を「代入」する.「等しい」という意味ではない. */

    printf("a is equal to %d.\n", a);   /* 変数 a の値を画面に表示.実行時に %d の部分が数値に置き換わる. */

    return 0;
}

実行結果:
a is equal to 10.

書式指定文字列中の % から始まる記号によって,表示スタイルをいろいろと変化させることが出来る.

書式指定文字
(m,nは整数)
意味
%d 整数を十進数で表示.%5d%05dとすると桁数指定可 1, 2, -35
%x 整数を十六進数で表示. ffff, 01ab
%f 実数(float型)を小数で表示 0.100000
%.mf 実数(float型)を小数部 m 桁まで表示.空白はスペースを表示
%.4f と書くと,全体で5桁,小数点以下3桁を表示する.
  3.1415
%n.mf 実数(float型)を n 桁の小数で表示,小数部を m 桁で表示.空白はスペースを表示
%5.3f と書くと,全体で5桁,小数点以下3桁を表示する.
  3.141
%lf 実数(double型)を小数で表示 0.100000

プログラム例1:以下のソースをコピーして実行してみよう.
  #include <stdio.h>

int main(void)
{
    int a = 30;        /* 変数の宣言と同時に代入(初期化) */
    float r = 3.14;

    printf("a = %d\n", a);   /* 10進数で表示 */
    printf("a = 0x %x\n", a);   /* 16進数で表示.0xをつける. */

    printf("\n");

    printf("r = %f \n", r);
    printf("r = %12.3f \n", r);  /* 桁数を指定 */

    return 0;
}

printf では,書式指定文字列中に複数の % 記号を並べれば,行内に複数の変数を順番に表示させることができる. もちろん,対応する変数も並べて書く必要がある.

プログラム例2:
#include <stdio.h>

int main(void)
{
    int a = 50;
    float r = 3.14;

    printf("a and r are equal to %d and %f, respectively.\n" , a, r);          /* カンマ区切りで変数を並べる */

    return 0;
}

エスケープシーケンス

printf() において,「abc」や「123」などの普通の文字・数値はそのまま表示できるが,それ以外にも改行やタブなどの特殊な文字を表示したい場合がある.
例えば,上の例で確認した通り,printf() の書式中では, %, \などの記号に特別な役割があるため,これらの文字をそのまま表示したい場合には,工夫が必要である.

そこで,特殊な文字を出力するためにエスケープシーケンスという機能が用意されており,\(バックスラッシュ) または ¥(円マーク)と文字を組み合わせて表現する. (注:\¥は,完全に同じものとみなす.)
たとえば,改行を画面に出力したい場合,ソースコード中に \n または ¥n と書く.

#include <stdio.h>

int main()
{
    printf("Hello! \n World \n ");
    return 0;
}
表示したい文字 エスケープシーケンス
\¥ は同じ意味.
\ \\
% %%
' \'
" \"
改行 \n
タブ \t
バックスペース \b
ベル(音が鳴る) \a

詳細については,Microsoft社,関数リファレンス,printf(外部サイト)や, Embarcadero社,ライブラリ関数リファレンス, printf(外部サイト)も参考にすると良い.
このようなコンパイラメーカーが提供するリファレンスマニュアルには,豊富なサンプルプログラムが掲載されており,これを自分のコンピュータで写して実行,結果を確認してみよう. そして,サンプルのソースコードを読むことは,大変良い勉強となる.


練習問題1 (「練習問題」は提出不要.cppファイル名は,各自で自由に設定して良い.)

以下のような文字を画面に表示するプログラムを書け.
エスケープシーケンスをうまく使用する.
全角文字を使用しないこと.

実行結果:

You have $100.
I got ¥500.
15 % discount!
That is "great!"


四則演算

C言語で標準的に使用できる算術演算について学ぶ.
(いろいろな演算を行う記号のことを,演算子と呼ぶ.)

算術演算子

数の計算に用いる演算子を下の表にまとめる.

 演算子   作用   使い方の例  意味
+ a = b + c; b と c をたした値を a に代入
- a = b - c; b から c をひいた値を a に代入
* a = b * c; b と c をかけた値を a に代入.アスタリスク,コメと読む.
/ a = b / c; b を c でわった値を a に代入(c が 0 の時はエラー,注:整数/整数は切り捨て
% 剰余 a = b % c; b を c でわったあまりを a に代入.整数のみOK

和差積商は数学でもおなじみだが,積と商は,数学とは異なる記号を用いる

積商は,和差よりも優先順位が高く,先に計算される.
また,( )を用いて計算順序を変更できる点は,数学と同様である.

% 演算子は数学では百分率を表す記号であるが,C言語では割り算のあまりを表す.

(1)式の値を表示する例:

以下のコードを実行してみよう.
#include <stdio.h>

int main(void)
{
    printf(" 1 + 2 は %d です\n", 1+2);
    printf(" 1 - 2 は %d です\n", 1-2);
    printf(" 5 x 2 は %d です\n", 5*2);
    printf(" 5 / 2 は %d です\n", 5/2);
    printf(" 10 %% 3 は %d です\n", 10%3);       /* %% は,エスケープシーケンス! */
    return 0;
}

(2)変数で計算し,値を表示する例:

(1)を改造して,以下のコードを実行してみよう.
#include <stdio.h>

int main(void)
{
    int a;        /* 変数の宣言 */
    int b;

    a = 1 + 2;    /* 四則演算と代入 */
    b = 3 * 4;

    /* 以下,表示 */
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("a+b = %d\n", a + b);     /* ここで計算してもOK */
}

次に,変数 a の値を 1 だけ増やしたい場合はどうしたら良いか?
実は,このように書ける.

a = a + 1;

まず,右辺の計算で a に 1 が加算され,その結果が左辺の a にふたたび代入されるため,これでうまく動作するのである.

注意:Cでは数学とは異なり 「a の値と a+1 とが等しい」という意味にはならない!
さらに,数学の 定義 とも異なり,変数と値の「関係」を定義するものではない.
つまり,処理が = が出現した行に差し掛かったときに,右辺から左辺へと「代入」が行われるのみである.

練習問題2 (cppファイル名は,各自で自由に設定して良い.)

和差積商を組み合わせた式の計算を行ってみよう.
計算結果を適切な型の変数に代入してから表示せよ.

  1. 1+2*3
  2. (10+20)*30
  3. 1-2*3/4
  4. 10-100%7
  5. 3.1415926535 * 10 * 10
  6. 5!
  7. 210

代入演算子

プログラムを書いていると,「ある変数に演算をして,またもとの変数に代入する」という処理が頻繁に登場する.
これを効率よく行うため,以下のような代入演算子(演算+代入を一度に行うもの)がある.

演算子  使い方  意味
= a = b; b の値を a に代入
+= a += b; a = a + b;
-= a -= b; a = a - b;
*= a *= b; a = a * b;
/= a /= b; a = a / b;
%= a %= b; a = a % b;
++ a++; a = a + 1; または a += 1;
-- a--; a = a - 1; または a -= 1;

代入で説明した,

a = a + 1;

を,代入演算子を使って

a += 1;

あるいは

a++;

と書くこともできる. いずれも全く同じ意味になる.
どれを使用してもよいが,この表記の意味を理解できるようにしておこう.

入力

キーボードからの入力

プログラムでは,処理の途中にユーザーからの指示を仰ぎたい場合や,データを入力させたい場合がある.
そのような場合,キーボードからデータを入力する scanf()関数を用いる.

scanf() 関数は,printf() 関数によく似ているが, 値を格納する変数の前に & をつける必要がある.

注:この記号&は,変数が置かれているメモリ中の場所(アドレス)を取り出す演算子で,scanf()関数に値を格納する場所を教えている.
詳しくはポインタ変数の単元で解説する.
例:キーボードから変数に値を入力し,画面にその二乗を表示するプログラム
  #include <stdio.h>

int main(void)
{
    int a = 0;
    float b = 0;

    printf("a = ");
    scanf("%d", &a);    // integer 

    printf("b = ");
    scanf("%f", &b);    // floating point

    printf("a*a = %d \n", a*a);
    printf("b*b = %.3f \n", b*b);        // 実数を小数第3位まで表示
    return 0;
}

複数データの入力

以下のように,1つのscanf 内に複数の書式指定文字と変数を書いて,複数の値をキーボードから入力させることができる.
(この例では,OnlineJudge提出用の例として,scanf() の前の printf()をコメントアウトしている.
デバッグ時はprintfを有効にして,提出時はこのように余分な文字出力をコメントアウトすること)

#include <stdio.h>

int main(void)
{
    int a, b;           // integer a, b

//  printf("a b = ? ");       // ユーザーに入力させるためのメッセージ.プロンプトという.OnlineJudgeに提出時はコメントアウトすること!.

    scanf("%d %d", &a, &b);   // 標準入力から整数を2つ入力.区切りは半角スペースを使用

    int c = a+b;              // aとbの和を計算し,ここで宣言する整数 c へ代入(何度も言うが,=は等式ではなく代入!)

    printf("%d\n", c);        // cの値を10進数表記で標準出力へ書き出す.
    return 0;
}

実行例:
10 20       <--- 入力
30          <--- 出力

以上で,基本的な入出力,変数の宣言と値の代入,四則演算について最低限の知識を学んだ.
あとは実習問題に取り組みながら,内容の理解を徐々に深めてゆこう.

練習問題3(重要):提出用プログラム作成上の注意:

OnlineJudge(OJ)では,計算結果などの出力値を用いて正解・不正解の判定を行うので,判定に不要な余分な文字を出力しないこと! タブ・スペース・改行などの表示されない文字も×

  1. プログラム作成時・修正時は,下記の例のように「キーボード入力」を促す文字などを出力しよう.
  2. プログラムが完成し,OJに提出する際には,余分なprintf()をコメントアウトし,数値のみを出力させること.

全角文字は特に指示のない限り使用しない.また,数値の出力時に表示桁数なども注意すること.

  1. キーボードから半径(1つの実数)を入力すると,その円の周長と面積を画面に表示するプログラムを作成せよ.
    ヒント:小数第1位まで表示するには,printf() の書式指定で "%.1f" とする.
    実行例:(数値は正しいとは限らない)
    
    (1)プログラム作成時の動作
    
    r =? 10.5 (キーボード入力)
    
    length = 100.2
    area = 200.1
    
    (2)OnlineJudgeで提出する際は,以下のように余分な文字(プロンプト)を表示しないようにする.
    
    10.5 (キーボード入力)
    
    100.2
    200.1
    
  2. キーボードから三角形の底辺長と高さ(2つの実数)を入力すると,その面積を画面に表示するプログラムを作成せよ.
    ヒント:小数第2位まで表示するには,printf の書式指定で "%.2f" とする.
    実行例:(数値は正しいとは限らない)
    
    (1)デバッグ時の動作
    
    width = 0.35 1.5 (キーボードから2つ数値をスペース区切りで入力)
    area = 29.20
    
    (2)OnlineJudge提出時の動作
    
    0.35 1.5
    29.20
    

    練習ができたら実際にOnlineJudgeにログインしてみよう.