ISO/IEC 9899:2011 条款6.2.5——类型

6.2.5 类型

1、存储在一个对象中的值或由一个函数所返回的值的意义由用于访问该对象的表达式的类型来确定。(声明为一个对象的一个标识符是最简单的这种表达式;其类型在标识符的声明中指定。)类型被划分为对象类型(描述对象的类型)以及函数类型(描述函数的类型)。在一个翻译单元中的各个点上,一个对象类型可以是不完全的(缺乏足够信息来确定那个类型对象的大小)或完全的(具有充足的信息)。[注:贯穿一整个翻译单元,一个类型可以是不完整的也可以是完整的,或者它可以在一个翻译单元的内的不同点来改变状态。]

2、声明为_Bool的一个对象足够大以存放0和1。

3、声明为类型char的一个对象足够大来存放基本执行字符集的任一成员。如果基本执行字符集的一个成员被存放在一个char对象内,那么其值被确保为非负的。如果任一其它字符被存放在一个char对象内,那么其结果值是实现定义的,但将在可以用那个类型所能表示的值的范围内。

4、有五种标准带符号整数类型,被指明为signed charshort intintlong int,以及long long int。(这些以及其它类型可以用若干额外的方法进行指明,在6.7.2中描述)也可以有实现定义的扩展带符号整数类型。[注:实现定义的关键字应该具有为任一在7.1.3中所描述使用的一个标识符的形式。]标准与扩展带符号整数类型统称为带符号整数类型。[注:从而,在此标准中关于带符号整数类型的任一语句也被应用于扩展整数类型。]

5、一个声明为signed char类型的对象占用与一个“朴素的”char对象相同的存储空间。一个“朴素的”int对象具有与执行环境架构所建议的自然大小(足够大以包含INT_MININT_MAX范围内的任何值,这两个宏在<limits.h>中定义)。

6、对于每个带符号整数类型,有一个相应的(但不同的)无符号类型(用关键字unsigned指明),使用与带符号类型(包含符号信息)相同的存储空间,并且具有相同的对齐要求。类型_Bool与相应于标准带符号整数类型的无符号整数类型是标准无符号整数类型。相应于扩展带符号整数类型的无符号整数类型是扩展无符号整数类型。标准与扩展无符号整数类型统称为无符号类型。[注:从而,在此标准中关于无符号整数类型的任一语句也应用于扩展无符号整数类型。]

7、标准带符号整数类型以及标准无符号整数类型统称为标准整数类型,扩展带符号整数类型与扩展无符号类型被统称为扩展整数类型

8、对于任何两个带有相同符号及不同整数转换等级的两个整数类型,带有更小整数转换等级的整数类型值的范围是另一个类型值的子范围。

9、一个带符号整数类型的非负值的范围是相应无符号整数类型的一个子范围,每个类型中的同一个值的表示都是相同的。[注:相同表示与对齐要求意味着作为函数实参、函数返回值、以及联合体成员的可互换性。]一个涉及无符号操作数的计算永远不会上溢,因为不能被结果为无符号整数类型所表示的结果被缩减为,对-比结果类型所能表示的最大值加1,取模。

10、有三种实数浮点类型,指明为floatdouble以及long double。[注:见未来语言方向(6.11.1)]类型float的值集合是double类型值集合的子集;类型double的值集合是类型long double值集合的子集。

11、有三种复数类型,指明为float _Complexdouble _Complex,以及long double _Complex。[注:虚数类型的规格说明在附录G中]。(复数类型是一个有条件的特征,实现不需要一定支持;见6.10.8.3。)实数浮点以及复数类型类型统称为浮点类型

12、对于每个浮点类型都有一个相应的实数类型,它总是一个实数浮点类型。对于实数浮点类型,类型相同。对于复数类型,它是通过从类型名删除关键字_Complex来给出。

13、每个实数类型都与一个包含相应实数类型的两个元素的数组类型具有相同的表示以及对齐要求;第一个元素等于实部,第二个元素为虚部。

14、char类型以及带符号与无符号整数类型,还有浮点类型统称为基本类型。基本类型是完整的对象类型。即使实现定义了两个或更多基本类型具有相同的表示,它们仍然是不同的类型。[注:一个实现可以定义提供新的关键字来提供可选的方式来指派一个基本(或其它任何)类型];这并不违背所有基本类型是不同的这个要求。实现定义的关键字应该具有一个为在7.1.3中所描述的一个保留标识符使用的形式。

15、三种类型charsigned char以及unsigned char统称为字符类型。实现应该将char定义为具有与signed charunsigned char具有相同的范围、表示和行为。[注:在<limits.h>中所定义的CHAR_MIN将具有0值或SCHAR_MIN值其中之一,并且这可以被用于区别这两个选择。与所做的选择无关,char是一个独立于其它两个类型的独有类型,并且与其它两个类型都不兼容。]

16、一个枚举由一组命名的整数常量值构成。每个独立的枚举建立了一个不同的枚举类型

17、类型char、带符号及无符号类型,以及枚举类型统称为整数类型。整数及实浮点类型统称为实数类型

18、整数及浮点类型统称为算术类型。每个算术类型属于一个类型域实数类型域由实数类型构成;复数类型域由复数类型构成。

19、void类型由一个值的空集;它是一个无法被完成的非完整对象类型。

20、任一个数的派生类型可以从对象及函数类型来构建,如以下所述:

