C言語のあれこれ3(基本的な値型の種類と構造体の作成方法)
はじめに
以下の記事の続きになります。
C言語のあれこれ1(Hello Worldの解読)
コードだけざっと見たいという方はこちらのgithubのページを参照してください
以下の順番で作成していきます。
- 変数と定数の作成方法
- 基本的な値型の種類と構造体の作成方法 <=今回の記事
- 関数の作成方法
- 計算するための演算子の説明
- 条件に関する演算子と条件分岐、繰り返し文の作成方法
- 配列を伴わないポインタの使用方法
- 配列を伴ったポインタの使用方法
- プリプロセッサの利用方法
本編
ここでは基本的な値型の種類と構造体を記述します
signed char型
一番最小の型です。
サイズは1byte(8bit)になります。
signed char c_value = 0;
unsigned char型
signed char型の符号なし型になります。
unsigned char uc_value = 0;
char型
signed charとunsigned charとは別の型です(サイズはsigned char
char型には'で囲った1文字のみを入れるか、直接数値を入れることが可能です。
ここでは'\0' == 0を入れています
char c_value = '\0';
※int型以降はsignedまたはunsignedのいずれかになるのに対してなんでこの型だけ入れられないんですかね???
int型(signed int型)
基本的な数値を入れる代表的な型です
int i_value = 0;
unsigned int型
int型の符号なし(+-がない)型になります。そのため負の値がなく、その分最大値が約2倍近く多くなります。
unsigned int ui_value = 0;
short型 (signed short型)
こちらも整数を入れる型になります
short s_value = 0;
unsigned short型
short型の符号なし型になります。
unsigned short us_value = 0;
long型 (signed long型)
整数型では最大の容量を誇る型です
long l_value = 0;
unsigned long型
long型の符号なし型になります。
unsigned long ul_value = 0;
整数型のサイズは基本的に以下のようになります。
char == unsigned char == signed char
< short == unsigned short
<= int == unsigned int
<= long == unsigned long
&&
short < long
float型
小数点の計算ができる浮動小数点型になります。
浮動小数点型には符号の有無の概念がないため、基本的にはすべて符号ありになります。
float f_value = 0.0f;
double型
float型よりも大きい浮動小数点型になります。
double d_value = 0.0;
long double型
double型よりも大きい浮動小数点型になります。
long double ld_value = 0.0;
C言語のバージョンアップにより追加された型
long long型 (signed long long型)※C99以降
long型よりも大きい整数型になります。
long long ll_value = 0;
unsigned long long型※C99以降
long long型の符号なし型になります。
unsigned long long ull_value = 0;
cast
代入や四則演算子を利用する際に型を変更することができます。
型を変更することをcast(キャスト)と言います。
計算式でcastを利用する場面がちらほらあり、
例えば、以下の内容の計算があるとします。
int num1 = 3,num2 = 5;
float res = num1 / num2;
この時、int型のまま割り算の計算をされてしまうため、resの値は0.6fではなく0.0fになってしまいます。
そこで利用されるのがcastになるわけです。
castの利用方法は次の通りです
(型名) 変数名;//変数を別の型にしたい場合//
(型名) 定数名;//定数を別の型にしたい場合//
(型名) 関数名(引数);//関数の戻り値を別の型にしたい場合//
先程の式にあてはめると次のようになります。
int num1 = 3,num2 = 5;
float res = (float)num1 / (float)num2;
片方の(float)はいらないと言われるかもですが、私自身は安心するために両方に入れています。
この結果としてresの値は0.6fとなるわけです。
構造体
構造体は変数をまとめたものになります。
そのため構造体のサイズは基本的に利用した変数のサイズの合計値になります。
基本的な構文は次の通りです。
struct 構造体名
{
メンバー変数;
メンバー変数;
...
};
※構造体のメンバー変数には修飾子を付けられないため注意しましょう
以下は例になります。
struct Test
{
int m_i_value;
double m_d_value;
char m_c_value;
//NG
//static int s_value;
//extern int e_value;
};
構造体も通常の型と同じように宣言します。
struct 構造体名 変数名;
構造体のメンバー変数を利用する方法は次のように記述します。
変数名.メンバー変数
また構造体名は違う名前でも利用することが可能です。
方法は次の3種類になります。
#defineを利用する
#define TEST_STRUCT struct Test
TEST_STRUCT test;//-> struct Test test;
typedefを利用する1
typedef struct Test{}Test;
//typedef struct {}Test;でも可//
Test test;
typedefを利用する2(こちらの方法は値型でも利用可能です。)
typedef struct Test Test;
Test test;
※typedef
typedefは既存の型に別の型名を付与することができるキーワードです。
例えばint*型に対してPIntと別名を用意することができます。
typedefを利用するの項目で言えばstruct TestからTestと別名を用意する形になります。
この別名のことをエイリアスと言います。
エイリアスは英語でもある通り、簡単に言えば、別名になります。
これを利用すると、プログラムの可読性を増させることもできます。
以下はchar*に対して別名を付与するための例になります。
typedef char* CharString;
//char* cstrと同じ//
CharString cstr = "";
配列の作成
配列は値型、構造体どちらでも利用することができます。
この時必ず配列の要素数を指定する必要があります。
配列の作成方法は次の2つになります。
型名 変数名[配列数];
型名 変数名[] = {初期値,初期値...};
2つめの初期値は1個以上指定します。
int array[5];
int array2[] = {0,1,2,3,4,5};
配列から値を利用する場合は添え字を利用する必要があります。
取り出し方は次の通りです。
変数名[取り出す番号]
以下は使用例になります。
array[4];
この時取り出す番号は0番を先頭とした数字になります。
また、定義した配列以上の値を配列から取り出そうとするとエラーが起きるため、注意が必要です。
また、配列を関数の引数に利用するとポインタの様に動きます。
※それならポインタを入れてあげたほうが良い気がする...(詳細はこの後のポインタの説明で)
Discussion
int型にのみサイズが環境に依存することが明記されていますが、同様にshort intやlong intもそのサイズは環境依存となっています。また C99 及び C++11 からは
long long intなる整数型が追加されており、8バイト以上のサイズである保証があります。ご指摘ありがとうございます。
一部勘違いもあったため、こちらの内容は一旦削除するようにします。
参考資料 Oracle Help Center
参考資料2 Wikipedia
(環境の情報が媒体事に定まっていないように見え、shortとintは情報によってサイズが変わらない記述もあるためです)
long double が「C言語のバージョンアップにより追加された型」とされていますが,バージョンアップというのはいつを指していますか?最初の規格である C89 (ANSI C) から存在します.
ご指摘ありがとうございます。
失礼しました。
これは完全に誤った情報になっているので削除します。
参考資料を追加させていただきます。
C言語では
charとsigned charとunsigned charはそれぞれ別の型ですが誤解があるよう思います。ご指摘いただきありがとうございます。
windowsやmacOSなどの環境に慣れすぎていると実感します。これは明記しておいた方が今後よさそうと感じたため、記述するようにさせていただきます。
追記(2026/06/27:20:30):
今後この記事を大きく修正するタイミングを用意させていただきます。
改めてありがとうございます。
環境に関係なくC言語では
shortやintやlongやlong longはsignedがあってもなくても同じ型ですが、charとsigned charは別の型であることを誤解されてると思います。申し訳ございません。
本当に知らない内容になっており困惑しています。
Windowsでは規定値がsigned charと一致するようで、
出来ればソースを教えていただきたいです。
ご足労おかけしますが、よろしくお願いします。
一例挙げると https://kikakurui.com/x3/X3010-2003-01.html の『6.2.5 型』に
という説明と、注釈に
(略)
と書かれています。
この
charはsigned charやunsigned charとは異なる内容はclang(macOSのコンパイラ)でwarningが出ることも初めて知りました。こちらの記載部分はどう記述するかは後ほど考え直すようにします。
改めてソースまでいただきありがとうございました。
追記です。
WindowsのC++でも再度試したところchar型だけsigned charまたはunsigned charでエラーが起こりました。ですが
WindowsのC言語側ではいまだにsigned charはcharと認識されているためよくわかりません。※
Visual C(Visual Studio 2022)の環境のみですかね?改めて補足していただきありがとうございました。