C プログラミング言語では、データ型はデータ要素の保存の意味と特性を構成します。これらは、メモリ位置または変数の宣言の形式で言語構文で表現されます。データ型は、データ要素の処理方法や操作の種類も決定します。
C言語は、整数型や実数型などの基本的な算術型と、配列型や複合型を構築するための構文を提供します。includeディレクティブを介して使用されるC標準ライブラリのヘッダーには、特定のハードウェアプラットフォーム上の言語実装に依存しない正確なサイズのストレージを提供するなどの追加のプロパティを持つサポート型の定義が含まれています。[1] [2]
主なタイプ
主な種類
C 言語には、char、int、float、double の4 つの基本的な算術型指定子と、 signed、unsigned、short、long の修飾子が用意されています。次の表は、ストレージ サイズ固有の宣言の大規模なセットを指定する場合に許容される組み合わせを示しています。
- ^ abcde 最小範囲[−(2 n −1 −1), 2 n −1 −1] (例 [−127,127]) は、標準で許可されているさまざまな整数表現 ( 1 の補数、符号絶対値、2 の補数) に由来します。[4]ただし、ほとんどのプラットフォームでは 2 の補数を使用するため、これらの実装ではm ≥ nの[−2 m −1 , 2 m −1 −1]の形式の範囲が示されます(例: 8 ビットのsigned charの場合 [−128,127] (および)) 。C23 以降では、2 の補数表現のみが許可されているため、値の範囲は少なくとも[−2 n −1 , 2 n −1 −1]になります。[5]
SCHAR_MIN == −128SCHAR_MAX == 127 - ^ または
%hhi数値出力の場合 - ^ または
%hhu数値出力の場合 - ^ これらの書式文字列はテキストの書式設定にも使用されますが、double に対して動作します。
- ^ ab 出力では大文字と小文字が異なります。大文字指定子は大文字で値を生成し、小文字は小文字で値を生成 (%A、%E、%F、%G は INF、NAN、E (指数) などの値を大文字で生成)
整数型の実際のサイズは実装によって異なります。標準では、データ型間のサイズ関係と各データ型の最小サイズのみが要求されています。
関係の要件は、 がlonglong longより小さくなく、 long がintより小さくなく、 int がshortより小さくないことです。 charのサイズは常にサポートされているデータ型の最小値であるため、他のデータ型(ビットフィールドを除く)はこれより小さくなりません。
charの最小サイズは 8 ビット、 shortとintの最小サイズは16 ビット、longの場合は32 ビットで、少なくとも 64 ビットを含める必要があります。
long long
int型は、ターゲット プロセッサが最も効率的に処理できる整数型である必要があります。これにより、柔軟性が高まります。たとえば、すべての型を 64 ビットにすることができます。ただし、いくつかの異なる整数幅スキーム (データ モデル) が一般的です。データ モデルはさまざまなプログラム間の通信方法を定義するため、特定のオペレーティング システム アプリケーション インターフェイス内では、統一されたデータ モデルが使用されます。[9]
実際には、charは通常 8 ビットのサイズで、shortは通常 16 ビットのサイズです (符号なしの対応するものも同様です)。これは、1990 年代のSunOS 4 Unix、Microsoft MS-DOS、最新のLinux、組み込み 8 ビット PICマイクロコントローラ用の Microchip MCC18 など、さまざまなプラットフォームに当てはまります。POSIXでは、char のサイズは正確に 8 ビットである必要があります。 [10] [11]
C標準のさまざまな規則により、unsigned char配列に使用される基本型は、任意の非ビットフィールドオブジェクトを格納するのに適しています。パディングビットとトラップ表現がないこと、オブジェクト表現の定義、[7]、エイリアシングの可能性などです。[12]
浮動小数点型の実際のサイズと動作も実装によって異なります。唯一の要件は、 がdoublelong doubleより小さくないこと、 double がfloatより小さくないことです。通常、 floatとdoubleにはそれぞれ32 ビットと 64 ビットのIEEE 754バイナリ浮動小数点形式が使用されます。
C99標準には、で定義されている新しい実数浮動小数点型float_tおよびdouble_tが含まれています。これらは、 FLT_EVAL_METHODが 0、1、または 2 の場合に浮動小数点式の中間結果に使用される型に対応します。これらの型は よりも幅が広い場合があります。
<math.h>long double
C99 では、複素数型も追加されました: float _Complex、、double _Complex。C11 では、虚数型も追加されました(C99 の参考付録で説明されています): long double _Complex、、。ヘッダーを含めると、これらすべての型にそれぞれcomplexとimaginary を使用してアクセスできるようになります。
float _Imaginarydouble _Imaginarylong double _Imaginary<complex.h>
ブール型
C99 では、ブール データ型 が追加されました_Bool。さらに、ヘッダーでは、この型の便利なエイリアスとして<stdbool.h>が定義され、およびのマクロも提供されています。は、通常の整数型と同様に機能しますが、例外が 1 つあります。 への 0 (偽) 以外の割り当ては、 1 (真) として保存されます。この動作は、暗黙的な縮小変換で整数オーバーフローを回避するために存在します。たとえば、次のコードでは次のようになります。
booltruefalse_Bool_Bool
符号なしchar b = 256 ;
if ( b ) { /* 何かする */ }
変数のサイズが 8 ビットの場合、変数bは false と評価されますunsigned char。これは、値 256 がデータ型に適合しないため、下位 8 ビットが使用され、ゼロ値になるからです。ただし、型を変更すると、前のコードは正常に動作します。
_Bool b = 256 ;
if ( b ) { /* 何かする */ }
_Bool型は、true 値が常に互いに等しいことを保証します。
_Bool a = 1 、b = 2 ;
if ( a == b ) { /* このコードは実行されます */ }
ビット精度の整数型
C23以降、この言語では任意のビット数の幅を持つ整数を定義できます。これらの型は として指定されます。ここで、N は2 の補数で表されるビット数 (符号付き型の符号ビットを含む) を表す整数定数式です。N の最大値はで提供され、少なくとも です。したがって、型(または) は -2 から 1 の値を取り、 は0 から 3 の値を取ります。型も存在し、0 または 1 のいずれかであり、同等の符号付き型はありません。[13]_BitInt(N)BITINT_MAXWIDTHULLONG_WIDTH_BitInt(2)signed _BitInt(2)unsigned _BitInt(2)unsigned _BitInt(1)
サイズとポインタの違いの種類
C 言語仕様には、メモリ関連の量を表すtypedefとが含まれています。これらのサイズは、使用可能なアドレス空間などのメモリ機能ではなく、ターゲット プロセッサの演算機能に応じて定義されます。これらの型は両方とも、ヘッダー ( C++ の場合) で定義されます。
size_tptrdiff_t<stddef.h>cstddef
size_tは、特定の実装における任意のオブジェクト (配列を含む) のサイズを表すために使用される符号なし整数型です。演算子sizeof は、型 の値を生成します。 の最大サイズは、ヘッダー ( C++ では ヘッダー )で定義されているマクロ定数によって提供されます。は、少なくとも 16 ビット幅であることが保証されています。さらに、POSIX には が含まれます。これは、 と同じ幅の符号付き整数型です。
size_tsize_tSIZE_MAX<stdint.h>cstdintsize_tssize_tsize_t
ptrdiff_tポインタ間の差を表すために使用される符号付き整数型です。同じ型のポインタに対してのみ有効であることが保証されています。異なる型で構成されるポインタの減算は実装定義です。
基本型のプロパティへのインターフェース
基本的な算術型の実際のプロパティ (サイズなど) に関する情報は、2 つのヘッダーのマクロ定数によって提供されます。<limits.h>ヘッダー ( climitsC++ では header ) は整数型のマクロを定義し、<float.h>ヘッダー ( cfloatC++ では header ) は浮動小数点型のマクロを定義します。実際の値は実装によって異なります。
整数型の特性
CHAR_BIT– char 型のサイズ(ビット単位)。一般的にはバイトのサイズと呼ばれます(少なくとも 8 ビット)。SCHAR_MIN、、、、(C99) – 符号付き整数型の最小可能値:signed char、signed short、signed int、signed long、SHRT_MINsignedINT_MINlongLONG_MINlongLLONG_MINSCHAR_MAX、、、、(C99) – 符号付き整数型の最大値:signed char、signed short、signed int、signed long、SHRT_MAXsignedINT_MAXlongLONG_MAXlongLLONG_MAXUCHAR_MAX、、、、(C99) – 符号なし整数型の最大値:unsigned char、unsigned short、unsigned int、unsigned long、unsignedUSHRT_MAXlongUINT_MAXlongULONG_MAXULLONG_MAXCHAR_MIN– 文字の最小値CHAR_MAX– 文字の最大値MB_LEN_MAX– マルチバイト文字の最大バイト数BOOL_WIDTH(C23) - のビット幅_Bool、常に1CHAR_WIDTH(C23) -char;のビット幅CHAR_WIDTH、UCHAR_WIDTHおよび は定義によりSCHAR_WIDTH等しいCHAR_BITSCHAR_WIDTH、、、、(C23 )- 、、、、、のビット幅SHRT_WIDTHINT_WIDTHLONG_WIDTHLLONG_WIDTHsigned charshortintlonglong longUCHAR_WIDTH、、、、(C23 )- 、、、、、のビット幅USHRT_WIDTHUINT_WIDTHULONG_WIDTHULLONG_WIDTHunsigned charunsigned shortunsigned intunsigned longunsigned long long
浮動小数点型の特性
FLT_MIN、、DBL_MIN–LDBL_MINそれぞれ float、double、long double の正規化された正の最小値FLT_TRUE_MIN、、(C11) – それぞれ float、double、long double の最小の正のDBL_TRUE_MIN値LDBL_TRUE_MINFLT_MAX、、 – それぞれ float、double、long doubleDBL_MAXのLDBL_MAX最大値FLT_ROUNDS– 浮動小数点演算の丸めモードFLT_EVAL_METHOD(C99) – 異なる浮動小数点型を含む式の評価方法FLT_RADIX– 浮動小数点型の指数の基数FLT_DIG、、 – それぞれ float、double、long doubleDBL_DIGでLDBL_DIG精度を落とさずに表現できる小数点以下の桁数FLT_EPSILON、、DBL_EPSILON–LDBL_EPSILONそれぞれ1.0 とfloat、double、long double の次の表現可能な値との差FLT_MANT_DIG、、DBL_MANT_DIG–それぞれ float、double、long double 型の浮動小数点仮数の - 進数LDBL_MANT_DIGの桁数FLT_RADIXFLT_MIN_EXP、、 –その数値より 1 小さいべき乗がそれぞれ正規化された float、double、long double となるDBL_MIN_EXP最小LDBL_MIN_EXPの負の整数FLT_RADIXFLT_MIN_10_EXP、、– 10 をその乗算した値がそれぞれ正規化された float、double、long double となる最小の負のDBL_MIN_10_EXP整数LDBL_MIN_10_EXPFLT_MAX_EXP、、 –その数値より 1 小さいべき乗がそれぞれ正規化された float、double、long double となるDBL_MAX_EXP最大LDBL_MAX_EXPの正の整数FLT_RADIXFLT_MAX_10_EXP、、– 10 をその乗算するとそれぞれ正規化された float、double、long double になる最大の正のDBL_MAX_10_EXP整数LDBL_MAX_10_EXPDECIMAL_DIG(C99) – サポートされている最も広い浮動小数点型の任意の数値を桁の精度で 10 進数で表現しDECIMAL_DIG、値を変更せずに元の浮動小数点型で読み戻すことができる 10 進数の最小桁数。DECIMAL_DIG少なくとも 10 です。
固定幅整数型
C99標準には、プログラムの移植性を高めるために、いくつかの新しい整数型の定義が含まれています。[2]既存の基本整数型は、実際のサイズが実装によって定義され、システムによって異なる可能性があるため、不十分であると見なされました。新しい型は、ハードウェアが通常いくつかの型しかサポートしておらず、そのサポートも環境によって異なる組み込み環境<inttypes.h>で特に役立ちます。すべての新しい型は、ヘッダー ( C++ では header)で定義され、ヘッダー ( C++ では header)cinttypesでも使用できます。型は次のカテゴリに分類できます。
<stdint.h>cstdint
- すべての実装で同じビット数nを持つことが保証されている正確な幅の整数型。実装で使用可能な場合にのみ含まれます。
- 実装で使用可能な最小の型であることが保証され、少なくとも指定されたビット数nを持つ最小幅の整数型。少なくとも N=8、16、32、64 が指定されることが保証されます。
- 実装で利用可能な最速の整数型であることが保証され、少なくとも指定されたビット数nを持つ最速の整数型。少なくとも N=8、16、32、64 が指定されることが保証されます。
- ポインターを保持できることが保証されているポインター整数型。実装で使用可能な場合にのみ含まれます。
- 実装内で最大の整数型になることが保証されている最大幅の整数型。
次の表は、実装の詳細を取得するための型とインターフェースをまとめたものです ( n はビット数を示します)。
Printf および scanf の書式指定子
ヘッダー<inttypes.h>( cinttypesC++ の場合) は、ヘッダーで定義された型の機能を強化する機能を提供します。 で定義された型に対応するprintf 書式文字列指定子とscanf 書式文字列指定子のマクロと、型と型を操作するためのいくつかの関数<stdint.h>を定義します。 このヘッダーはC99で追加されました。
<stdint.h>intmax_tuintmax_t
Printf フォーマット文字列
マクロの形式は です。ここで、{fmt} は出力フォーマットを定義し、 (10 進数)、 (16 進数)、 (8 進数)、 (符号なし)、 (整数) のいずれかになります。{ type }は引数の型を定義し、、、、のいずれかになります。ここで、 は引数のビット数に対応します。
PRI{fmt}{type}dxouinFASTnLEASTnPTRMAXn
Scanf フォーマット文字列
マクロの形式は です。ここで、{fmt} は出力フォーマットを定義し、 (10 進数)、 (16 進数)、 (8 進数)、 (符号なし)、 (整数) のいずれかになります。{ type }は引数の型を定義し、、、、のいずれかになります。ここで、 は引数のビット数に対応します。
SCN{fmt}{type}dxouinFASTnLEASTnPTRMAXn
機能
追加の浮動小数点型
固定幅整数型と同様に、ISO/IEC TS 18661 では、2 進数と 10 進数の IEEE 754 交換および拡張形式の浮動小数点型を規定しています。
_FloatNバイナリ交換形式の場合;_DecimalN10 進数交換形式の場合。_FloatNxバイナリ拡張形式の場合;_DecimalNx10 進拡張形式の場合。
構造
構造体は、異なる可能性のあるデータ型の複数のデータ項目のストレージを、単一の変数によって参照される 1 つのメモリ ブロックに集約します。次の例では、struct birthday人物の名前と誕生日を含むデータ型を宣言しています。構造体の定義に続いて、必要なストレージを割り当てる変数の宣言が続きますJohn。
構造体誕生日{ char name [ 20 ]; int日; int月; int年; };
構造体の誕生日John ;
構造体のメモリ レイアウトは、各プラットフォームの言語実装の問題であり、いくつかの制限があります。最初のメンバーのメモリ アドレスは、構造体自体のアドレスと同じである必要があります。構造体は、複合リテラルを使用して初期化または割り当てることができます。関数は構造体を直接返すことができますが、実行時には効率的ではないことがよくあります。C99 以降、構造体は柔軟な配列メンバーで終わることもできます。
独自の型の構造体へのポインターを含む構造体は、リンクされたデータ構造を構築するためによく使用されます。
構造体ノード{ int val ;構造体ノード* next ; };
配列
void 型Tと関数型を除くすべての型には、 「型の要素の配列」型が存在します。配列は、すべて同じ型の値の集合で、メモリ内に連続して格納されます。サイズの配列は、から までの整数でインデックス付けされます。以下に簡単な例を示します。
NTN0N−1
int cat [ 10 ]; // 10個の要素を持つ配列。各要素はint型
配列は複合初期化子で初期化できますが、割り当てることはできません。配列は、最初の要素へのポインターを渡すことによって関数に渡されます。多次元配列は「配列の配列…」として定義され、最も外側の次元を除くすべての次元はコンパイル時の定数サイズを持つ必要があります。
int a [ 10 ][ 8 ]; // 10 個の要素の配列。各要素の型は '8 つの int 要素の配列' です。
ポインタ
すべてのデータ型には、 へのT対応する型ポインタTがあります。ポインタは、特定の型の変数の格納場所のアドレスを含むデータ型です。これらは、*基本の格納型の後、変数名の前にアスタリスク ( ) 型宣言子を付けて宣言されます。アスタリスクの前後の空白はオプションです。
char * square ; long * circle ; int * oval ;
ポインター データ型に対してもポインターを宣言できます。これにより、配列型へのポインターを含む、 char **やint ***などの複数の間接ポインターが作成されます。後者はポインターの配列よりも一般的ではなく、その構文はわかりにくい場合があります。
char * pc [ 10 ]; // ' charへのポインタ'の10要素の配列char ( * pa )[ 10 ]; // charの10要素配列へのポインタ
要素には、ポインターのサイズ(一般的なプラットフォームでは通常 40 バイトまたは 80 バイト)pcのメモリ ブロックが 10 個必要ですが、要素には 1 つのポインター (サイズ 4 バイトまたは 8 バイト) しかなく、参照するデータは 10 バイトの配列 ( ) です。
charpasizeof *pa == 10
労働組合
ユニオン型は、異なる型の説明を選択して同じメモリ ブロックにアクセスできるようにする特別な構造です。たとえば、データ型のユニオンは、同じデータを整数、浮動小数点数、またはその他のユーザー宣言型として読み取ることができるように宣言できます。
共用体{ int i ; float f ;構造体{ unsigned int u ; double d ; } s ; } u ;
の合計サイズは のサイズuです。これはとu.sのサイズの合計です。これはが と の両方よりも大きいためです。 に何かを割り当てるときに、が より小さい場合はの一部が保持されることがあります。
u.s.uu.s.dsifu.iu.fu.iu.f
ユニオン メンバーからの読み取りは、メンバーの値が変換されるのではなく、単に読み取られるだけなので、キャストと同じではありません。
関数ポインタ
関数ポインタを使用すると、特定のシグネチャを持つ関数を参照できます。たとえば、標準関数のアドレスをabs変数に格納するには、次のようにしますmy_int_f。
int ( * my_int_f )( int ) = & abs ; // & 演算子は省略できますが、ここでは abs の「アドレス」が使用されていることを明確にします
関数ポインターは、通常の関数呼び出しと同様に名前によって呼び出されます。関数ポインターは、ポインターおよびvoid ポインターとは別です。
型修飾子
前述の型は、型修飾子によってさらに特徴付けることができ、修飾された型[アップデート]が生成されます。2014 年およびC11 の時点で、標準 C には 4 つの型修飾子があります: const( C89 )、volatile( C89 )、restrict( C99 )、_Atomic( C11 ) – 後者はユーザー名との衝突を避けるためにプライベート名が付けられていますが、[14]atomicヘッダーが含まれている場合は、より一般的な名前を使用できます<stdatomic.h>。これらのうち、はconst圧倒的に最もよく知られ、最も多く使用されており、標準ライブラリに表示され、 const の正確性を満たす必要がある C 言語の重要な使用で遭遇します。その他の修飾子は低レベルのプログラミングに使用され、そこでは広く使用されていますが、一般的なプログラマによって使用されることはほとんどありません。[要出典]
参照
参考文献
- ^ Barr, Michael (2007 年 12 月 2 日). 「C 言語でのポータブル固定幅整数」 . 2016 年1 月 18 日閲覧。
- ^ ab ISO/IEC 9899:1999 仕様、TC3 (PDF)。p. 255、§ 7.18整数型 <stdint.h>。
- ^ abcdefghij ISO/IEC 9899:1999 仕様、TC3 (PDF)。p. 22、§ 5.2.4.2.1整数型のサイズ <limits.h>。
- ^ 国際標準—プログラミング言語—C リビジョン 5.10 の根拠(PDF)。p. 25、§ 5.2.4.2.1整数型のサイズ <limits.h>。
- ^ ISO/IEC 9899:2023 仕様草案(PDF)。p. 41、§ 6.2.6型の表現。
- ^ 「C および C++ の整数制限」。2023 年 7 月 21 日。
- ^ ab ISO/IEC 9899:1999 仕様、TC3 (PDF)。p. 37、§ 6.2.6.1型の表現 - 一般。
- ^ abcdef ISO/IEC 9899:1999 仕様、TC3 (PDF)。p. 56、§ 6.4.4.1整数定数。
- ^ 「64 ビット プログラミング モデル: なぜ LP64 か?」 The Open Group 。2011 年11 月 9 日閲覧。
- ^ 「Width of Type (The GNU C Library)」. www.gnu.org . 2022年7月30日閲覧。
- ^ "<limits.h>". pubs.opengroup.org . 2022年7月30日閲覧。
- ^ ISO/IEC 9899:1999 仕様、TC3 (PDF)。p. 67、§ 6.5式。
- ^ ISO/IEC 9899:2023 仕様草案(PDF)。p. 37、§ 6.2.5タイプ。
- ^ C11:新しいC標準、トーマス・プラム
