情報処理のWeb教科書―IPA情報処理試験対策のお供に!
C言語のプログラムの書き方から、for文、if文なのど構文、フローチャートの書き方など、C言語プログラミング入門レベルの内容を、簡単なプログラムなら自由に作成できるレベルを目指して、初歩的なC言語の基本文法についてみていきます。
この記事の目次です。
1. コードとコメント
2. 変数の使用方法
3. 配列
4. 演算子
5. 制御文の種類とフローチャートの書き方
6. 関数
7. 変数のスコープ
8. コマンドライン引数
9. 構造体
10. ポインタ
C言語の入門知識として、はじめにC言語のソースコードはどのようなものか見てきます。
/* コメント1 */ #include <stdio.h> int main(void){ printf("Hello World!!\n"); return 0; //コメント2 }
C言語のコードは、C言語用のコンパイラを使用して、コンパイルを行って、実行できる形式の実行形式ファイルを作成します。
C言語を使用する場合は、あらかじめコンパイルして実行形式ファイルを用意して、プログラムを利用します。
コマンドプロンプトでソースファイルを保存したフォルダに移動しgccコマンドを実行してコンパイルします。 例えば、テストフォルダにhello.cというソースファイルを作成した場合は以下のようにコマンドを実行します。
>cd test
>gcc hello.c
a.exeというファイルができたフォルダにコマンドプロンプトで移動し、 a.exeとコマンドラインに入力すると「Hello World!!」と出力されます。
>a.exe
Hello World!!
プログラムのソースコードで扱われるデータを一定期間記憶して、必要なときに利用できるよう、データに固有の名前を付けて保管しておく変数という仕組みがあります。
変数(へんすう、variable)は、プログラム内の名前を付けたデータの保管先のことをいいます。 変数を使用して、プログラム内でデータを保管して利用することができます。
変数には値を記憶させることができます。 この値には、いくつかの「種類」があります。 値の種類は、データ型(data type)、または型と呼ばれます。
C言語のデータ型には以下のような種類があります。
型名 | 説明 |
---|---|
void | 型なし |
char | 文字型 |
int | 整数型 |
float | 単精度浮動小数点型 |
double | 倍精度浮動小数点型 |
struct | 構造体 |
union | 共用体 |
enum | 列挙型 |
なお、データ型はshort、long、unsigned、signedなどの型修飾子と組み合わせて、変数のバイト長や値の範囲が決められます。
このページでは、C言語で文字(char)型のデータを変数で扱う方法について説明します。
ソースフォルダに以下のサンプルコードを記述したテキストファイルを作成します。
#include <stdio.h>
int main(void) {
char c = 'H';
printf("%c", c);
c = 'e';
printf("%c", c);
c = 'l';
printf("%c", c);
c = 'l';
printf("%c", c);
c = 'o';
printf("%c", c);
c = '!';
printf("%c", c);
return 0;
}
文字(char)型の値はシングルコーテーション(')で囲んで表現します。
サンプルコードでは、cという文字(char)型の変数に 'H'、'e'、・・・、'!'という文字を順番に設定(代入)して表示し、「Hello!」と出力しています。
printf関数にカンマ区切りで引数を2つしていしており、1つ目に%cを設定し、2つ目の引数で指定した変数cの値が出力されるようにしています。
コマンドプロンプトでソースファイルを保存したフォルダに移動しgccコマンドを実行してコンパイルします。
>cd test
>gcc hello.c
a.exeというファイルができたフォルダにコマンドプロンプトで移動し、 a.exeとコマンドラインに入力すると「Hello!」と出力されます。
>a.exe
Hello!
C言語で整数(int)型のデータを変数で扱う方法について説明します。
ソースフォルダに以下のサンプルコードを記述したテキストファイルを作成します。
//ファイル名:sample.c
#include <stdio.h>
int main(void)
{
int i = 0;
printf("%d\n", i);
i = 1;
printf("%d\n", i);
return 0;
}
サンプルコードでは、iという整数(int)型の変数に 0、1という数を順番に設定(代入)して出力しています。
printf関数にカンマ区切りで引数を2つしていしており、1つ目に%dを設定し、2つ目の引数で指定した変数iの値が出力されるようにしています。
コマンドプロンプトでソースファイルを保存したフォルダに移動しgccコマンドを実行してコンパイルします。
>cd test
>gcc sample.c
a.exeというファイルができたフォルダにコマンドプロンプトで移動し、 a.exeとコマンドラインに入力すると0と1の数字が改行されて出力されます。
>a.exe
0
1
C言語の配列について見ていきます。
配列とは、同じ種類のデータを、複数まとめて扱うことのできる変数です。
配列は次のような書式で宣言します。
データ型 配列名[個数];
ここではC言語で文字(char)型の配列を変数で扱う方法について説明しています。
ソースフォルダに以下のサンプルコードを記述したテキストファイルを作成します。
//ファイル名:hello.c
#include <stdio.h>
int main(void) {
char message[] = "Hello World!!";
printf("%s\n", message);
return 0;
}
サンプルコードでは、messageという文字の配列(文字の型charの配列を示すため[]を付与)を格納する変数に「Hello World!!」という文字の配列(文字列)を初期値として設定(代入という)して 変数を宣言しています。
printf関数にカンマ区切りで引数を2つしていしており、1つ目に%sを設定し、2つ目の引数で指定した変数messageの値が出力されるようにしています。
コマンドプロンプトでソースファイルを保存したフォルダに移動しgccコマンドを実行してコンパイルします。
>cd test
>gcc hello.c
a.exeというファイルができたフォルダにコマンドプロンプトで移動し、 a.exeとコマンドラインに入力すると「Hello World!!」と出力されます。
>hello
Hello World!!
C言語の演算子の使用方法について見ていきます。
2=1+1のような計算式がある場合、=と+のような記号のことを演算子(operator)と呼びます。 詳細ではC言語の演算子についてまとめています。優先順位やノットイコール、アロー演算子、サンプルプログラムでは四則演算アプリなども紹介しています。
プログラミングに無くてはならないのは制御文です。フローチャートの書き方を示しつつ、C言語の制御文(分岐)の方法について説明しています。
関数とは、プログラムの記述として、何度も使用する命令のかたまりをまとめ、名前を付けたグループ化されたコードです。
「int a(){処理;}」のようにaという名前の関数を記述します。なお、C言語のmain関数はプログラムの開始時にはじめに実行される特別な関数になります。
関数はパラメータを引数で受け取り、return文で戻り値を呼び出し元にデータを返します。 データを返却しないものや引数がないものも定義できます。 なお、関数の引数や戻り値のデータ型もあらかじめ定義する必要があります。
戻り値の型 関数名(引数1,引数2…) {
retrun 戻り値;
}
引数と戻り値がある関数の例です。引数の値を足して、結果を戻り値に設定します。
#include <stdio.h> int add(int a, int b) { return a + b; } int main(void) { printf("%d\n", add(1, 1)); return 0; }
以下は、引数と戻り値がない関数の例です。 引数はブランク、voidという型無しを表す型のキーワードを戻り値の型に設定します。 関数内でreturn文は省略できます。
#include <stdio.h> void hello() { printf("Hello World!!\n"); } int main(void) { hello(); return 0; }
プロトタイプ宣言を行うと関数の定義をmain関数の後に記述できるようになります。 void hello();が関数のプロトタイプ宣言になります。 関数名と引数、戻り値が何かをあらかじめ知らせることでmain関数で使用するhello()関数が何かコンパイラー側が解決できるようになります。
#include <stdio.h> void hello(); int main(void) { hello(); return 0; } void hello() { printf("Hello World!!\n"); }
C言語のスコープ(変数)について見ていきます。
変数の宣言時に「記憶クラス指定子」を付けることで、変数のスコープを設定することができます。 また、変数がローカルかグローバルかにより変数の寿命を変えることができます。
種別 | 記憶クラス指定子 | スコープ | 寿命 |
---|---|---|---|
ローカル変数 | なし | ブロック内 | ブロック内 |
static | ブロック内 | プログラム終了まで | |
extern | スコープ | プログラム終了まで | |
グローバル変数 | なし | プログラム全体 | プログラム終了まで |
static | ファイル単位 | プログラム終了まで | |
extern | プログラム全体 | プログラム終了まで |
コマンドライン引数とは、プログラムをコマンドラインで実行する際にプログラムに引き渡すパラメータをいいます。 C言語のコマンドライン引数とは何か概要を見ていきます。
受け取ったコマンドライン引数を表示してみます。
#include <stdio.h> int main(int argc, char** argv) { int i; printf("引数の個数 = %d\n", argc); for (i = 0; i < argc; i++) { printf("引数%d = %s\n", i, argv[i]); } return 0; }
上記のコードをWindows用のコンパイラでコンパイルして実行した例です。
C:\sample>sample.exe 1 2 3 引数の個数 = 4 引数0 = C:\sample\sample.exe 引数1 = 1 引数2 = 2 引数3 = 3
argcに引数の数が設定され、上記のコードでは、4が設定されています。
argvに引数自体の値が文字列(char型の配列)の配列で格納されます。
argvはプログラム名から格納されます。上記のコードでは、「C:\sample\sample.exe」が設定されています。
コマンドライン引数は、文字列となります。数値に変換して利用したい場合は変換が必要です。
#include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { int i; printf("引数の個数 = %d\n", argc); for (i = 0; i < argc; i++) { printf("引数%d = %d\n", i, atoi(argv[i])); } return 0; }
stdlib.hをインクルードして、atoi()を使用することで文字列を数値に変換できます。
C:\sample>sample.exe 1 2 3 引数の個数 = 4 引数0 = C:\sample\sample.exe 引数1 = 1 引数2 = 2 引数3 = 3
atoi()に数字以外の文字列が設定されると「0」となります。
C:\sample>sample.exe a b c 引数の個数 = 4 引数0 = C:\sample\sample.exe 引数1 = 0 引数2 = 0 引数3 = 0
C言語には、複数のデータを一まとまりにする構造体という仕組みが用意されています。
structの直後に「タグ名」、構造体内の各データのことを「メンバ」と呼びます。 たとえば、次のように定義します。
struct Person { char name[64]; char address[256]; }
C言語ではtypedefを使用することで既にあるデータ型に新しい名前をつけることができます。
typedef 既存のデータ型 新しい名前;
たとえば、構造体のPersonに別の名前(User)をつける場合は以下のように記述します。
typedef Person User;
たとえば、typedefでUserの名前をつけていないと、gccやg++コンパイラで「error: 'User' does not name a type」のように出力されます。
C言語のポインタについて見ていきます。
コンピュータのメモリにはアドレスがあり、そのアドレスを扱う変数をポインターといいます。 ポインタを使用することで、データのメモリの位置を保存して参照したり変更したりすることができます。
コンピュータは補助記憶にあるプログラムをメモリにロードしてCPUが実行します。 またメモリ内の管理はOSが行っていて、メモリにアドレスを振って管理しています。
以下は、コンピュータの仕組みの参考情報になります。
プロセッサとは、CPUとの違いはMPUなども含む装置の総称です。CPU、MPU(マイクロプロセッサ)など処理装置の総称のことをいいます。プロセッサについての技術知識をまとめています。
オペレーティングシステムとは、OSのことですが、種類と特徴、機能、タスク管理などOSとはどのようなものかついてまとめています。
プログラムのソースコードで扱われるデータを一定期間記憶して、必要なときに利用できるようにするため、 そのデータに固有の名前を付けて保管しておく仕組みがあり、変数はプログラム内の名前を付けたデータの保管先です。 プログラム内でデータを保管して利用するために変数を使用します。
変数や値のアドレスを取得するにはアドレス演算子(&)を使用します。
#include <stdio.h> int main(void) { int n; printf("&iの値は%p\n", &n); return 0; }
printfでの%pはポインタの値を表示する書式指定です。
gcc sample.c
例)
>a.exe
&iの値は0060FF1C
ポインタは、アドレスを代入して初期化しなければなりません。 ポインタにアドレスを代入してはじめて、ポインタの指すアドレスを見たり、そのアドレスの変数に記憶してある値を操作することができます。
C言語のポインタの宣言は、intなどのデータ型の後ろに「*」をつけます。
ポインタの初期化の例です。
int *p; /*ポインタpの宣言*/ int n; /*変数nを宣言*/ p = &n; /*ポインタpを変数nのアドレスで初期化*/ *p = 999; printf("アドレス(%p)の変数の値は、%dである。\n", p,*p);
ポインタの初期化の間違いの例です。 ポインタに何もアドレスが記憶されていないのでそのアドレスの変数に値は代入できません。
int *p; //ポインタpの宣言 *p = 999; printf("アドレス(%p)の変数の値は、%dである。\n", p,*p);
//ファイル名:Sample1.c #include <stdio.h> int main(void) { int *p; /*ポインタpの宣言*/ int n; /*変数nを宣言*/ p = &n; /*ポインタ変数pを変数nのアドレスで初期化*/ *p = 999; printf("アドレス(%p)の変数の値は、%dである。\n", p,*p); return 0; }
gcc Sample1.c
作成したa.exeというファイルと同じディレクトリでSample1とコマンドラインに入力して、 「アドレス(16進数の数字)の変数の値は、999である。」と出力されます。
例)
>a.exe
アドレス(0012FF88)の変数の値は、999である。
//ファイル名:Sample2.c
#include <stdio.h>
int main(void) {
// 変数nに9999を代入して表示
int n = 9999;
printf("変数nのアドレス(%p)の値は、%dである。\n", &n, n);
// 変数pにnのアドレスを代入して表示
int *p = &n;
printf("変数pのアドレス(%p)の値は、%dである。\n", p, *p);
// 変数p経由でnの値を変更して表示
*p = 8888;
printf("変数nのアドレス(%p)の値は、%dである。\n", &n, n);
return 0;
}
gcc Sample2.c
作成したa.exeというファイルと同じディレクトリでa.exeとコマンドラインに入力して、以下のように表示されます。
変数nのアドレス(16進数の数字)の値は、9999である。 変数pのアドレス(16進数の数字)の値は、9999である。 変数nのアドレス(16進数の数字)の値は、8888である。
ポインターに配列のアドレスを設定すれば、ポインターで配列が扱えます。 また、ポインターの配列を利用することで複数の文字列が扱えます。
#include <stdio.h> void hello(char *str) { printf("Hello %s!!\n", str); } int main(void) { char *str = "World"; hello(str); return 0; }
コンパイルし、実行すると以下のように表示されます。
Windows)a.exe Linux) ./a.out Hello World!!
C言語の構造体とポインターについて解説しています。
構造体は複数のデータを一まとまりにして扱えますが、その分構造体変数のデータサイズが大きくなりますので、関数の呼び出しの際に毎度大きなデータのコピーが行われるなど、メモリ使用量や処理速度に影響が懸念されます。
関数の引数など構造体はポインタで渡す工夫が必要です。 そうすることでアドレス(32bitの場合は4バイト)のみのデータサイズですみます。
構造体のメンバへのアクセスには、「.」、ドット演算子を使用しますが、構造体のデータを指し示すポインタについては、ドットではなくて、「->」、アロー演算子を使用します。
たとえば、次のように定義します。
struct Person { char* name; char* address; }
アロー演算子の利用例は以下になります。
struct Person *person; person = malloc(sizeof(struct Person)); person->name = strdup("太郎");
Windowsでも使えるフリーソフトのgccコンパイラで学ぶC言語入門用のオリジナルテキストをまとめています。 フリーソフトのgccコンパイラのインストール方法や基本文法はもちろんですが、分割コンパイルやヘッダーファイルの作成方法など入門者にとって気になる内容もまとめています。
プログラミング作法などプログラミングについてまとめています。Python、C言語、流れ図などプログラミングのオリジナル入門テキスト問形でまとめています。
Copyright (C) 2010-2023 情報処理のWeb教科書. All Rights Reserved. Loarding…