Oracle® Solaris Studio 12.4:C 用户指南

退出打印视图

更新时间: 2014 年 12 月
 
 

ISO C 数据表示法

本附录介绍了 ISO C 如何表示存储器中的数据以及向函数传递参数的机制。它可以为想要编写或使用非 C 语言模块并将这些模块与 C 代码连接的程序员提供指导。

G.1 存储分配

下表显示了数据类型及其表示方法。大小以字节为单位。


注 - 堆栈中分配的存储空间(带有内部、自动或链接的标识符)应限于 2G 字节或更少。
表 G-1  数据类型的存储分配
C 类型
LP64 (-m64) 大小
LP64 对齐
ILP32 (-m32) 大小
ILP 32 对齐
整数
_Bool
char
signed char
unsigned char
1
1
1
1
short
signed short
unsigned short
2
2
2
2
int
signed int
unsigned int
enum
4
4
4
4
long
signed long
unsigned long
8
8
4
4
long long
signed long long
unsigned long long
8
8
8
4 (x86) / 8 (SPARC)
指针
any-type *
any-type (*) ()
8
8
4
4
浮点
float
double
long double
4
8
16
4
8
16
4
8
12 (x86) / 16 (SPARC)
4
4 (x86) / 8 (SPARC)
4 (x86) / 8 (SPARC)
复数
float _Complex
double _Complex
long double _Complex
8
16
32
4
8
16
8
16
24 (x86) / 32 (SPARC)
4
4 (x86) / 8 (SPARC)
4 (x86) / 16 (SPARC)
虚数
float _Imaginary
double _Imaginary
long double _Imaginary
4
8
16
4
8
16
4
8
12 (x86) / 16 (SPARC)
4
4 (x86) / 8 (SPARC)
4 (x86) / 16 (SPARC)

G.2 数据表示法

任何给定数据元素的位编号取决于使用的体系结构:SPARCstation 机器将位 0 用作最低有效位,将字节 0 用作最高有效字节。本节中的表介绍各种表示法。

G.2.1 整数表示法

ISO C 中使用的整型有 shortintlonglong long

表 G-2  short 的表示法
内容
8- 15
字节 0 (SPARC)
字节 1 (x86)
0- 7
字节 1 (SPARC)
字节 0 (x86)
表 G-3  int 的表示法
内容
24- 31
字节 0 (SPARC)
字节 3 (x86)
16- 23
字节 1 (SPARC)
字节 2 (x86)
8- 15
字节 2 (SPARC)
字节 1 (x86)
0- 7
字节 3 (SPARC)
字节 0 (x86)
表 G-4  使用 -m32 编译的 long 的表示法
内容
24- 31
字节 0 (SPARC)
字节 3 (x86)
16- 23
字节 1 (SPARC)
字节 2 (x86)
8- 15
字节 2 (SPARC)
字节 1 (x86)
0- 7
字节 3 (SPARC)
字节 0 (x86)
表 G-5  long (-m64) 和 long long-m32 和 -m64)的表示法
内容
56- 63
字节 0 (SPARC)
字节 7 (x86)
48- 55
字节 1 (SPARC)
字节 6 (x86)
40- 47
字节 2 (SPARC)
字节 5 (x86)
32- 39
字节 3 (SPARC)
字节 4 (x86)
24- 31
字节 4 (SPARC)
字节 3 (x86)
16- 23
字节 5 (SPARC)
字节 2 (x86)
8- 15
字节 6 (SPARC)
字节 1 (x86)
0- 7
字节 7 (SPARC)
字节 0 (x86)

G.2.2 浮点表示法

floatdoublelong double 数据元素按照 ISO IEEE 754-1985 标准来表示。表示法为:

(-1)s *2(e - bias) *[j.f]

其中:

  • s 为符号

  • e 为偏置指数

  • j 为前导位,由 e 的值确定。在 long double (x86) 情况下,前导位是显式的;在所有其他情况下,它是隐式的。

  • f = 尾数

  • u 表示位可以是 0 或 1(此部分的表格中使用)。

对于 IEEE Single 和 Double,j 总是隐式的。偏置指数为 0 时, j 为 0,只要 f 不为 0,生成的数字就不太正常。偏置指数大于 0 时,只要该数字是有限的,j 就为 1。

对于 Intel 80 位 Extended,j 总是显式的。

下表显示各个位的位置。

表 G-6  float 表示法
名称
31
符号
23- 30
偏置指数
0- 22
尾数部分
表 G-7  double 表示法
名称
63
符号
52- 62
偏置指数
0- 51
尾数部分
表 G-8  longdouble 表示法 (SPARC)
名称
127
符号
112- 126
偏置指数
0- 111
尾数部分
表 G-9  longdouble 表示法 (x86)
名称
80- 95
不使用
79
符号
64- 78
偏置指数
63
前导位
0- 62
尾数部分

