C言語基礎からマスター4-プログラム構成とメモリ構造-

C言語基礎からマスター

はじめに

前回の第三回目では、独自の関数を作成していく中で関数の形を解説し、型や変数、演算子といったC言語の文法について学びました。

第四回目は、第三回で作成した足し算を計算する関数を実際に動かしてみます。動かすにあたってC言語のプログラム構成について学び、プログラムで使われている関数や変数がコンピュータの中でどのように扱われているのか解説していきたいと思います。

このブログシリーズは、C言語文法の基礎を例題プログラムから学んでマスターしていくものです。

それでは、はじめていきます。

前回の復習

前回では、次のような足し算の計算をする関数add1をつくりました。

int add1(int x,int y)
{
	int p;
	p = x + y;
	return(p);
}

この関数は、引数にint型の2つの変数xとyをもち、int型の計算結果を戻り値として返します。

処理部分では、計算結果を保存するint型の変数pを定義して、その変数pに引数から渡されてきた2つの値の和を代入しています。

ここで、算術演算子「+」や代入演算子「=」という演算子が使われています。

戻り値は、「return( )」で返すということも解説しました。

詳しくは前回の記事を参照してみてください。

今回は、この関数をどう使うかという部分に進んでいきます。

関数のプロトタイプ宣言

作成したプログラムを実際に呼び出すとなったときに必要となるのが関数のプロトタイプ宣言です。

プロトタイプ宣言といわれてもピンとこないですよね。プロトタイプは「原型」と日本語で訳されるのですが、原型といっても何を意味するかよく分からないと思います。

自作の関数を使うとき、C言語では、その処理を記述した実体の部分とは別にその関数の戻り値の型、関数名、引数をコンパイラに知らせる必要があります。これがプロトタイプ宣言というものになります。

プロトタイプ宣言は、ルールとして書き方を覚えてしまえばよいと思います。

add1関数のプロトタイプ宣言は、次のようになります。

int add1(int x,int y);

作成した関数名の記述部分にセミコロン「;」を付けただけです。

これがプロトタイプ宣言です。これをプログラムの先頭部分に記述します。

add1関数を呼び出すプログラム

では、add1をmain関数の中で呼び出すプログラムをつくってみます。

プログラム1行目は、printf関数を使うためにstdioライブラリの読み込みを行っています。

3行目がプロトタイプ宣言になります。関数add1をmain関数で使うため、ここで宣言します。

7行目から9行目がmain関数の処理部分です。ここで、add1関数を呼び出して計算結果をint型変数resに入れて、その結果をprintf関数で画面出力しています。

12行目から17行目が足し算の計算をするadd1関数の本体部分のプログラムになります。

この部分は、前回作成したものと同じです。

このプログラムを実行すると「3」という結果が得られます。

printf("%d \n",res);

とさらっと書いていますが、%dや\nという記号は何を意味しているのか疑問が生じると思います。

これまでは、文字列を表示するprintfを見てきました。

printf("Hello World!!");

文字列をダブルクォーテーション「” “」で囲うとその文字列を表示してくれるのがprintf関数の処理でした。

ここでprintf関数が新しい使い方をしているのでその説明をしたいと思います。

printf関数の仕様

printf関数の仕様はこのようになっています。

printf関数、実は、int型の戻り値があります。厳密なプログラムをつくるには、戻り値をint型変数で受けて、その値が負値のチェックをする必要があるのですが、それはその時々、プログラムによってになるかと思います。これまでprintfの戻り値を受けていなかったように戻り値は、その値を変数に代入しなくてもエラーにはなりません。

printf関数の引数には、ダブルクォーテーションで囲った引数と書式変換する変数の引数があります。

printf("Hello World!!");

のように出力する文字列に変換文字がない場合は、書式変換する変数を持たない形で記述できます。

printf関数には、変数の値を文字列に変換して出力することができます。

それが%記号を付けた文字になります。また、出力を改行するには、「\n」を記述します。