——一个数组类型描述了一个连续分配非空对象的集合,带有一特定数量的对象类型,该对象类型称为元素类型。无论数组类型在什么时候被指定,元素类型应该是完整的。数组类型通过它们的元素类型以及数组中元素个数来描述其特征。一个数组类型被称为从其元素类型而派生,并且如果其元素类型为T,那么数组类型有时称为“T的数组”。从一个元素类型构造一个数组类型被称为“数组类型派生”。

——一个结构体类型描述了一个叠交的成员对象的的非空集合,每个成员对象具有一个可选指定的名称与可能独立的类型。

——一个联合体类型描述了一个叠交的成员对象的非空集合,每个成员具有一个可选指定的名称与可能独立的类型。

——一个函数类型描述了带有特定返回类型的一个函数。一个函数类型通过其返回类型以及其形参类型和个数进行描述。一个函数类型被称为从其返回类型派生,并且如果其返回类型为T,那么函数类型有时称为“返回T的函数”。从一个返回类型对一个函数类型的构造被称为“函数类型派生”。

——一个指针类型可以从一个函数类型或一个对象类型派生,称为被引用类型。一个指针类型描述了一个对象,其值提供了对一个被引用类型的实体的一个引用。一个从被引用类型T所派生的指针类型有时称为“指向T的指针”。从一个被引用类型所构造的一个指针类型被称为“指针类型派生”。一个指针类型是一个完整的对象类型。

——一个原子类型描述了由_Atomic ( type-name )构造所指派的类型。(原子类型是一个可选特征,实现不必要支持;见6.10.8.3)

    构造派生类型的这些方法可以被递归应用。

21、算术类型与指针类型统称为标量类型。数组及结构体类型统称为聚合类型。[注:注意,聚合类型并不包含联合体类型,因为一个具有联合体类型的对象只能一次包含一个成员。]

22、一个未知大小的数组类型是一个非完整类型。对于一个该类型的标识符,通过在稍后的声明中(具有内部或外部连接)指定其大小来完成此数组类型。一个未知内容的联合体类型或一个结构体类型(在6.7.2.3中描述)是一个不完整类型。对于那个类型的所有声明,通过声明同一个结构体或联合体标签,然后在同一作用域中稍后定义其内容来完成此类型。[译者注:以下代码给出了这几个实例。

// 声明未指定大小的数组sArray
static int sArray[];

// 不完整类型
struct MyStruct;
union MyUnion;

static void CFunc(void)
{
    printf("The value is: %d\n", sArray[0] + sArray[1]);
}

// 完整类型
struct MyStruct
{
    int a;
    float f;
};

union MyUnion
{
    int a;
    float f;
};

// 定义并初始化数组sArray
static int sArray[3] = { 1, 2, 3 };

23、一个类型具有已知的内容大小,如果该类型是完整的并且不是一个可变长度的数组类型。

24、数组、函数以及指针类型统称为派生的声明符类型。从一个类型T派生的一个声明符类型是对一个从T所派生的声明符类型的构造,通过对一个数组类型、一个函数类型,或一个指针类型对T的派生的应用。

25、一个类型由其类型类别进行描述,类型类别要么是一个派生类型的最外层的派生(如上述所描述的派生类型的构造),要么是该类型本身,如果该类型没有被派生的类型。

26、到目前为止所提到的任一类型是一个非限定的类型。每个非限定的类型具有其类型所对应的若干限定版本,[注:见6.7.3关于限定数组与函数类型的描述],对应于一个、两个或所有这三个constvolatile以及restrict限定符的组合。一个类型的限定的与非限定版本是完全不同的类型,但它们属于同一个类型类别,并具有相同的表示与对齐要求。[注:相同的表示与对齐要求意味着暗示作为对函数的实参、从函数的返回值,以及联合体成员的可互换性]一个派生类型不被从它所派生的类型的限定符(如果存在)所限定。

27、此外,还有_Atomic限定符。_Atomic限定符指派了一个原子类型。一个原子类型的大小、表示以及对齐不需要与相应的非限定类型完全一样。因此,本标准显式地使用短语“原子的,限定或非限定的类型”,每当一个类型的原子版本被允许与其它限定版本一起使用时。短语“限定的或非限定的类型”,没有对原子特别提到的话,则不包括原子类型。

28、一个指向void的指针应该具有与一个指向字符类型的指针具有相同的表示与对齐要求。[注:相同的表示与对齐要求意味着暗示作为对函数的实参、从函数的返回值,以及联合体成员的可互换性]。类似地,指向兼容类型的限定或非限定版本应该具有相同的表示与对齐要求。所有指向结构体类型的指针应该相互具有相同的表示与对齐要求。所有指向联合体类型的指针应该相互具有相同的表示与对齐要求。指向其它类型的指针不需要具有相同的表示或对齐要求。

29、例1:标明为“float *”的类型具有类型“指向float的指针”。其类型类别是指针,而不是一个浮点类型。此类型的const限定版本被标明为“float * const”,而标明为“const float *”的类型并不是一个受限定的类型——其类型是一个“指向const限定的float的指针”,并且是一个指向限定类型的指针。

30、例2:标明为“struct tag (*[5])(float)”的类型具有“指向返回struct tag的函数的指针数组”。该数组的长度为五,并且函数具有一个float类型单个形参。其类型类别是一个数组。

posted @ 2015-07-14 03:28  zenny_chen  Views(445)  Comments(0Edit  收藏  举报