有关详细信息,请参阅《数值计算指南》。

G.2.3 异常值

floatdouble 数被认为包含一个“隐藏的”或隐含的位,从而比不包含该位时的精度高一位。对于 long double,前导位为隐式 (SPARC) 或显式 (x86);该位对于正规数为 1,对于非正规数为 0。

表 G-10  float 表示法
正规数 (0<e<255):
(-1)s2 (e-127)1.f
非正规数
(e=0, f!=0):
(-1)s2 (-126)0.f
零 (e=0, f=0):
(-1)s0.0
信号 NaN
s=u,e=255(max);f=.0uuu-uu;至少一个位必须为非零
静态 NaN
s=u,e=255(max);f=.1uuu-uu
无穷
s=u,e=255(max);f=.0000-00(全为零)
表 G-11  double 表示法
正规数 (0<e<2047):
(-1)s2 (e-1023)1.f
非正规数 (e=0, f!=0):
(-1)s2 (-1022)0.f
零 (e=0, f=0):
(-1)s0.0
信号 NaN
s=u,e=2047(max);f=.0uuu-uu;至少一个位必须为非零
静态 NaN
s=u,e=2047(max);f=.1uuu-uu
无穷
s=u,e=2047(max);f=.0000-00(全为零)
表 G-12  longdouble 表示法
正规数 (0<e<32767):
(-1)s2 (e- 16383)1.f
非正规数 (e=0, f!=0):
(-1)s2 (-16382)0.f
零 (e=0, f=0):
(-1)s0.0
信号 NaN
s=u,e=32767(max);f=.0uuu-uu;至少一个位必须为非零
静态 NaN
s=u,e=32767(max);f=.1uuu-uu
无穷
s=u,e=32767(max);f=.0000-00(全为零)

G.2.4 选定的数的十六进制表示

下表显示十六进制表示。

表 G-13  选定数的十六进制表示法 (SPARC)
float
double
long double
+0
-0
00000000
80000000
0000000000000000
8000000000000000
00000000000000000000000000000000
80000000000000000000000000000000
+1.0
-1.0
3F800000
BF800000
3FF0000000000000
BFF0000000000000
3FFF00000000000000000000000000000
BFFF00000000000000000000000000000
+2.0
+3.0
40000000
40400000
4000000000000000
4008000000000000
40000000000000000000000000000000
40080000000000000000000000000000
正无穷
负无穷
7F800000
FF800000
7FF0000000000000
FFF0000000000000
7FFF00000000000000000000000000000
FFFF00000000000000000000000000000
NaN
7FBFFFFF
7FF7FFFFFFFFFFFF
7FFF7FFFFFFFFFFFFFFFFFFFFFFFFFFF
表 G-14  选定数的十六进制表示法 (x86)
float
double
long double
+0
-0
00000000
80000000
0000000000000000
0000000080000000
00000000000000000000
80000000000000000000
+1.0
-1.0
3F800000
BF800000
000000003FF00000
00000000BFF00000
3FFF8000000000000000
BFFF8000000000000000
+2.0
+3.0
40000000
40400000
0000000040000000
0000000040080000
40008000000000000000
4000C000000000000000
正无穷
负无穷
7F800000
FF800000
000000007FF00000
00000000FFF00000
7FFF8000000000000000
FFFF8000000000000000
NaN
7FBFFFFF
FFFFFFFF7FF7FFFF
7FFFBFFFFFFFFFFFFFFF

有关详细信息,请参阅《数值计算指南》。

G.2.5 指针表示法

C 中的一个指针占 4 个字节。C 中的一个指针在 64 位 SPARC v9 体系结构中占 8 个字节。NULL 值指针等于零。

G.2.6 数组存储

数组及其元素按特定的存储顺序存储。元素实际上按存储元素的线性序存储。

C 数组按行主顺序存储。多维数组的最后一个下标变化最快。

字符串数据类型是 char 元素的数组。文本字符串或宽文本字符串(串联后)中允许的字符数最大值为 4,294,967,295。

有关堆栈中存储分配大小限制的信息,请参见存储分配

表 G-15  数组类型和存储
类型
-m32 元素的最大数目
-m64 元素的最大数目
char
4,294,967,295
2,305,843,009,213,693,951
short
2,147,483,647
1,152,921,504,606,846,975
int
1,073,741,823
576,460,752,303,423,487
long
1,073,741,823
288,230,376,151,711,743
float
1,073,741,823
576,460,752,303,423,487
double
536,870,911
288,230,376,151,711,743
long double
268,435,451
144,115,188,075,855,871
long long
536,870,911
288,230,376,151,711,743

