C言語のあれこれ3(基本的な値型の種類と構造体の作成方法)

に公開
11

はじめに

以下の記事の続きになります。
C言語のあれこれ1(Hello Worldの解読)

C言語のあれこれ2(変数と定数の作成方法)

コードだけざっと見たいという方はこちらのgithubのページを参照してください

以下の順番で作成していきます。

本編

ここでは基本的な値型の種類と構造体を記述します

signed char型

一番最小の型です。
サイズは1byte(8bit)になります。

signed char c_value = 0;

unsigned char型

signed char型の符号なし型になります。

unsigned char uc_value = 0;

char型

signed charunsigned 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

yaito3014yaito3014

int 型にのみサイズが環境に依存することが明記されていますが、同様に short intlong int もそのサイズは環境依存となっています。
また C99 及び C++11 からは long long int なる整数型が追加されており、8バイト以上のサイズである保証があります。

1
とがとが

long double が「C言語のバージョンアップにより追加された型」とされていますが,バージョンアップというのはいつを指していますか?最初の規格である C89 (ANSI C) から存在します.

1
藤田望藤田望

char型(signed char型)

unsigned char型

C言語ではcharsigned charunsigned charはそれぞれ別の型ですが誤解があるよう思います。

1
Chronoss0518Chronoss0518

ご指摘いただきありがとうございます。

windowsmacOSなどの環境に慣れすぎていると実感します。
これは明記しておいた方が今後よさそうと感じたため、記述するようにさせていただきます。

追記(2026/06/27:20:30):
今後この記事を大きく修正するタイミングを用意させていただきます。
改めてありがとうございます。

藤田望藤田望

※申し訳ございませんが、筆者は基本的にWindows環境で開発しています。(signedunsignedの記載がない場合はデフォルトでsigned型になります)

環境に関係なくC言語ではshortintlonglong longsignedがあってもなくても同じ型ですが、charsigned charは別の型であることを誤解されてると思います。

1
藤田望藤田望

出来ればソースを

一例挙げると https://kikakurui.com/x3/X3010-2003-01.html の『6.2.5 型』に

三つの型charsigned char及びunsigned charを総称して文字型(character type)と呼ぶ。処理系は,charを,signed char又はunsigned charのいずれかと同じ値の範囲,同じ表現形式,そして同じ動作をするものとして定義しなければならない(35)。

という説明と、注釈に

(35) <limits.h>

(略)

いずれを選択したとしても,charsigned charunsigned charとは異なる型であり,いずれとも適合しない。

と書かれています。

1
Chronoss0518Chronoss0518

このcharsigned charunsigned charとは異なる内容はclang(macOSのコンパイラ)でwarningが出ることも初めて知りました。

こちらの記載部分はどう記述するかは後ほど考え直すようにします。

改めてソースまでいただきありがとうございました。

Chronoss0518Chronoss0518

追記です。

WindowsC++でも再度試したところchar型だけsigned charまたはunsigned charでエラーが起こりました。

ですがWindowsC言語側ではいまだにsigned charcharと認識されているためよくわかりません。
Visual C(Visual Studio 2022)の環境のみですかね?

改めて補足していただきありがとうございました。