Cのサイズは「int」が2バイトですか、4バイトですか?


169

Cの整数変数は2バイトまたは4バイトを占めますか?それが依存する要因は何ですか?

ほとんどの教科書では、整数変数は2バイトを占めると述べています。しかし、整数の配列の連続したアドレスを出力するプログラムを実行すると、4の違いが表示されます。



1
intは、いくつかの整数型の1つにすぎません。「整数」のサイズについて質問しました。あなたはおそらくのサイズについて尋ねるつもりでしたint
Keith Thompson

3
そして、あなたはより良い教科書を見つけるべきです。「int2バイトである」というテキストは、(a)おそらく古いシステムを参照しており、(b)サイズがシステムによって異なることを明確にしていない。Cに関する最良の本は、プログラミングの経験があることを前提としていますが、KernighanとRitchieによる「Cプログラミング言語」です。comp.lang.c FAQの質問18.10も参照してください
キーストンプソン

2
#define int int64_t64ビットプラットフォームで試してみてください。だけを使用してくださいsizeof。;-)
netcoder、

回答:


183

と等しいことは知っていsizeof(int)ます。のサイズは、int実際にはコンパイラに依存します。昔は、プロセッサが16ビットのときintは、2バイトでした。現在、32ビットおよび64ビットのシステムでは、ほとんどの場合4バイトです。

それでも、使用 sizeof(int)プログラムを実行する特定のシステムの整数のサイズを取得するにはが最善の方法です。

編集:intほとんどの64ビットシステムで8バイトである誤ったステートメントを修正しました。たとえば、64ビットGCCでは4バイトです。


31
@RajivPrathap:まあ、それはコンパイラ依存ですが、コンパイラはそれがマシン依存でもあるかどうかを決定します。:)
user541686

2
プリプロセッサーのサイズが必要な場合は、INT_MAXなどの定義済みマクロを確認できます。値がコードで想定されているものと異なる場合、intのバイトサイズは現在のコンパイラとプラットフォームの組み合わせで異なります。
Waltセラーズ

3
マシンに依存するだけでなく、マシンで実行されているオペレーティングシステムにも依存します。たとえば、Win64のlongは4バイトですが、Linux64のlongは8バイトです。
Cem Kalyoncu

9
違う。ほとんどの64ビットシステムでは、intは依然として4バイトですen.wikipedia.org/wiki/64-bit_computing#64-bit_data_models
phuclv

7
sizeof(int)からの任意の値を指定できます1。バイトは8ビットである必要はなく、一部のマシンには8ビットのアドレス指定可能なユニットがありません(これは基本的に標準でのバイトの定義です)。詳しい情報がなければ答えは正しくありません。
このサイトには正直すぎます

103

これは、最初は混乱を招く可能性があるCのポイントの1つですが、C標準では、サポートされることが保証されている整数型の最小範囲のみを指定しています。int16ビットを必要とする-32767〜32767を保持できることが保証されています。その場合、intは2バイトです。ただし、多くの最新のコンパイラーがint32ビット(つまり、4バイトがかなり広く存在する)になっていることがわかるように、実装はその最小値を超えて自由です。

あなたの本に2バイトと書かれている理由は、おそらく古いからです。かつてはこれが当たり前だった。一般に、使用sizeofしているプラ​​ットフォームでのバイト数を調べる必要がある場合は、常に演算子を使用する必要があります。

これに対処するために、C99は、明示的に、たとえば、特定のサイズの整数を求めることができる新しいタイプの追加int16_tまたはをint32_t。それ以前は、特定の幅の整数を取得する一般的な方法はありませんでした(ほとんどのプラットフォームでは、プラットフォームごとに同様の型が提供されていました)。


7
@nevanking:2の補数マシン(これは私が知っているすべてのマシンです)で、はい。しかし、Cはそれが事実であることを保証しません。
FatalError 2014年

@nevanking Cは完全に新しいですが、それ以外の場合は別のビット|バイトを使用するため、32767ではありませんか?3桁(0または1)を保持できると想像してください。000から111(10進数の7)に進むことができます。7は2の指数の直前です。8(1000)まで行ける場合は、これらの4桁を15まで使用できます。32767などは、2の指数の直前にあり、使用可能なすべてのビットを使い果たします。
RGS 2014