静态数据和全局数组可以容纳更多元素。

G.2.7 异常值的算术运算

本节介绍了对异常和普通浮点值的组合应用基本算术运算所得的结果。以下信息假定不执行陷阱或任何其他异常操作。

下表解释缩写。

表 G-16  缩写使用方式
简称
含义
Num
非正规数或正规数
Inf
无穷(正或负)
NaN
不是数
Uno
未排序

下表描述对不同类型的操作数的组合执行算术运算所得值的类型。

表 G-17  加法和减法结果
右操作数:0
右操作数:Num
右操作数:Inf
右操作数: NaN
左操作数: 0
0
Num
Inf
NaN
左操作数: Num
Num
请参见

结果太大(溢出)时,Num + Num 可能为 Inf 而不是 Num。无穷值具有相反的 sign 时,Inf + Inf = NaN。

Inf
NaN
左操作数: Inf
Inf
Inf
请参见
NaN
左操作数: NaN
NaN
NaN
NaN
NaN
表 G-18  乘法结果
右操作数:0
右操作数:Num
右操作数:Inf
右操作数: NaN
左操作数: 0
0
0
NaN
NaN
左操作数: Num
0
Num
Inf
NaN
左操作数: Inf
NaN
Inf
Inf
NaN
左操作数: NaN
NaN
NaN
NaN
NaN
表 G-19  除法结果
右操作数:0
右操作数:Num
右操作数:Inf
右操作数: NaN
左操作数: 0
NaN
0
0
NaN
左操作数: Num
Inf
Num
0
NaN
左操作数: Inf
Inf
Inf
NaN
NaN
左操作数: NaN
NaN
NaN
NaN
NaN
表 G-20  比较结果
右操作数:0
右操作数:+Num
右操作数:+Inf
右操作数: +NaN
左操作数: 0
=
<
<
Uno
左操作数: +Num
>
比较的结果
<
Uno
左操作数: +Inf
>
>
=
Uno
左操作数: +NaN
Uno
Uno
Uno
Uno

注 - NaN 与 NaN 比较结果为无序,从而导致不相等。+0 与 - 0 的比较结果是相等。

G.3 参数传递机制

本节介绍了在 ISO C 中如何传递参数。

  • 传递给 C 函数的所有参数均通过值进行传递。

  • 实际参数按函数声明中声明参数的反向顺序传递。

  • 本身为表达式的实际参数在函数引用之前求值。然后表达式的结果置入寄存器或推入堆栈。

G.3.1 32 位 SPARC

函数在寄存器 %o0 中返回 integer 结果,在寄存器 %f0 中返回 float 结果,在寄存器 %f0%f1 中返回 double 结果。

long long 整数以较高词序在 %oN 寄存器中进行传递,以较低词序在 %o(N+1) 寄存器中进行传递。寄存器中的结果在 %o0%o1 中返回,排序相似。

doubleslong double 外,所有参数都作为 4 字节值来传递。double 作为 8 字节值传递。前六个 4 字节值(double 计为 8)在寄存器 %o0%o5 中传递。其余值传递到堆栈中。结构的传递方式是复制结构并将指针传递到副本。long double 的传递方式与结构的传递方式相同。

此处描述的寄存器是可被调用程序识别的寄存器。

G.3.2 64 位 SPARC

所有整型参数均作为 8 字节值传递。

浮点参数尽可能在浮点寄存器中传递。

G.3.3 x86/x64

遵循 Intel 386 psABI 和 AMD64 psABI。

函数在以下寄存器中返回结果:

表 G-21  x86 函数返回类型所使用的寄存器 (-m32)
返回的类型
寄存器
int
%eax
long long
%edx%eax
floatdoublelong double
%st(0)
float _Complex
实部为 %eax,虚部为 %edx
double _Complexlong double _Complex
与包含相应浮点类型的两个元素的结构相同。

有关详细信息,请参阅 http://www.x86-64.org/documentation/abi.pdfhttp://www.x86–64.org/documentation/abi.pdf 上的 AMD64 psABI

除了 structunionlong longdoublelong double 之外的所有参数都作为 4 字节值传递;long long 作为 8 字节值传递,double 作为 8 字节值传递,long double 作为 12 字节值传递。

structunion 被复制到堆栈中。大小向上舍入为 4 字节的倍数。返回 structunion 的函数被传递一个隐藏的首参数,并指向返回的 structunion 的存储位置。

从一个函数返回时,调用程序负责从堆栈中弹出参数,但 structunion 返回的附加参数除外,它由调用的函数弹出。