这些数据类型的sizeof具体长度依赖于编译器和操作系统(32-bit or 64-bit)

1: 首先,参见c99标准

标准中没有定义这些数据类型的长度,而是定义了这些数据类型能表达的大小范围的最小极限。

C99链接: 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个标准

一个是数据类型能描述的范围,一个是数据类型表达范围之间的顺序

C90 standard requires that

sizeof(short)<=sizeof(int)<=sizeof(long)

C99 standard requires that

sizeof(short)<=sizeof(int)<=sizeof(long)<sizeof(longlong)

3: 5种标准数据类型和他们的衍生类型

signed char

short int

int

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 操作系统中,事实标准为 ILP32,  int, long, pointer 都是4字节

64-bit 操作系统中,事实标准为LP64, int - 4字节, long, pointer 是8字节

在linux操作系统中,参见头文件 int-ll64.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: 数据模型 LP64和ILP32

数据来源: http://en.wikipedia.org/wiki/64-bit#64-bit_data_models


Data model short (integer) int long (integer) long long pointers/
size_t
Sample operating systems
LLP64/
IL32P64
16 32 32 64 64 Microsoft Windows (X64/IA-64)
LP64/
I32LP64
16 32 64 64 64 Most Unix and Unix-like systems, e.g. SolarisLinuxBSD, 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 Type

ILP32

LP64

char

8

8

short

16

16

int

32

32

long

32

64

long long

64

64

pointer

32

64

In addition to the data model changes, some system-derived types, such as size_t, have been expanded to be 64-bit quantities when

compiled 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, short, int, 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_structure_alignment

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 an aligned four-byte word
  • Align 32-bit data so that its base address is a multiple of four
  • Align 64-bit data so that its base address is a multiple of eight
  • 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 attempt to share pointers between 32-bit and 64-bit processes
Attention:

Source:

#include <stdio.h>
#include <stddef.h>
int main()
{
struct T {
char c;
int *p;
short s;
} t;
printf("sizeof(t) = %d\n", sizeof(t));
printf("offsetof(t, c) = %d sizeof(c) = %d\n",
offsetof(struct T, c), sizeof(t.c));
printf("offsetof(t, p) = %d sizeof(p) = %d\n",
offsetof(struct T, p), sizeof(t.p));
printf("offsetof(t, s) = %d sizeof(s) = %d\n",
offsetof(struct T, s), sizeof(t.s));
}
ILP32 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
LP64 output:
sizeof(t) = 24
offsetof(t, c) = 0 sizeof(c) = 1
offsetof(t, p) = 8 sizeof(p) = 8
offsetof(t, s) = 16 sizeof(s) = 2
Comparison of data structure member lengths produced from the same code
Source:
#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\n",sizeof(li));
printf("length lii = %d\n",sizeof(lii));
printf("length ili = %d\n",sizeof(ili));
}
ILP32 member lengths:
length li = 8
length lii = 12
length ili = 12
LP64 member lengths:
length li = 16
length lii = 16
length ili = 24

插曲:

我为什么写这篇文章。前不久去公司面试,boss问我int在64-bit OS上是多少,我说是4字节。然后他说是8字节,我表示又学到了很多知识。我其实以前就看过关于这个数据模型的一些帖子,只是没这么仔细。于是今天整理了一下。



												