3
@RSerrao私もCのエキスパートではありませんが、正の数のAFAIKは最大の負の数より1つ少ない数です。つまり、-8〜7、-256〜255などです。負の数はゼロを数える必要はありません。
nevan king 2014

1
「16ビット。その場合、intは2バイトです」は、CHAR_BITが16の場合、間違っている可能性があります。sizeof(int)は1バイト(またはchar)になる可能性があります。
12431234123412341234123 2017

6
@nevanking:signedに2の補数表現を仮定した場合のみint。Cはその仮定を行いません。1の補数および符号の大きさのシステムは-32768、16ビットで表すことはできません。むしろ、ゼロの2つの表現(正と負)があります。そのため、の最小範囲int[-32767..32767]です。
John Bode 2017年

33

具体的な答えはありません。プラットフォームによって異なります。これは実装定義です。2、4、またはそれ以外の場合があります。

背後intにあるアイデアは、与えられたプラットフォームの自然な「ワード」サイズに一致するはずであるというものでした:16ビットプラットフォームで16ビット、32ビットプラットフォームで32ビット、64ビットプラットフォームで64ビット、というアイデアが得られます。ただし、下位互換性の目的で、一部のコンパイラintは64ビットプラットフォームでも32ビットを使用することを好みます。

int16ビットワードサイズの組み込みプラットフォームを使用している場合を除いて、2バイトの時間が長くかかります(16ビットプラットフォームですか?)。あなたの教科書はおそらく非常に古いものです。


2
The idea behind int was that it was supposed to match the natural "word" size on the given platform-これは私が探していたものです。理由は何ですか?自由な世界では、intはメモリ内の連続するバイトをいくつでも占有できますよね?
8、16

19

この質問への答えは、使用しているプラ​​ットフォームによって異なります。
ただし、プラットフォームに関係なく、次のタイプを確実に想定できます。

 [8-bit] signed char: -127 to 127
 [8-bit] unsigned char: 0 to 255
 [16-bit]signed short: -32767 to 32767
 [16-bit]unsigned short: 0 to 65535
 [32-bit]signed long: -2147483647 to 2147483647
 [32-bit]unsigned long: 0 to 4294967295
 [64-bit]signed long long: -9223372036854775807 to 9223372036854775807
 [64-bit]unsigned long long: 0 to 18446744073709551615

3
誰かがあなたの投稿を編集して範囲を「修正」しましたが、あなたの編集があなたの意図を適切に反映しているかどうかはわかりません。これは2の補数の実装を前提としています。これはほとんどの場合に当てはまりますが、すべてではありません。あなたの答えは特に実装依存性を指摘しているので、私はおそらく編集が間違っていると思います。同意する場合は、編集内容を元に戻してください。
コーディグレイ

1
@ k06a 編集が正しくありません。元の範囲を2の補数の範囲に具体的に変更しました-これらはC標準で指定された範囲ではありません
Antti Haapala 2018年

@CodyGrayこれは前後に変動しており、過去3年間は1の補数に準拠しており、OPは何も言わなかったため、「確実に想定できる」と言っているため、「修正範囲」で2の補数に変更した編集を元に戻しました。 、まだ正確ではありません。
Antti Haapala

13

Cの整数変数は2バイトまたは4バイトを占めますか?

これは、使用しているプラ​​ットフォーム、およびコンパイラーの構成方法によって異なります。唯一の信頼できる答えは、sizeof演算子を使用して、特定の状況での整数の大きさを確認することです。


それが依存する要因は何ですか?

サイズではなく、範囲を検討することをおすすめします。どちらも実際には異なりますが、後で説明するように、サイズよりも範囲によって変数の型を選択する方がはるかに簡単です。また、標準ではサイズではなく範囲に基づいて整数型を選択することを推奨していますが、ここでは標準的な方法を無視して、好奇心を探り、バイトと整数表現を調べてみましょう...うさぎの穴と自分で見て...sizeofCHAR_BIT


