最終更新2014/5/30 執筆者:mznh
普段自分が使っているソフトウェアの中身を見たことがありますか?
試しにちょっと特殊な方法でWindowsに標準で付いているメモ帳の中身を見てみましょう。
[00000000] 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 |3C| MZ・・・・・・・・・・・・・・
[00000010] B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |F8| ク・・・・・・・@・・・・・・・
[00000020] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |00| ・・・・・・・・・・・・・・・・
[00000030] 00 00 00 00 00 00 00 00 00 00 00 00 E0 00 00 00 |E0| ・・・・・・・・・・・・・・・・
[00000040] 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 |4F| ・・コ・・エ・ヘ!ク・Lヘ!Th
[00000050] 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F |23| is program canno
[00000060] 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 |ED| t be run in DOS
[00000070] 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 |1B| mode.・・・$・・・・・・・
[00000080] B2 BE C2 62 F6 DF AC 31 F6 DF AC 31 F6 DF AC 31 |AA| イセツb・゚ャ1・゚ャ1・゚ャ1
[00000090] FF A7 39 31 F5 DF AC 31 FF A7 3F 31 EB DF AC 31 |7E| ・ァ91・゚ャ1・ァ?1・ャ1
[000000A0] F6 DF AD 31 00 DF AC 31 FF A7 2F 31 E9 DF AC 31 |1A| ・゚ュ1・゚ャ1・ァ/1鱇ャ1
: : :
Microsoft Windows バージョン 6.1 付属 notepad.exe より引用 Copyright © 2009 Microsoft Corporation. All rights resserved
何がなんだかわかりませんね。これはコンピュータが解る「機械語」と呼ばれる言語で書かれています。
しかし僕達人間にとってこれはわかり易い言葉ではありません。
これではよほどの人でない限りプログラムを書けないのでなるべく人間にわかりやすい言語を作ってそれを機械語に変換して使うようになりました。
それをプログラミング言語といい、プログラムを書くことをプログラミングといいます。
またプログラミング言語を機械語に変換することをコンパイルと言い、変換するソフトのことをコンパイラと呼びます。
この講習では最も一般的なプログラミング言語の一つであり、マイコン開発に用いられることの多い言語としてC言語の基本を学んでいきます。
この講習では演習や課題があります。とはいってもそんなに堅苦しいものではありません、わからなかったら質問してもらって結構です。
僕はプログラミングというものは実際に自分で書いてみることが重要だと考えています。
しかしC言語というプログラミング言語はそれ単体では正直いってそんなに面白い言語ではありません。面白くない言語なので自分で目的を見つけることも難しいです。
そこで以下のサイトを利用することにします。
Aizu Online Judge(以下AOJ)は会津大学が運営しているサイトで様々なプログラミングの問題が紹介されています。またその問題に正解しているかどうかを自動で試すことが出来ます。
まず最初はHelloWorldと出力するだけのプログラムを書いてみましょう。丸写しで大丈夫です。
//hello.c
#include<stdio.h>
int main(void){
printf("Hello World\n");
return 0;
}
コンパイルはgcc hello.c -o hello
コマンド解説 gcc
GNU C Compiler もしくは GNU Compiler Collectionの略
使い方は
gcc ソースファイル -o 作成したい実行ファイル名
実行ファイル名を省略するとa.outという名前の実行ファイルが生成されます。
実行は./hello
[hoge@sol ]$ ./hello
HelloWorld
[hoge@sol ]$
//hello.c
#include<stdio.h>
//include文:ライブラリという辞書のようなものを読み込んでいます
int main(void){
//main関数:Cのプログラムははじめにmain関数を実行するように決められています。
printf("Hello World\n");
//printfという関数を使ってHelloWorldという文字列を表示しています。
return 0;
//値を返しています。
}
今の段階ではprintf("ホニャララ")ってやるとホニャララが画面に出力されるってことがわかればOKです。
C言語ではタブやスペースで単語同士を区切り;で文を終えます。
hogehoge fugafuga; //この行は文です
piyopiyo foobar //この行は;で終わっていないので文ではありません。
また単語自体を分割しない限り自由に改行やスペースを入れることができます。
//つまりC言語的に言ったら
//この文と
printf("HelloWorld\n");
//この文は一緒です
printf(
"HelloWorld\n"
) ;
//これは違います(単語を分割しちゃってるため
pri nt f
("Hello World\n"
);
文末の;は忘れがちなので注意しましょう。
発展的な内容
{}で複数の文を囲んだものも複文という一つの文として解釈されます。
なお " で囲まれているものを文字列と呼びます。(詳しくは後の回でやります。
プログラムの中にメモをしたい場合 // の後に書くとそこから行末までコンパイラは無視してくれます。
また/*と*/で囲んだところもコメントになります。
printf("hogehoge"); //これはコメントです
/* これもコメントです */
それでは先程紹介したAOJの問題10000番がちょうどHello Worldを出力する問題なので試しに投稿してみましょう。
皆さん通りましたか?通らなかったら周りのTAや僕に質問してください。
"\n"のような特別な文字は他にも色々あります。気になる方は”printf 書式”で調べてみると良いでしょう。
変数という言葉を聞いたことがあるでしょうか、数学に出てくるx^2+x+2=0とかでいうxも変数といいますね。
プログラミングにおいても変数というものがあります。簡単に言えばデータを格納しておく箱のようなものです。試しに使ってみましょう。
C言語において変数を使うにはまず宣言というものが必要です。
変数の宣言は型(器の大きさや形を指定したもの)と名前(器の名前)を並べて書きます。
int var; //intが型,varが名前
これによりintという型のvarという名前の変数が宣言されました。(定義されたともいう)
なお変数の名前にはアルファベットの大文字と小文字、0から9の数字、_(アンダーバー)を使う事ができます。ただし頭文字に数字は使うことが出来ません。
またこれはC言語の文法と直接関係することではありませんが、変数名は何を表しているかがわかる名前を付けると良いです。
宣言した変数に何か値を入れることを代入と言います。
代入には代入演算子「=」を使います。
例えばaという変数に100という値を代入するのなら
int a; //変数宣言
a = 100; //100という値を代入
と書きます。実際に代入されているかprintfという関数を使って確認してみましょう。
printf関数はprintf("hoge%dhuga", a);
と書くと%dのところに変数aの値を数字として入れて出力してくれます。
//hensuu.c
#include<stdio.h>
int main(void){
int a;
a = 100;
printf("%d\n",a);
return 0;
}
コンパイルして実行してみましょう。
[hoge@sol ]$ gcc hensuu.c -o hensuu
[hoge@sol ]$ ./hensuu
100
[hoge@sol ]$
ちゃんと変数aに100が代入されていることがわかります。
ちなみに変数から変数への代入も可能です。
//hensuu2.c
#include<stdio.h>
int main(void){
int a,b; //aとb2つの変数を宣言しました。
a = 10; //それぞれ値を代入
b = 20;
printf("a = %d \n",a);
printf("b = %d \n",b);
a = b; //bの値をaに代入
printf("a = %d \n",a);
printf("b = %d \n",b);
return 0;
}
コンパイルして実行してみましょう。
[hoge@sol ]$ gcc hensuu2.c -o hensuu2
[hoge@sol ]$ ./hensuu2
a = 10
b = 20
a = 20
b = 20
[hoge@sol ]$
ここで注意して欲しいのはC言語における=は数学における=とは意味が異なる点です。(数学でいう=は後にやります。)
C言語を使って簡単な計算をしてみましょう。いつも使っている式と同じように書けます。
名前 | 演算子 | 書き方 |
加算 | + | a+b |
減算 | - | a-b |
乗算 | * | a*b |
除算 | / | a/b |
剰余算 | % | a%b |
剰余算というのはaをbで割った余りを意味します。
ではひと通り試してみましょう。
//keisan.c
#include<stdio.h>
int main(){
int a,b;
a = 17;
b = 5;
printf("a=%d,b=%d\n",a,b);
printf("a+b = %d\n", a+b ); //a+bの値が%dに入って出力されます。
printf("a-b = %d\n", a-b );
printf("a*b = %d\n", a*b );
printf("a/b = %d\n", a/b );
printf("a%%b = %d\n", a%b );
return 0;
}
コンパイルして実行してみましょう。
[hoge@sol ]$ gcc keisan.c -o keisan
[hoge@sol ]$ ./keisan
a=17,b=5
a+b = 22
a-b = 12
a*b = 85
a/b = 3
a%b = 2
[hoge@sol ]$
正しく計算されていることがわかります。
突然ですが以下のコードを実行してみましょう。
//kata.c
#include<stdio.h>
int main(void){
int a,b,c;
a = 2000000000;
b = 2000000000;
c = a + b;
printf("c = %d\n",c);
return 0;
}
実行結果はどうなったでしょうか?おそらく期待したものと違う答えが出力されたと思います。
では何故このようなことが起きたのでしょうか。
変数の宣言に必要なものを思い出してみましょう。変数の宣言には型と名前が必要でした。
コップやバケツに大きさが在るように型にも大きさがあります。
そしてコップやバケツと同じように変数も大きな値を入れると溢れてしまうのです。
変数において値が溢れてしまうことをオーバーフローと言います。
それでは一般的なC言語で使われる変数の型を少し見てみましょう。
注意 変数の大きさは環境によって変わることがあります。以下の表はsol(コンピューターリテラシーの授業等で使うサーバー)での値です。
型の名前 | 保存できる値の種類とbyte数 | 保存できる値の範囲 |
char | 整数(1byte) | -128~127 |
short | 整数(2byte) | -32,768~32,767 |
long | 整数(8byte) | おおよそ-10^20~2^20 |
int | 整数(4byte) | -2,147,483,648~2,147,483,647 |
float | 実数(4byte) | ±10^-38~10^38 |
double | 実数(8byte) | ±10^-308~10^308 |
この講習では詳しい整数や小数点の表し方については学びません。気になる方は「浮動小数点数」や「2の補数表現」で調べてみるとよいでしょう。
難しそうな言葉ですが平たく言うと画面に文字を出したりキーボードから入力を受け取ったりすることです。
ちょっと今の段階では説明できないおまじないが出てきますがそれはまた次回…
それでは手始めにキーボードから数値の入力を受け取ってみましょう。
よく使われる標準入力の関数にscanf関数があります。例えばキーボードから数値の入力を受け取ってhogeという名前の変数に保存したいときは、
int hoge; //変数の宣言
scanf("%d",&hoge);
というように書きます。printfと似た感じですが変数の前に「&」をつけることに注意してください。
これはhogeという変数のアドレスを表しているのですがこれについては後の回で詳しくやります。
とりあえず試してみましょう。
//input.c
#include<stdio.h>
int main(){
int a;
scanf("%d",&a); //&を忘れないように注意
printf("入力された値は%dです。\n",a);
return 0;
}
ではコンパイルして実行してみましょう。
[hoge@sol ]$ gcc input.c -o input
[hoge@sol ]$ ./input
100 <-キーボードからの入力です。
入力された値は100です。
[hoge@sol ]$
自分の入力した数値がちゃんと帰ってきましたか?うまくいかない時はTAや僕に質問してください。
さて今まで何気なくprintfやscanfで%dとか書いてきましたがこれについて詳しく見てみましょう。
scanfやprintfはおおまかに言って以下のような構成になっています。
printf("書式文字列",各種変数…);
この書式文字列の中に書かれる%dのようなものを変換指定文字と呼びます。
では他にどのような変換指定文字があるのか見てみましょう。
変換指定文字 | 動作 | 出力例 |
%d | 整数10進数で出力 | 200 |
%x | 整数16進数で出力 | c8 |
%f | 実数で出力 | 10.000000 |
%e | 指数表記で出力 | 1.000000e+01 |
%c | 一文字出力 | A |
%s | 文字列を出力 | Hello World |
これらはscanfにおいても同様に使うことが出来ます。
scanf("%d",&a); //数値を入力
scanf("%s",string); //文を入力
aの前の&を忘れずに!
また逆になんでstringの前には&がないのかは後の回で詳しくやります。
複数個の値を入力したいとき、例えば2つ整数の値を入力したいときは、
scanf("%d %f ,&a,&b);
というように書きます。
この場合10 5.0
という入力が合った場合aに10,bに5.0が代入されます。
また数値の表現において出力する桁数を固定したいとき、
例えば20という数字を「___ 20」 (_はスペース)という風に出力したい場合は
printf("%5d",20);
0詰めで出力したい場合は
printf("%05d",20);
というように書きます。
文字そのものと文字列はC言語ではちょっと扱いが違います。
では演習課題を初めてください。
これで第一回目のC言語講習は終わりです。
演習 1:printfを使って好きな文を表示させるプログラムを作成せよ。
演習 2:printfを複数回使って複数行に渡る文章を表示するプログラムを作成せよ。
演習 3:printfを1回だけ使って複数行に渡る文章を表示するプログラムを作成せよ。
演習 4:変数を2つ宣言してそれに好きな値を代入したあとその2つの和をprintfを使って出力するプログラムを作成せよ。
演習 5:一つ数の入力を受け取ってそれを2倍した数を出力するプログラムを作成せよ。
演習 6:2つの整数の入力を受け取ってそれを足しあわせた数を出力するプログラムを作成せよ。
演習 7: AOJ10000 Hello World
演習 8: AOJ10001 X Cubic
演習 9: AOJ10002 Rectangle
この 作品 は クリエイティブ・コモンズ 表示 - 非営利 - 改変禁止 2.1 日本 ライセンスの下に提供されています。免責事項