第一回 基本文法
第二回 ポインタ・構造体
対象者
- C言語をほとんどやったことがない人
- プログラムに触ったことがある人
- メモリやポインタの意味をよくわかってない人
はじめに
大学の授業でC言語を学んだので、その内容をまとめて記事にしようと思う。ざっくりとした説明のみなので、完全な初心者にはあまり向かないかもしれない。基本文法は簡単に、メモリやポインタなどに重点を置いて説明していくつもりである。
C言語とは
1972年にD.Ritchieら(AT&T Bell研)が作ったプログラミング言語。
java,C++も含む高級言語の中では「低水準」であり、ポインタ演算、ビットごとの論理演算など、ハードウェアよりなコードを書くことができる。
基本文法
メイン関数
// コメント
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
Hello World!
-
#include <stdio.h>
で「stdio.h」という標準ライブラリをインポートしている。必要に応じて複数書かれる。ヘッダーファイルは< >で囲まれ、自分でディレクトリ上に置いたものは" "で囲む。 - メイン関数の最後の
return 0;
はメイン関数の返り値を表す。0以外でも可。 -
int main(void)
の「void」は引数がないことを示している。省略可。
変数と型宣言
- 変数: 定数を格納するもの。その箱の名前を「変数名」という。
型宣言
int a; // 整数型
float x; // 実数型(単精度)
double y; // 実数型(倍精度)
char c; // 文字型
- 整数型は、4byteの変数。-2^31~2^31-1
- 実数型(単精度)は、4byteの変数。± 10^-38 ~ 10^38
- 実数型(倍精度)は、8byteの変数。± 10^-308 ~ 10^308
- 文字型は変数1つに一文字格納できる。1byteの変数。-128~127
※1byte = 8bit
出力
// 1.
printf("Hello World!\n");
// 2.
printf("Hello ");
printf("World!");
printf("\n");
// 3.
puts("Hello World!");
- 上記の3つは同じ実行結果。
-
printf()
は明示的に改行(\n)を入れない限り開業は出力されない。 - \n 改行、\t タブ、\ バックスラッシュ
int i = 1000;
float x = 12345.67;
double y = 3.14159265358979;
printf("%d, %10d, %+10d, %-10d, %010d\n", i,i,i,i,i);
printf("%d, %o, %x\n", i,i,i);
printf("%f, %f\n", x, y);
printf("%8.3f, %8.3f\n", x, y);
printf("%e\n", y);
printf("%g\n", y);
出力
1000, 1000, +1000, 1000 , 0000001000
1000, 1750, 3e8
12345.669922, 3.141593
12345.670, 3.142
3.141593e+00
3.14159
- %dは対応する整数を10進数で出力する。「 フォーマット指定子 」と呼ぶ。
- %o 8進数で出力、%x 16進数で出力
- %f 実数型(double,float)
- %10d 10桁で表示。余った桁はスペースで表示。
- %010d 10桁で表示。余った桁は0で埋める。
- %+10d 左揃え、 %-10d 右揃え
- %8.3f 8桁で表示し、小数点3桁まで表示する。
- %e 指数で表示
- %d 形式を適宜変えて表示
演算子
int a=100, b=17;
printf("%d\n", a+b); // 和
printf("%d\n", a-b); // 差
printf("%d\n", a*b); // 積
printf("%d\n", a/b); // 商(int/intは切り捨て整数)
printf("%d\n", a%b); // 余り
117
83
1700
5
15
- 商を小数点まで表示させたい時は、
(float)a /b
と書き、これはint型のaをfloat型に変更してからbで割ることを示す。これを「 型キャスト 」と呼ぶ。float -> int、double -> intへキャストすると小数点は切り捨てられる。
// 単純代入演算子
a = 100;
a = b = c; // a = (b = c); と同じ意味
// 複合代入演算子
a += 100; // a = a + 100;と同じ意味
a -= 100; // 以下同様
a *= 100;
a /= 100;
a %= 100;
-
a = b = c;
は結果的にはa, bにcの値が代入される。
// 比較演算子
int a=10, b=20;
printf("%d\n", a<b); // 小なり
printf("%d\n", a<=b); // 小なりイコール
printf("%d\n", a>b); // 大なり
printf("%d\n", a>=b); // 大なりイコール
printf("%d\n", a==b); // イコール
printf("%d\n", a!=b); // ノットイコール
1
1
0
0
0
1
- C言語にはBoolean型は存在せず、true=1かfalse=0で表す。
//論理演算子
int a=10, b=10, c=20;
printf("%d\n", a==b && a==c); // a==bかつa==c
printf("%d\n", a==b || a==c); // a==bまたはa==c
printf("%d\n", !(a==b)); // a==bの否定
// インクリメント演算子
++a; // a = a + 1;
a++; // a = a + 1;
// デクリメント演算子
--a; // a = a - 1;
a--; // a = a - 1;
-
++a;
は式の値はインクリメント後の値で、a++;
は式の値はインクリメント前の値。 - 例えば
int a=0;
の時、a++ == 0
は1で++a == 0
は0になる。
入力
int i;
float x;
double y;
scanf("%d", &i);
scanf("%f", &x);
scanf("%lf", &y);
printf("i=%d, x=%f, y=%f\n", i, x, y);
- 入力はscanf()関数を使う。stdio.hライブラリに搭載
- &は「 アドレス演算子 」その変数のメモリ上のアドレスの値が返る。
関数
#include <stdio.h>
int func(int i); // プロトタイプ宣言
int main(void){
int a;
a = func(3);
}
// 引数を2倍にして返す関数
int func(int i){
return i * 2;
}
- プロトタイプ宣言 とは、引数の数、各引数の型、戻り値の型など、関数の形式に関するプロトタイプだけをプログラム前半に宣言するもの。
条件分岐
// if文
int a;
scanf("%d", &a);
if(a > 100){
printf("100より大きい\n");
}else{
printf("100以下\n");
}
// switch文
int a;
scanf("%d", &a);
switch(a){
case 10: // a==10の時
printf("10です\n");
break;
case 20: case30: case: 40: // a==20 || a==30 || a==30の時
printf("20か30か40です\n");
break;
default: // 上記のどれでもない時
printf("10,20,30,40ではない\n");
}
- switch文は
break;
を忘れると、switch文を抜けず、次へ突入する。
ループ
// while文
// まず条件を検査し、条件が真である間一定の処理を繰り返す
int i = 0;
while(i++ < 100){
printf("%d", i);
}
// do-while文
// まず一連の処理を実行し、後から条件を検査し、条件が真である間繰り返す
int i = 0;
do{
printf("%d", i);
}while(i++ < 100);
// for文
/* カウンタ変数の初期化
* 条件判定
* 処理の実行
* カウンタ変数の更新
*/
int i;
for(i=0; i<100; i++){
printf("%d", i);
}
- ループの実行文の中に
break;
と記述することでループを抜けることができる。