sizeof、バイトおよび CHAR_BIT

(上記にリンクされている)C標準から取られた次のステートメントは、これを改善できないと思う言葉で説明しています。

sizeofオペレータは、発現またはタイプの括弧名前であってもよい、そのオペランドのサイズ(バイト単位)をもたらします。サイズは、オペランドのタイプから決定されます。

明確な理解があると仮定すると、バイトに関する議論につながります。1 バイトは8ビットであると一般に想定されていますが、実際にCHAR_BITは1バイトのビット数がわかります。これは、一般的な2バイト(または4バイト)の整数について話すときに考慮されないニュアンスのもう1つにすぎません。

ここまででまとめましょう。

  • sizeof =>バイト単位のサイズ、および
  • CHAR_BIT =>バイトのビット数

したがって、システムによっては、16の場合のように、ゼロより大きい任意の値(2または4だけではない)にsizeof (unsigned int)なる可能性があります。1バイト(16ビット)には、標準(以下に引用)。それは必ずしも有用な情報ではありませんか?もっと深く調べてみましょう...CHAR_BIT


整数表現

C標準では、すべての標準整数型(およびCHAR_BIT、fwiw)の最小精度/範囲をここで指定しています。これから、値を格納するために必要なビット数の最小値を導き出すことができますが範囲に基づいて変数を選択することもできます。それでも、この回答に必要な詳細の大部分はここにあります。たとえば、標準で(少なくとも)16ビットのストレージが必要である次の例:unsigned int

UINT_MAX                                65535 // 2¹⁶ - 1

したがってunsigned int、(少なくとも)16ビットが必要で、2バイトCHAR_BIT8と仮定)を取得する場所であることがわかります。その後、制限がに増加すると2³² - 1、代わりに4バイトと表示されていました。これは、あなたが観察した現象を説明しています:

ほとんどの教科書では、整数変数は2バイトを占めると述べています。しかし、整数の配列の連続したアドレスを出力するプログラムを実行すると、4の違いが表示されます。

移植性のないCを教えている古代の教科書とコンパイラーを使用しています。あなたの教科書を書いた著者は、気付かないかもしれませんCHAR_BIT。あなたはすべきであるあなたの教科書(とコンパイラ)をアップグレードし、ITが進化し続けるフィールドは、あなたが滞在する必要があるということであることを覚えておくために努力先の競合...、しかしそのことについて十分に。それらの基礎となる整数バイトが格納する他の非移植可能な秘密を見てみましょう...

値ビットは、一般的な誤解が数えているように見えるものです。上記の例では、unsigned通常値ビットのみを含む整数型を使用しているため、詳細で悪魔を見逃しがちです。

符号ビット ...上記の例では、コメントから値を抽出する簡単な例UINT_MAXであるunsigned intため、上限として引用しました16。符号付きの型の場合、正の値と負の値(つまり、符号)を区別するために、符号ビットも含める必要があります。

INT_MIN                                -32768 // -(2¹⁵)
INT_MAX                                +32767 // 2¹⁵ - 1

ビットのパディング ...整数にパディングビットを持つコンピュータに遭遇することは一般的ではありませんが、C標準ではそれが可能です。一部のマシン(つまり、このマシン)は、2つの小さい(符号付き)整数値を組み合わせることにより、より大きい整数型を実装します...符号付き整数を組み合わせると、無駄な符号ビットを取得します。その無駄になったビットはCではパディングと見なされます。パディングビットの他の例には、パリティビットとトラップビットが含まれる場合があります


あなたが見ることができるよう、標準のような考慮の範囲を奨励するようだINT_MIN... INT_MAX、標準から他の最小/最大値の整数型、および選択する際に阻止する可能性が高いなどの忘れする他の微妙な要因があるようなサイズに依存しCHAR_BITていると、パディングビットをの値に影響を与える可能性がありますsizeof (int)(つまり、2バイト整数と4バイト整数の一般的な誤解は、これらの詳細を無視します)。


13

C99 N1256標準ドラフト

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

intその他すべての整数型のサイズは実装で定義され、C99は次のもののみを指定します。

  • 最小サイズ保証
  • タイプ間の相対的なサイズ

