こんにちは!フリーランスの長野です。
プログラミングでよく使うのが変数ですよね。C言語でも数字や文字列などの型を指定し値を格納する変数にそれぞれ名前を付けて、その変数名を使って処理を記述します。
その変数名に代入する値を必要に応じて変えることで処理結果が変わってきます。
この記事では、型と変数について
など、まとめ的な内容についても解説していきます。今回は型と変数について、使い方をわかりやすく解説します!
変数、型とは
変数とはデータを格納しておく領域のことです。変数は通常メモリ上に確保され、値を代入したり参照したりすることができます。
それぞれの領域を区別するために変数名を付けて宣言します。また型とは、数字や文字などのデータをメモリ上に確保する領域やバイト長、確保した領域の扱い方などを指定するものです。
変数の宣言
変数の宣言は次のように記述します。
記憶域クラス名 型修飾子 型名 変数名;
記憶域クラスとは、変数を格納する記憶領域を指定するものです。型修飾子とは、変数の用途をこまかく指定するものです。
変数の初期化と値の代入
変数は必要に応じて宣言時に初期化する場合もあります。また同じ型の変数は「,」(カンマ)区切って1行で宣言する場合もあります。
また値や式の代入は次のように記述します。
変数名 = 式;
値を参照する場合は、変数名を使って参照します。
それでは型および記憶域クラス、型修飾子についても詳しくみていきましょう!
型の一覧(サイズ、範囲)
型とは、数字や文字などのデータをメモリ上に確保する領域やバイト長、確保した領域の扱い方などを指定するものです。
型には以下のような種類があります。
型名 | 説明 |
---|---|
void | 型なし |
char | 文字型 |
int | 整数型 |
float | 単精度浮動小数点型 |
double | 倍精度浮動小数点型 |
struct | 構造体 |
union | 共用体 |
enum | 列挙型 |
型はshort、long、unsigned、signedなどの型修飾子と組み合わせて、変数のバイト長や値の範囲が決められます。
主なデータ型は以下のとおりです。
種類 | データ型 | データ型の名称 | バイト長 | 値の範囲 |
---|---|---|---|---|
型なし | void | void型 | ー | ー |
文字列 | (unsigned) char | (符号なし)文字型 | 1 | 0~255 |
signed char | 符号付き文字型 | 1 | -128~127 | |
整数型 | unsigned short int | 符号なし短整数型 | 2 | 0~65535 |
(signed) short int | (符号付き)短整数型 | 2 | -32768~32767 | |
unsigned int | 符号なし整数型 | 4 | 0~4294967295 | |
(signed) int | (符号付き)整数型 | 4 | -2147483648~2147483647 | |
unsigned long int | 符号なし長整数型 | 4 | 0~4294967295 | |
(signed) long int | (符号付き)長整数型 | 4 | -2147483648~2147483647 | |
unsigned long long int | 符号なし長長整数型 | 8 | 0~18446744073709551615 | |
(signed) long long int | (符号付き)長長整数型 | 8 | -9223372036854775808 ~9223372036854775807 |
|
浮動小数点型 | float | 単精度浮動小数点型 | 4 | 最小の正の数:1.175494e-38 最大値:3.402823e+38 |
double | 倍精度浮動小数点型 | 8 | 最小の正の数:2.225074e-308 最大値:1.797693e+308 |
変数の値を表示する方法
変数の値を表示するには、printf関数を使用します。
int型の変数の値を表示する例について、サンプルコードで確認しましょう。
#include <stdio.h> int main(void) { int num = 1234; printf("num: %d\n", num); return 0; }
実行結果:
num: 1234
printf関数を使って出力表示する方法については、こちらで詳しく解説していますので、ぜひ参考にしてくださいね。
型の変換について
例えばint型の変数をdouble型の変数として使いたい場合があります。そんな場合は型変換を行う必要があります。
型変換については、こちらで詳しく解説していますので、ぜひ参考にしてくださいね。
記憶域クラスについて
記憶域クラスとは、変数を格納する記憶領域を指定するものです。
記憶域にはメモリの割り当て方で3種類に分けられます。自動記憶域のスタック領域と、静的記憶域のスタティック領域とヒープ領域です。
また、この他にもデータを記憶する領域としてCPU内のレジスタが使われることがあります。
記憶クラス名について下記のように簡単にまとめています。
記憶域クラス名 | 説明 |
---|---|
extern | 複数のソースファイルで1つの変数を共有する |
static | ファイルの有効範囲内:他のソースファイルから隠ぺい ブロックの有効範囲内:前の値を保存 |
auto | 一般的に省略 |
register | レジスタを使用 |
typedef | データ型に別名を付ける |
auto、staticについて
スタック領域では自動的にメモリの割り当てと解除が行われます。したがって自動変数と呼ばれ、記憶クラス名は「auto」を使用しますが、記述を省略するのが一般的です。
記憶域クラスの指定のない変数は自動変数ということになります。スタティック領域ではプログラムの起動時にメモリが割り当てられ、プログラム終了時まで割り当てが変化しません。記憶クラス名は「static」を使用します。
なお、「static」と「auto」の詳しい説明や使い方についてはこちらを参考にしてくださいね!
externについて
C言語ではコンパイルの際に1個のソースファイルを機械語に翻訳して1個のオブジェクトファイルを作成します。
その際に「結合」と呼ばれる変数名とメモリのアドレスの対応付けを行います。1個のオブジェクトファイルに限定した結合を内部結合、他のオブジェクトファイルとの結合を外部結合と呼びます。記憶クラス名は「static」は内部結合で使用し、外部結合では「extern」を使用します。
「extern」の詳しい説明や使い方についてはこちらを参考にしてくださいね!
参考:malloc、freeについて
また、ヒープ領域ではプログラムの実行中に必要なメモリを確保したり、解放したりします。mallocやfreeなどの関数を使用します。
mallocやfreeなどの詳しい説明や使い方についてはこちらを参考にしてくださいね!
registerについて
CPU内のレジスタはアクセスが比較的高速で、可能な限り高速に処理したい場合に使われことがあります。ただし、レジスタを使用したからといって必ずしも高速になるとは限りません。記憶クラス名は「register」を使用します。
typedefについて
その他の記憶クラス名には「typedef」があります。データ型に新しい型を付ける場合に使用し、構造体を宣言するときなどによく使われます。
「typedef」を構造体の宣言で使用する場合の詳しい説明や使い方についてはこちらを参考にしてくださいね!
型修飾子について
型修飾子とは、変数の用途をこまかく指定するものです。型修飾子にはshort、long、unsigned、signedなどの変数のバイト長や値の範囲を決める修飾子のほかに、const、restrict、volatileなどがあります。
型修飾子について下記のように簡単にまとめています。
型修飾子 | 説明 |
---|---|
short | 短 |
long | 長 |
signed | 符号付き |
unsigned | 符号なし |
const | 定数化 |
restrict | 最適化を促進 |
volatile | 最適化を抑制 |
constについて
「const」は変数を定数として扱う場合に使用します。
「const」の詳しい説明や使い方についてはこちらを参考にしてくださいね!
restrictについて
「restrict」はポインタに用いる型修飾子です。
そのポインタが指す先を同一関数・同一ブロック内の別のポインタが指さないようにコンパイラに指定することができます。そうすることでコンパイラの最適化を促進しますが、目に見える動作は変わりません。
memcpy関数などの引数で使用します。
void *memcpy(void restrict *buf1, const void restrict *buf2, size_t n);
memcpy関数の詳しい説明や使い方についてはこちらを参考にしてくださいね!
volatileについて
「volatile」は割り込み処理や他のスレッドから変数が変更される可能性がある場合などに指定します。
変数がコンパイラのあずかり知らないところで変更される場合に使われ、コンパイラの最適化によって起こる不具合を回避することができます。
まとめ
ここでは、型を指定し変数を宣言する方法について説明しました。
記憶域クラスや型修飾子を使うことで変数の役割を変えることができます。それぞれ使いこなすことができるように、この記事を何度も参考にして下さいね!