[セットトップ]C言語における各種データタイプの長さsizof char,shot,int,long,long long long

18348 ワード

これらのデータタイプのsizefの具体的な長さはコンパイラとオペレーティングシステムに依存しています(32-bitr 64-bit).
 
1:まず、c 99規格を参照してください.
これらのデータタイプの長さは標準では定義されていませんが、これらのデータタイプが表現できるサイズ範囲の最小限界を定義しています.
C 99リンク:  http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
 
The C++ standard does not specify the size of integral types in bytes, but it specifies minimum ranges they must be able to hold. You can infer minimum size in bits from the required range and the value of CHAR_BIT macro, that defines the number of bits in a byte (in all but the most obscure platforms it's 8).

One additional constraint for char is that its size is always 1 byte, or CHAR_BIT bits (hence the name).

Minimum ranges required by the standard (page 22) are:

signed char: -127 to 127 (note, not -128 to 127; this accommodates 1's-complement platforms)
unsigned char: 0 to 255
"plain" char: -127 to 127 or 0 to 255 (depends on default char signedness)
signed short: -32767 to 32767
unsigned short: 0 to 65535
signed int: -32767 to 32767
unsigned int: 0 to 65535
signed long: -2147483647 to 2147483647
unsigned long: 0 to 4294967295
signed long long: -9223372036854775807 to 9223372036854775807
unsigned long long: 0 to 18446744073709551615
A C++ (or C) implementation can define the size of a type in bytes sizeof(type) to any value, as long as

the expression sizeof(type) * CHAR_BIT evaluates to the number of bits enough to contain required ranges, and
the ordering of type is still valid (e.g. sizeof(int) <= sizeof(long)).
The actual implementation-specific ranges can be found in <limits.h> header in C, or <climits> in C++ (or even better, templated std::numeric_limits in <limits> header).
 
 
2:データタイプの長さは2つの基準を満たす必要があります.
一つはデータタイプが記述できる範囲であり、一つはデータタイプの表現範囲の間の順序である.
 
C 90 standard requires that
sizeof(short)<=sizeof(int)<=sizeof(long)
C 99 standard requires that
sizeof(short)<=sizeof(int)<=sizeof(long)<sizeof(longlong)
3:5種類の標準データタイプと彼らの派生タイプ
signed char
ショートポイント
要点
long int
long long int
 
There are five standard signed integer types : signed char, short int, int, long int, and long long int. In this list, each type provides at least as much storage as those preceding it in the list.

For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: unsigned char, unsigned short int, unsigned int, unsigned long int, and unsigned long long int, each of which occupies the same amount of storage and has the same alignment requirements. 
 
The C++ Standard says it like this :

3.9.1, §2 :

There are five signed integer types : "signed char", "short int", "int", "long int", and "long long int". In this list, each type provides at least as much storage as those preceding it in the list. Plain ints have the natural size suggested by the architecture of the execution environment (44); the other signed integer types are provided to meet special needs.

(44) that is, large enough to contain any value in the range of INT_MIN and INT_MAX, as defined in the header <climits>.

The conclusion : it depends on which architecture you're working on. Any other assumption is false.
 
4:実践中の事実基準
32-bitオペレーティングシステムでは、実際の基準はILP 32であり、 int、long、pointは全部4バイトです.
64 bitオペレーティングシステムでは、実際の基準はLP64、int-4バイト、long、pointerは8バイトです.
 linuxオペレーティングシステムでは、ヘッダファイルを参照してください. int-ll 64.h
 
For 32-bit systems, the 'de facto' standard is ILP32 - that is, int, long and pointer are all 32-bit quantities.

For 64-bit systems, the primary Unix 'de facto' standard is LP64 - long and pointer are 64-bit (but int is 32-bit). The Windows 64-bit standard is LLP64 - long long and pointer are 64-bit (but long and int are both 32-bit).

At one time, some Unix systems used an ILP64 organization.

None of these de facto standards is legislated by the C standard (ISO/IEC 9899:1999), but all are permitted by it. 
 
5:データモデル LP 64とILP 32
データソース:  http://en.wikipedia.org/wiki/64-bit#64-bit_data_models
 
Data model
ショートショット(integer)
要点
long(integer)
long long
pointers/size_t
Sample operating systems
LLP 64/IL 32 P 64
16
32
32
64
64
Microsoft Windows (X 64/IA-64)
LP 64/I 32 LP 64
16
32
64
64
64
Most  Unix and  Unix-like systems、e.g.  ソラリス、  Linux、  BSD,and  OS Xz/OS
 
 
データソース:http://docs.oracle.com/cd/E19620-01/805-3024/lp64-1/index.html
Table F-1 C Data Type Sizes
 
Cタイプ 
ILP 32 
LP 64 
char 


ショート?ト 
16 
16 
要点 
32 
32 
long 
32
64
long long 
64 
64 
pointer 
32
64
 
 
In addition to the data model changes,some system-dersived types,such as size_t,have been expaded to be 64-bit quanties when 
comppiled in the 64-bit environment.
データソース:  http://publib.boulder.ibm.com/infocenter/zvm/v6r2/index.jsp?topic=%2Fcom.ibm.zos.r12.cbcpx01%2Fdatatypesize64.htm
同上
6:linuxでの実際の使用
 
#ifndef __ASSEMBLY__
/*
 * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
 * header files exported to user space
 */

typedef __signed__ char __s8;
typedef unsigned char __u8;

typedef __signed__ short __s16;
typedef unsigned short __u16;

typedef __signed__ int __s32;
typedef unsigned int __u32;

#ifdef __GNUC__
__extension__ typedef __signed__ long long __s64;
__extension__ typedef unsigned long long __u64;
#else
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
#endif
つまり、longタイプは使われていません.char、shott、int、long long longで十分です.
 
7.printf
 
http://www.gnu.org/software/libc/manual/html_mono/libc.html#Integer-Conversions

12.12.4 Integer Conversions

This section describes the options for the ‘%d’, ‘%i’, ‘%o’, ‘%u’, ‘%x’, and ‘%X’ conversion specifications. These conversions print integers in various formats.

The ‘%d’ and ‘%i’ conversion specifications both print an int argument as a signed decimal number; while ‘%o’, ‘%u’, and ‘%x’ print the argument as an unsigned octal, decimal, or hexadecimal number (respectively). The ‘%X’ conversion specification is just like ‘%x’ except that it uses the characters ‘ABCDEF’ as digits instead of ‘abcdef’.

‘l’
Specifies that the argument is a long int or unsigned long int, as appropriate. Two ‘l’ characters is like the ‘L’ modifier, below.
If used with ‘%c’ or ‘%s’ the corresponding parameter is considered as a wide character or wide character string respectively. This use of ‘l’ was introduced in Amendment 1 to ISO C90. 

‘L’
‘ll’
‘q’
Specifies that the argument is a long long int. (This type is an extension supported by the GNU C compiler. On systems that don't support extra-long integers, this is the same as long int.)
The ‘q’ modifier is another name for the same thing, which comes from 4.4 BSD; a long long int is sometimes called a “quad” int. 
 
8:バイトの配置
http://publib.boulder.ibm.com/infocenter/zvm/v6r2/index.jsp?topic=%2Fcom.ibm.zos.r12.cbcpx01%2Fcbcpg1b0233.htm
http://publib.boulder.ibm.com/infocenter/zvm/v6r2/index.jsp?topic=%2Fcom.ibm.zos.r12.cbcpx01%2Fcbcpg1b0228.htm
http://www.unix.org/whitepapers/64bit.html
http://software.intel.com/en-us/articles/data-alignment-when-migrating-to-64-bit-intel-architecture
https://en.wikipedia.org/wiki/Data_structurealignment
http://csweapon.diandian.com/post/2011-08-26/4372667
自然配置
 64-bit operating environment
 
Align 8-bit data at any address Align 16-bit data to be contained within aligned four-byte word Align 32-bit data so that its base address is a multile of four Align 64-bit data so that its base address is a multiple of eigt Align 80-bit data so that its base address is a multiple of sixteen Align 128-bit data so that its base address is a multiple of sixteen  An atempt to share pointers between 32-bit and 64-bit processes
Attention:
ソース:
#include <stdio.h>
#include <stddef.h>
int main()
{
    struct T {
        char c;
        int *p;
        short s;
        } t;
        printf("sizeof(t) = %d
", sizeof(t)); printf("offsetof(t, c) = %d sizeof(c) = %d
", offsetof(struct T, c), sizeof(t.c)); printf("offsetof(t, p) = %d sizeof(p) = %d
", offsetof(struct T, p), sizeof(t.p)); printf("offsetof(t, s) = %d sizeof(s) = %d
", offsetof(struct T, s), sizeof(t.s)); }
ILP 32 output:
sizeof(t) = 12
offsetof(t, c) = 0 sizeof(c) = 1
offsetof(t, p) = 4 sizeof(p) = 4
offsetof(t, s) = 8 sizeof(s) = 2
LP 64 out put:
sizeof(t) = 24
offsetof(t, c) = 0 sizeof(c) = 1
offsetof(t, p) = 8 sizeof(p) = 8
offsetof(t, s) = 16 sizeof(s) = 2
 
 
 
Comprison of data structure member lengths produced from the same code
ソース:
#include <stdio.h>

int main(void) {
    struct li{
             long la;
             int ia;
             } li;
    struct lii{
              long la;
              int ia;
              int ib;
              } lii;
    struct ili{
              int ia;
              long la;
              int ib;
              } ili;
    printf("length li = %d
",sizeof(li)); printf("length lii = %d
",sizeof(lii)); printf("length ili = %d
",sizeof(ili)); }
ILP 32 member lengths:
length li = 8   
length lii = 12 
length ili = 12 
LP 64 member lengths:
length li = 16  
length lii = 16 
length ili = 24 
 
 
 
挿入歌:
なぜこの文章を書きますか?この前ある会社に面接に行きましたが、bossは64 bit OSでどれぐらいですか?と聞きました.4バイトです.そして彼は8バイトだと言っていますが、私はまた多くの知識を学びました.実は以前からこのデータモデルに関する書き込みを見たことがありますが、詳しくはないです.今日は整理しました.