[置顶] C语言中各种数据类型的长度 sizeof char, short, int, long, long long的更多相关文章

  1. [置顶] C语言中 || 和 &&

    || 或操作,|| 为界将表达式分为两部分,他会先算前一部分,如果前一部分为真,他将停止运算,如果为假,他才会算第二部分,你这里第一部分就为真了,第二部分当然也就不会算了. 例如:  a || b , ...

  2. c语言中各种数据类型的长度

    在32位平台和64位平台上,同一种数据类型可能有不同的数据长度: 类型 32位平台 64位平台 char 1 1 short 2 2 int 4 4 long 4 8 long long 8 8 fl ...

  3. 2_C语言中的数据类型 (五)char

    1.1       char类型 1.1.1          char常量,变量 char c:定义一个char变量 ‘a’,char的常量 Char的本质就是一个整数,一个只有1个字节大小的整数 ...

  4. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  5. C语言中求字符串的长度

    在C语言中求字符串的长度,可以使用sizeof()函数和strlen()函数,后者需要引入string.h (#include <string.h>) 因为C语言字符串是以 \0 结尾表示 ...

  6. 在C语言中基本数据类型所占的字节数

    基本数据类型所占的字节数其实跟C语言本身没有太大的关系,它取决于编译器的位数,下面这张表说明了不同编译器下基本数据类型的长度: 32位编译器中各基本类型所占字节数: 注:对于32位的编译器,指针变量的 ...

  7. 2_C语言中的数据类型 (七)printf与scanf

    1          字符串格式化输出和输入 1.1       字符串在计算机内部的存储方式 字符串是内存中一段连续的char空间,以’\0’结尾 “”是C语言表达字符串的方式 1.2       ...

  8. 2_C语言中的数据类型 (四)整数与无符号数

    1.1       sizeof关键字 sizeof是c语言关键字,功能是求指定数据类型在内存中的大小,单位:字节 sizeof与size_t类型 1.1       int类型 1.1.1      ...

  9. [置顶] C语言学习入门

    编译文件:cc -c one.c two.c  生成.o目标文件 链接文件:cc one.o two.o     默认生成 a.out 执行文件 指定生成的可执行文件名   cc -o one one ...

随机推荐

  1. POJ 3067 Japan 树状数组求逆序对

    题目大意:有两排城市,这两排城市之间有一些路相互连接着,求有多少条路相互交叉. 思路:把全部的路先依照x值从小到大排序,x值同样的依照y值从小到大排序,然后插入边的时候,先找有多少比自己y值小的,这些 ...

  2. 表单元素的外观改变(webkit and IE10)

    1.禁止表单默认外观: input,select{ -webkit-appearance:none; appearance:none; }2.伪元素改变ie10表单元素默认外观 select::-ms ...

  3. checkbox 选择功能和反选

    使用jQuery实现checkbox全补选和反选功能.什么时候checkbox选择禁用时,不涉及功能 <!DOCTYPE html> <html> <head> & ...

  4. 探秘IntelliJ IDEA 13测试版新功能——调试器显示本地变量

    IntelliJ IDEA在业界被公认为最好的Java开发平台之一,JetBrains公司将在12月正式发布IntelliJ IDEA 13版本. 现在,小编将和大家一起探秘密IntelliJ IDE ...

  5. 分享12款经典时尚的HTML5应用

    分享伟大,呵呵.今天给大家分享一下收集的12个HTML5小特效. 我整理一下源码,给大家打包一下,我博客园上传文件大小有限,传不了了. 需要的请留下邮箱就行了,觉得好的话,不要忘了点赞哦~ 1.CSS ...

  6. 如何防范CC攻击

    服务器如何防范CC攻击CC攻击是DDOS(分布式拒绝服务)的一种,相比其它的DDOS攻击CC似乎更有技术含量一些.这种攻击你见不到虚假IP,见不到特别大的异常流量,但造成服务器无法进行正常连接,听说一 ...

  7. CSS3中文手册基础知识

    CSS3手册是学习CSS3的最佳文档,不管是自己写博客,还是买书,手册少不了.今天我给大家介绍一些CSS3有哪些分类及其使用. 具体参考:http://caibaojian.com/css3/ 上来进 ...

  8. Fiddler工具

    Fiddler初探 我们知道监视Http和Https请求的工具有多种,例如:HttpWatch,FireBug等.但是今天接触到一种新的工具Fiddler.Fiddler能记录所有客户端和服务器的ht ...

  9. [Usaco2008 Open]Roads Around The Farm分岔路口[水题]

    Description     约翰的N(1≤N≤1,000,000,000)只奶牛要出发去探索牧场四周的土地.她们将沿着一条路走,一直走到三岔路口(可以认为所有的路口都是这样的).这时候,这一群奶牛 ...

  10. 园 首页 新随笔 联系 管理 订阅 订阅 RTSP协议转换RTMP直播协议

    RTSP协议转换RTMP直播协议 RTSP协议也是广泛使用的直播/点播流媒体协议,最近实现了一个RTSP协议转换RTMP直播协议的程序,为的是可以接收远端设备或服务器的多路RTSP直播数据,实时转换为 ...