printf関数の変換文字には次のようなものがあります。

変換文字引数の型変換フォーマット
dint10進数出力
oint符号なし8進数出力
x,Xint符号なし16進数出力 10~15→a~f / A~F
uint符号なし10進数出力
cint単一文字出力
schar *文字列出力
fdouble小数点出力 m.dddddd
e,Edouble小数点出力 m.dddddd e±xx / m.dddddd E±xx
%変換されない%を出力する

ファイル内の構成

C言語プログラムは、処理部分、すなわち、ソースコードが書かれたソースファイルと定義などが書かれたヘッダファイルからなり、ヘッダファイルは、「#include」というキーワードを使って呼び出すことができます。

ソースファイルのファイル構成は、宣言部と関数部からなります。

宣言部は、先ほど出てきた関数のプロトタイプ宣言やヘッダファイルの呼び出しなどが書かれています。また、関数部は、main関数や自作の関数を記述した部分になります。ソースファイルは大きく分けてこの宣言部と関数部に分かれます。

関数部をさらにみると、関数使用部、関数実体部に分かれます。

関数使用部は、関数を呼び出す部分、関数実体部はその関数の処理を記述したプログラム部分です。

ソースファイル全体をみると、このような要素で構成されています。

メモリに配置される変数と関数

ここまでwindowsパソコンを使ってVisual Studioという開発環境のC言語コンパイラを使ってプログラムをつくってきましたが、Raspberry PiやESP-32、Arduinoのようなマイクロコンピュータ(マイコン)視点で少しお話しをしたいと思います。

マイコンのような小さなコンピュータは、パソコンのような高速処理はできないですし、大容量のプログラムを書き込むこともできません。限られたコンピュータの資源(リソース)、つまり限られた演算能力や記憶領域の大きさの中でプログラムを組んで実行していくことになります。

コンピュータは、プログラムを読み出して解釈し実行するという演算を行います。演算処理は中央演算装置:CPU(Central Processing Unit)で実行されますが、プログラムやデータを保持したり一時的に退避したりする場所として記憶領域(メモリ)が必要となります。

マイコンでは、メモリの容量が小さいのでプログラムや使うデータもなるべく無駄なく作成する必要があります。その点がパソコン上のプログラミングとの違いでもあります。

これまで解説してきたプログラム(関数)や変数というものは、メモリ空間と呼ばれる記憶領域を番地で管理する空間に割り当てます。この番地のことを「アドレス」といいます。

変数にもいろいろな分類があり、定数というものもまだ扱っていないですが、変数を含む様々なデータやプログラムはすべてメモリの中にあるということです。

前回解説した変数の型の一覧表にあったサイズは、このメモリのサイズということになります。

例えば、long型は4バイトというサイズを持ちます。long型は、メモリ空間上のアドレス4番地分を使用するということになります。上の図の例では、long型の変数aには、0x12345678という数値(先頭の0xは16進数表記という意味)を代入演算子で代入しています。このプログラムの裏では、自動的にアドレス4バイト分が変数aに割り当てられているのです。

まとめ

第四回では、前回作成した足し算を計算する関数を実際に動かしてみました。そして、C言語のプログラム構成やプログラムで使われている関数や変数がコンピュータの中でどのように扱われているのかを解説しました。

メモリ空間というコンピュータ内部の話も出てきて少し専門的なところもありましたが、プログラムや変数などは、メモリに配置されているということが理解できるとC言語文法の最難関であるポインタが分かりやすくなると思います。メモリの話はポインタのときにさらに詳しく解説していきたいと思います。

次回は、直接探索プログラムからC言語の制御文と配列についてみていきます。制御文と配列をマスターできれば、作りたいプログラムを自分で組んでいけるようになると思います。

新・明解C言語 入門編 第2版 [ 柴田望洋 ]

価格:2,530円
(2022/9/4 21:34時点)
感想(0件)

コメント

タイトルとURLをコピーしました