深入理解C语言-----各数据类型大小

来源:互联网 发布:网络礼仪资料 编辑:程序博客网 时间:2024/05/29 08:37


首先看下C标准中“未明确定义”的三种类型Implementation-defined、Unspecified和Undefined。


Implementation-defined 的情况,是C 标准没有明确规定,但是要求编译器必须对此做出明确规定,并写在编译器的文档中。


Unspecified的情况,往往有几种可选的处理方式,C 标准没有明确规定按哪种方式处理,编译器可以自己决定,并且也不必写在编译器的文档中,这样即使用同一个编译器的不同版本来编译也可能得到不同的结果,因为编译器没有在文档中明确写它会怎么处理,那么不同版本的编译器就可以选择不同的处理方式,比如一个函数调用的各个实参表达式按什么顺序求值是Unspecified的。


Undefined的情况则是完全不确定的,C 标准没规定怎么处理,编译器很可能也没规定,甚至也没做出错处理,有很多Undefined的情况是编译器是检查不出来的,最终会导致运行时错误,比如数组访问越界就是Undefined的。


除了char型在C 标准中明确规定占一个字节之外,其它整数类型占几个字节都是Implementation Defined。通常的编译器实现遵守ILP32 或LP64规范。

LP32 这个缩写的意思是int (I )、long(L )和指针(P )类型都占32位,通常32位计算机的C 编译器采用这种规范,x86 平台的gcc 也是如此。LP64是指long(L )和指针占64位,通常64位计算机的C 编译器采用这种规范。指针类型的长度总是和计算机的位数一致。


(PS下,long long 类型对应的占位符和平台和编译器有关,linux中gcc很统一用%lld,在windows中,MinGW的gcc和VC6都需要用到%I64d,但VS2008却是%lld)

在limit.h文件中有比较详细的定义

[cpp] view plain copy print?
  1. /* Copyright (C) 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2005 
  2.    Free Software Foundation, Inc. 
  3.    This file is part of the GNU C Library. 
  4.  
  5.  
  6.    The GNU C Library is free software; you can redistribute it and/or 
  7.    modify it under the terms of the GNU Lesser General Public 
  8.    License as published by the Free Software Foundation; either 
  9.    version 2.1 of the License, or (at your option) any later version. 
  10.  
  11.  
  12.    The GNU C Library is distributed in the hope that it will be useful, 
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  15.    Lesser General Public License for more details. 
  16.  
  17.  
  18.    You should have received a copy of the GNU Lesser General Public 
  19.    License along with the GNU C Library; if not, write to the Free 
  20.    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
  21.    02111-1307 USA.  */  
  22.   
  23.   
  24. /* 
  25.  *<span style="white-space: pre;"> </span>ISO C99 Standard: 7.10/5.2.4.2.1 Sizes of integer types<span style="white-space: pre;">  </span><limits.h> 
  26.  */   