5.2.4.2.1「整数型のサイズ<limits.h>」は、最小サイズを示します。

1 [...]それらの実装定義の値は、表示されている値と同じかそれ以上(絶対値)でなければならない[...]

  • UCHAR_MAX 255 // 2 8 − 1
  • USHRT_MAX 65535 // 2 16 − 1
  • UINT_MAX 65535 // 2 16 − 1
  • ULONG_MAX 4294967295 // 2 32 − 1
  • ULLONG_MAX 18446744073709551615 // 2 64 − 1

6.2.5 "型"は次のように言います:

8同じ符号付きで整数変換ランクが異なる2つの整数型(6.3.1.1を参照)の場合、整数変換ランクの小さい型の値の範囲は、他の型の値の部分範囲です。

6.3.1.1「ブール、文字、整数」は、相対的な変換ランクを決定します。

1すべての整数型には、次のように定義された整数変換ランクがあります。

  • long long intのランクはlong intのランクよりも大きくなければならず、これはintのランクよりも大きくなければならず、short intのランクよりも大きくなければならず、signed charのランクよりも大きくなければなりません。
  • 符号なし整数型のランクは、対応する符号付き整数型のランクと同じです(存在する場合)。
  • すべての整数型T1、T2、およびT3について、T1がT2よりもランクが高く、T2がT3よりもランクが高い場合、T1はT3よりもランクが高い

8

唯一の保証は、それがあるcharなければならない少なくとも 8ビット幅、short及びintなければならない、少なくとも 16ビット幅、及びlongなければならない、少なくとも 32ビット幅、及びそのsizeof (char)<= sizeof (short)<= sizeof (int)<= sizeof (long)(同じことが、これらのタイプの符号なしのバージョンについても同様です)。

int プラットフォームに応じて、16ビットから64ビットまでの幅になります。


6

Cのサイズは「int」が2バイトですか、4バイトですか?

答えは「はい」/「いいえ」/「たぶん」/「たぶんそうでない」です。

Cプログラミング言語では、次のように指定されています。「バイト」charと呼ばれ、「バイト」とも呼ばれる最小のアドレス指定可能な単位は、CHAR_BITビット幅が正確CHAR_BITで、少なくとも8です。

したがって、Cの1 バイトは必ずしもオクテット、つまり8ビットではありません。過去には、Cコード(およびUnix)を実行する最初のプラットフォームの1つは4バイトintでしたが、合計でint36ビットCHAR_BITでした。

int少なくともの-32767 ... 32767範囲を持つプラットフォームの自然な整数サイズであると想定されています。のサイズはintプラットフォームのバイト数で取得できますsizeof(int)。この値を掛けるCHAR_BITと、ビット単位の幅がわかります。


36ビットマシンはほとんど機能していませんが、8ビット以外のバイトを使用するプラットフォームはまだあります。ちょうど昨日、C99、C11準拠のコンパイラを備えた16ビットバイトのTexas Instruments MCUに関する質問がありまし

受け、TMS320C28xそれはそれを思わcharshortintされているすべての 1つのバイトので、16ビット幅、および。long int2バイトで、long long int4バイトです。Cの優れた点は、このようなプラットフォーム向けの効率的なプログラムを作成でき、しかも移植可能な方法でさえ実行できることです。


「CHAR_BITが9だったからです!」-彼らは当時362880ビットのコンピューティングを持っていました!?印象的です。
Josh Desmond

5

ほとんどの場合、使用しているプラ​​ットフォームによって異なります。コンパイラによって異なります。ほとんどのコンパイラでは、int4バイトです。コンパイラが使用しているものを確認したい場合は、を使用できますsizeof(int)

main()
{
    printf("%d",sizeof(int));
    printf("%d",sizeof(short));
    printf("%d",sizeof(long));
}

cコンパイラが約束する唯一のことは、shortのサイズはint以下でなければならず、longのサイズはint以上でなければならないということです。したがって、intのサイズが4の場合、shortのサイズは2または4になりますが、それより大きくなることはありません。それよりも長く同じです。また、ショートとロングのサイズを同じにすることはできません。


