web-dev-qa-db-ja.com

Cのサイズは2バイトですか、4バイトですか?

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

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

131
Rajiv Prathap

私はそれがsizeof(int)と等しいことを知っています。 intのサイズは本当にコンパイラに依存します。当時、プロセッサが16ビットだった当時、intは2バイトでした。今日では、32ビットシステムでも64ビットシステムでもほとんどの場合4バイトです。

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

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

151
yhyrcanus

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

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

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

93
FatalError

具体的な答えはありません。プラットフォームによって異なります。実装定義です。それは2、4か何か他のものです。

intの背後にある考え方は、与えられたプラットフォーム上の自然な "Word"サイズと一致するはずだったということでした。16ビットプラットフォームでは16ビット、32ビットプラットフォームでは32ビット、64ビットプラットフォームでは64ビットです。 。ただし、下位互換性のために、64ビットプラットフォームでも32ビットのintを使用することを好むコンパイラもあります。

16ビットWordサイズの組み込みプラットフォームを使用していない限り、2バイトintの時代は過ぎ去りました(16ビットプラットフォーム?)。あなたの教科書はおそらく非常に古いです。

29
AnT

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

 [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
18
Priyank Arora

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

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


依存する要因は何ですか?

Rangeは、sizeではなく、最もよく考慮される可能性があります。どちらも実際には異なりますが、後で説明するように、サイズよりも範囲で変数タイプを選択する方がはるかに安全です。また、標準では、sizeではなくrangeに基づいて整数型を選択することを検討するよう奨励されていることに注意することも重要です。 、しかし今は標準の練習を無視します、好奇心でsizeof、バイトとCHAR_BIT、整数表現を調べましょう...ウサギの穴を掘り下げて見てみましょう自分のために...


sizeof、バイトおよびCHAR_BIT

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

sizeof演算子は、そのオペランドのサイズ(バイト単位)を生成します。これは、式または括弧付きの型の名前です。サイズは、オペランドのタイプから決定されます。

明確な理解が得られれば、bytesについての議論につながります。一般に、byteは8ビットであると想定されていますが、実際には CHAR_BITは1バイトにいくつのビットがあるかを示します です。これは、一般的な2(または4)バイト整数については考慮されないニュアンスの1つにすぎません。

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

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

したがって、システムに応じて、sizeof (unsigned int)anyの値が0より大きい(2または4だけでなく)、CHAR_BITが16の場合、単一(16ビット)バイトには、標準で記述されている16ビット整数を表すのに十分なビットがあります(以下に引用)。それは必ずしも有用な情報ではありませんか?深く掘り下げましょう...


整数表現

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

UINT_MAX                                65535 // 2¹⁶ - 1

したがって、unsigned intには(少なくとも)16ビットが必要であることがわかります。two bytesを取得します(CHAR_BITが8であると仮定します)...そして、その制限が2³² - 1に増加したとき、人々は代わりに4バイトを述べていました。これはあなたが観察した現象を説明しています:

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

移植性のないCを教えている古代の教科書とコンパイラを使用しています。あなたの教科書を書いた著者はCHAR_BITにさえ気付かないかもしれません。あなたはshould教科書(およびコンパイラー)をアップグレードし、I.T。ahead ofを維持する必要がある進化し続けるフィールドです...基になる整数バイトを格納する他の移植性のない秘密を見てみましょう...

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

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

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

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


ご覧のとおり、標準では、INT_MIN..INT_MAX標準のその他の最小値/最大値 整数型を選択するときの範囲、およびdiscouragessizeof (int)の値に影響する可能性のあるCHAR_BITやパディングビットなど、忘れられる可能性のある他の微妙な要因があるため、サイズに依存します(つまり、twoの一般的な誤解-byteおよび4バイト整数はこれらの詳細を無視します)。

11
Flimzy

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 intのランクよりも大きくなければなりません。
  • 符号なし整数型のランクは、対応する符号付き整数型のランクと同じでなければなりません。
  • すべての整数型T1、T2、およびT3について、T1がT2よりもランクが高く、T2がT3よりもランクが大きい場合、T1はT3よりもランクが大きくなります。

唯一の保証は、char 少なくとも 8ビット幅、shortおよびint 少なくとも 16ビット幅、およびlong 少なくとも 32でなければならないということです。 sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)(これらの型の符号なしバージョンについても同様です)。

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

6
John Bode

主にそれはあなたが使用しているプラ​​ットフォームに依存します。それはコンパイラによって異なります。最近のほとんどのコンパイラでは int 4バイト です。コンパイラが何を使用しているのかを確認したい場合は、sizeof(int)を使用できます。

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

Cコンパイラが約束している唯一のことは、shortのサイズはint以下でなければならず、longのサイズはint以上でなければならないということです。それよりも。longとintに同じことが言えます。また、短いと長いのサイズは同じにはできません。

5
justpraveen

Cのサイズは「int」2バイトですか、それとも4バイトですか?

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

Cプログラミング言語は次を指定します。charで知られ、"byte"とも呼ばれる最小アドレス可能ユニットは、正確にCHAR_BITビット幅で、CHAR_BITは少なくとも8です。

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

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


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

TMS320C28x では、charshort、およびintall 16ビット幅であるため、1バイトになります。 long intは2バイトで、long long intは4バイトです。 Cの長所は、このようなプラットフォーム用の効率的なプログラムを作成できることです。さらに、移植可能な方法でそれを行うこともできます。

4
Antti Haapala

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

確実に特定のサイズの型を使用したい場合は、<stdint.h>の型を使用してください。

3
slartibartfast
#include <stdio.h>

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

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

2
thelaws

Cのサイズは「int」2バイトですか、それとも4バイトですか?

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

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

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

8を超える値はますます一般的ではありません。移植性を最大限に高めるには、8ではなくCHAR_BITを使用します。Cのbitsintのサイズはsizeof(int) * CHAR_BITです。

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

依存する要因は何ですか?

intビットサイズは、通常32ビットまたは16ビットです。 C指定最小範囲

タイプintINT_MIN -32767のオブジェクトの最小値
タイプintINT_MAX +32767のオブジェクトの最大値
C11dr§5.2.4.2.11

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

コンピューターのプロセッサとアーキテクチャは、intビットサイズの選択を駆動します。

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

1
chux

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

しかし、この質問は、「はい。両方とも」という答えです。

それはあなたのアーキテクチャに依存します。 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(配列t)を定義し、function2(配列t、int size_of_t)を定義します。 "function(t)"を呼び出して、コピー作業で長さを測定し、その結果をfunction2に送信します。ここで、可変の配列サイズに対して必要なことをすべて実行できます。

0
Shalec