[cpp] view plain copy print?
  1. */  
  2.   
  3. #ifndef _LIBC_LIMITS_H_  
  4. #define _LIBC_LIMITS_H_ 1  
  5.   
  6. #include <features.h>  
  7.   
  8.   
  9. /* Maximum length of any multibyte character in any locale. 
  10.    We define this value here since the gcc header does not define 
  11.    the correct value.  */  
  12. #define MB_LEN_MAX  16  
  13.   
  14.   
  15. /* If we are not using GNU CC we have to define all the symbols ourself. 
  16.    Otherwise use gcc's definitions (see below).  */  
  17. #if !defined __GNUC__ || __GNUC__ < 2  
  18.   
  19. /* We only protect from multiple inclusion here, because all the other 
  20.    #include's protect themselves, and in GCC 2 we may #include_next through 
  21.    multiple copies of this file before we get to GCC's.  */  
  22. # ifndef _LIMITS_H  
  23. #  define _LIMITS_H 1  
  24.   
  25. #include <bits/wordsize.h>  
  26.   
  27. /* We don't have #include_next. 
  28.    Define ANSI <limits.h> for standard 32-bit words.  */  
  29.   
  30. /* These assume 8-bit `char's, 16-bit `short int's, 
  31.    and 32-bit `int's and `long int's.  */  
  32.   
  33. /* Number of bits in a `char'.  */  
  34. #  define CHAR_BIT  8  
  35.   
  36. /* Minimum and maximum values a `signed char' can hold.  */  
  37. #  define SCHAR_MIN (-128)  
  38. #  define SCHAR_MAX 127  
  39.   
  40. /* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */  
  41. #  define UCHAR_MAX 255  
  42.   
  43. /* Minimum and maximum values a `char' can hold.  */  
  44. #  ifdef __CHAR_UNSIGNED__  
  45. #   define CHAR_MIN 0  
  46. #   define CHAR_MAX UCHAR_MAX  
  47. #  else  
  48. #   define CHAR_MIN SCHAR_MIN  
  49. #   define CHAR_MAX SCHAR_MAX  
  50. #  endif  
  51.   
  52. /* Minimum and maximum values a `signed short int' can hold.  */  
  53. #  define SHRT_MIN  (-32768)  
  54. #  define SHRT_MAX  32767  
  55.   
  56. /* Maximum value an `unsigned short int' can hold.  (Minimum is 0.)  */  
  57. #  define USHRT_MAX 65535  
  58.   
  59. /* Minimum and maximum values a `signed int' can hold.  */  
  60. #  define INT_MIN   (-INT_MAX - 1)  
  61. #  define INT_MAX   2147483647  
  62.   
  63. /* Maximum value an `unsigned int' can hold.  (Minimum is 0.)  */  
  64. #  define UINT_MAX  4294967295U  
  65.   
  66. /* Minimum and maximum values a `signed long int' can hold.  */  
  67. #  if __WORDSIZE == 64  
  68. #   define LONG_MAX 9223372036854775807L  
  69. #  else  
  70. #   define LONG_MAX 2147483647L  
  71. #  endif  
  72. #  define LONG_MIN  (-LONG_MAX - 1L)  
  73.   
  74. /* Maximum value an `unsigned long int' can hold.  (Minimum is 0.)  */  
  75. #  if __WORDSIZE == 64  
  76. #   define ULONG_MAX    18446744073709551615UL  
  77. #  else  
  78. #   define ULONG_MAX    4294967295UL  
  79. #  endif  
  80.   
  81. #  ifdef __USE_ISOC99  
  82.   
  83. /* Minimum and maximum values a `signed long long int' can hold.  */  
  84. #   define LLONG_MAX    9223372036854775807LL  
  85. #   define LLONG_MIN    (-LLONG_MAX - 1LL)  
  86.   
  87. /* Maximum value an `unsigned long long int' can hold.  (Minimum is 0.)  */  
  88. #   define ULLONG_MAX   18446744073709551615ULL  
  89.   
  90. #  endif /* ISO C99 */  
  91.   
  92. # endif /* limits.h  */  
  93. #endif  /* GCC 2.  */  
  94.   
  95. #endif  /* !_LIBC_LIMITS_H_ */  
  96.   
  97.  /* Get the compiler's limits.h, which defines almost all the ISO constants. 
  98.  
  99.     We put this #include_next outside the double inclusion check because 
  100.     it should be possible to include this file more than once and still get 
  101.     the definitions from gcc's header.  */  
  102. #if defined __GNUC__ && !defined _GCC_LIMITS_H_  
  103. /* `_GCC_LIMITS_H_' is what GCC's file defines.  */  
  104. # include_next <limits.h>  
  105. #endif  
  106.   
  107. /* The <limits.h> files in some gcc versions don't define LLONG_MIN, 
  108.    LLONG_MAX, and ULLONG_MAX.  Instead only the values gcc defined for 
  109.    ages are available.  */  
  110. #if defined __USE_ISOC99 && defined __GNUC__  
  111. # ifndef LLONG_MIN  
  112. #  define LLONG_MIN (-LLONG_MAX-1)  
  113. # endif  
  114. # ifndef LLONG_MAX  
  115. #  define LLONG_MAX __LONG_LONG_MAX__  
  116. # endif  
  117. # ifndef ULLONG_MAX  
  118. #  define ULLONG_MAX    (LLONG_MAX * 2ULL + 1)  
  119. # endif  
  120. #endif  
  121.   
  122. #ifdef  __USE_POSIX  
  123. /* POSIX adds things to <limits.h>.  */  
  124. # include <bits/posix1_lim.h>  
  125. #endif  
  126.   
  127. #ifdef  __USE_POSIX2  
  128. # include <bits/posix2_lim.h>  
  129. #endif  
  130.   
  131. #ifdef  __USE_XOPEN  
  132. # include <bits/xopen_lim.h>  
  133. #endif  