1
使用%dのためのsize_tパラメータはUBです。
ポールR

3

これは実装によって異なりますが、通常はx86や、ARMなどの他の一般的なアーキテクチャーでintは4バイトかかります。コンパイル時、sizeof(int)または確認したい他のタイプを使用して、いつでも確認できます。

特定のサイズのタイプを使用したい場合は、次のタイプを使用してください。 <stdint.h>


2
#include <stdio.h>

int main(void) {
    printf("size of int: %d", (int)sizeof(int));
    return 0;
}

これは4を返しますが、おそらくマシンに依存しています。


1

Cのサイズは「int」が2バイトですか、4バイトですか?

Cの整数変数は2バイトまたは4バイトを占めますか?

Cでは、「バイト」を「バイト」あたり8ビット以外にすることができます。

CHAR_BIT ビットフィールドではない最小のオブジェクトのビット数(バイト)C11dr§5.2.4.2.11

8を超える値は珍しくなってきています。最大の移植のために、使用しCHAR_BITなく8のサイズintビット Cですsizeof(int) * CHAR_BIT

#include <limits.h>
printf("(int) Bit size %zu\n", sizeof(int) * CHAR_BIT);

それが依存する要因は何ですか?

intビットサイズは、一般的に32または16ビットです。C仕様の最小範囲

型のオブジェクトの最小値int INT_MIN-32767
タイプのオブジェクトの最大値int INT_MAX+32767
C11dr§5.2.4.2.11

最小範囲は、プロセッサが「8ビット」であってもint、ビットサイズを少なくとも 16 に強制します。64ビットのようなサイズは、特殊なプロセッサで見られます。18、24、36などの他の値は、歴史的なプラットフォームで発生したか、少なくとも理論的には可能です。最新のコーディングでは、2の累乗以外のintビットサイズについて心配することはほとんどありません。

コンピュータのプロセッサとアーキテクチャによって、intビットサイズの選択が決まります。

ただし、64ビットプロセッサでも、int互換性の理由から、コンパイラのサイズは32ビットになる場合があります。これは、大きなコードベースintが32ビット(または32/16)であることに依存しているためです。


-1

これは、この質問に答えるための良い情報源です。

しかし、この質問は常に「真実です」と答える一種の真実です。

それはあなたのアーキテクチャに依存します。16ビット以下のマシンで作業する場合は、4バイト(= 32ビット)にすることはできません。32ビット以上のマシンで作業している場合、その長さは32ビットです。

理解するには、読みやすいものを出力し、「sizeof」関数を使用できるようにプログラムを準備します。宣言したデータ型のサイズをバイト単位で返します。しかし、配列でこれを使用してカーフルになります。

宣言しint t[12];ている場合は、12 * 4バイトを返します。この配列の長さを取得するには、単にを使用しますsizeof(t)/sizeof(t[0])。関数を作成する場合は、送信配列のサイズを計算する必要があります。

typedef int array[12];
int function(array t){
    int size_of_t = sizeof(t)/sizeof(t[0]);
    return size_of_t;
}
void main(){
    array t = {1,1,1};  //remember: t= [1,1,1,0,...,0]
    int a = function(t);    //remember: sending t is just a pointer and equal to int* t
   print(a);   // output will be 1, since t will be interpreted as an int itselve. 
}

したがって、これは何か別のものを返しません。配列を定義し、後で長さを取得する場合は、sizeofを使用します。配列を関数に送信する場合、送信値は最初の要素の単なるポインタであることに注意してください。ただし、1つ目の場合は、配列のサイズを常に知っています。ケース2は、2つの関数を定義することで理解でき、一部のパフォーマンスが失われます。function(array t)を定義し、function2(array t、int size_of_t)を定義します。"function(t)"を呼び出して、コピーワークで長さを測定し、結果をfunction2に送信します。ここで、変数の配列サイズに対して必要なことをすべて実行できます。


それは常に真実ではない事を想定しているので、提供されたリンクは、情報の悪い源である(例えばchar常にsigned
アンドレイ・ダミアン-Fekete
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.