注意一点:对于不带signed 或unsigned 关键字的char型,C 标准规定这是Implementation Defined ,编译器可以定义char型是无符号的,也可以定义char型是有符号的,在该编译器所对应的体系结构上哪种实现效率高就可以采用哪种实现,x86 平台的gcc 定义char是有符号的。这也是C 标准的Rationale之一:优先考虑效率,而可移植性尚在其次。另外,除了char型以外的整数类型(short,int,long,long long)如果不明确写signed 或unsigned 关键字都表示有符号数,这一点是C 标准明确规定的。

有符号数在计算机中的表示形式是Sign and Magnitude 、1's Complement还是2's Complement?C 标准也没有明确规定,也是Implementation Defined 。大多数体系结构都采用2's Complement表示形式和加减运算规则,x86 平台也是如此。

注意,ASCII码的取值范围是0~127 ,所以不管char型是有符号的还是无符号的,存一个ASCII码都没有问题,一般来说,如果用char型存ASCII码字符,就不必明确写signed 还是unsigned ,如果把char型当作8 位的整数来用,为了可移植性就必须写明是signed 还是unsigned 。

如果不是为了效率,一般来说就没有理由故意写不可移植的代码。比如Linux内核代码使用了很多gcc 特性以得到最佳的执行效率,在写的时候就没打算用别的编译器编译,也就没考虑可移植性的问题。可见C 语言与平台和编译器是密不可分的,离开了具体的平台和编译器讨论C 语言必然难以深入


C 标准规定的浮点型有float、double 、long double ,和整数类型一样,既没有规定每种类型占多少字节,也没有规定采用哪种表示形式。浮点数的实现在各种平台上差异很大,x86 处理器通常是有浮点运算单元的,遵循IEEE 754,float型通常是32位,double 型通常是64位。要详细了解浮点数的IEEE表示可以查看CSAPP的第二章2.4.2 .具体的定义可以查看float.h

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 房门前乱挂光纤线影响住户怎么办 挂断低于限高的光缆怎么办 开大车挂住光缆怎么办 风把树枝挂断压到车该怎么办 货车柴油冻住了怎么办 尖头鞋老是折尖怎么办 打 氟氯西林疼怎么办 多余的十字绣线怎么办 硅胶类的东西沾到蓝药水怎么办? ph计斜率不到90怎么办 ph计斜率低于90怎么办 顾客说衣服起球怎么办 买的手机壳太滑怎么办 硅胶手机壳太滑怎么办 磨砂手机壳太滑怎么办 被热胶棒烫了怎么办 车钢垫子次了怎么办 【图】机组主轴密封漏水怎么办? 孕妇吃了好多杏怎么办 怀孕6个月吃了好多杏怎么办 白色纯棉衣服染色了怎么办 红色硅胶壳黑了怎么办 小米6gps信号弱怎么办 网线头卡子断了怎么办 入户网线太短了怎么办 孩子弹钢琴大拇指出琴键怎么办 手指肿胀疼痛变粗怎么办 iphone系统占用内存大怎么办 手机系统占用内存大怎么办 头盔固定配件掉了怎么办 移动4g网络不好怎么办 wifi登录密码忘记了怎么办 电脑登录密码忘记了怎么办 笔记本电脑登录密码忘记了怎么办 信用卡登录密码忘记了怎么办 华为p9后置摄像头模糊怎么办 手机图片文件夹删了怎么办 发票系统导出的xml怎么办 微信支付被限制怎么办 跨行三天不到账怎么办 测速正常但实际很慢怎么办