现在的位置: 首页 > 综合 > 正文

【C99标准翻译1】sizeof

2018年02月08日 ⁄ 综合 ⁄ 共 3500字 ⁄ 字号 评论关闭

《C++编程专家》在第2章 (这不是Bug,而是语言特征)第三节(误做之过)中的骆驼背上的重载中,讲到了括号重载造成sizeof多重意义的例子。

例子1

p=N*sizeof*q;

r=malloc(p);

例子2

apple=sizeof(int)*p;

在例子1中我们可以从第二句中看出,第一句只有一个乘号。但是例子2到底是先计算int类型的字节数再乘以即apple=(sizeof(int))*p,还是计算指针p(被强制转换成int)的字节数呢,即apple=sizeof((int)*p)。

例子中给出了发生歧义的原因:sizeof的操作数是个类型名时,两边必须加括号,但操作数如果是变量则不必要加括号。这在C99标准中明确的有说明。

本文翻译了C99标准中关于sizeof的部分:C.语言标准草案.1999(C)ISO!IEC.9899;1999(E).pdf

翻译中文为:

6.5.3.4 sizeof 操作符

限制

1 sizeof操作符不能作用于有函数类型或者不完整类型的表达式,也不能用于加括号的类型名称,也不能用于 指定位域成员的表达式。

语义

2 sizeof操作符返回操作数的大小(比特),操作数可以是表达式或者加括号的类型名。最终大小由操作数的类型确定。结果是个整数。如果操作数的类型是一个可变长度的数组类型,操作数被求值。否则,操作数不被求值,结果是一个常量整数值。

3 当操作数中有char ,unsigned char, signed char时(或者其他的有效的形式)结果是1。当操作数中有数组类型,结果是数组中总共的字节数。当操作数中有结构体或者联合类型时,结果是包含内部字节和填充字节总的字节数84

4 结果值是实现定义的,它的类型(无符号整数类型)是size_t,定义在<stddef.h>头文件中(或者其他头文件)

5 例1 sizeof操作符的典型应用是和例程例如内存分配和I/O系统,交流。一个内存分配函数可能接收一个对象的大小(字节)然后返回一个空指针。例如

extern void  *alloc(size_t);
double *dp = alloc(sizeof *dp);

alloc函数的实现为了转换成双精度指针应该确保返回值适当地对齐。

6 例2 sizeof另一个用法是计算数组的元素个数。

sizeof array / sizeof array[0]

7 例3 在这个例子中变长数组的大小被这个函数计算和返回。

<pre name="code" class="cpp">#include <stddef.h>
size_t fsize3(int n)
{
    char b[n+3];     // 变长数组
    return sizeof b; // 执行时间 sizeof
}

<pre name="code" class="cpp">84)参数中被声明包含数组或者函数类型,sizeof操作符产生<em>调整(指针)类型</em>的大小。(见6.9.1)

int main()
{
  size_t size;
  size = fsize3(10);  //fsize3返回13
  return 0;
} 

前引:一般定义<stddef.h>(7.17),声明(6.7),结构体和联合体的说明符(6.7.2.1),类型名(6.7.6),数组声明(6.7.5.2)。



原文:

6.5.3.4 The sizeof operator
Constraints
 The sizeof operator shall not be applied to an expression that has function type or an
incomplete type, to the parenthesized name of such a type, or to an expression that
designates a bit-field member.
Semantics
 The sizeof operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type. The size is determined from the type of
the operand. The result is an integer. If the type of the operand is a variable length array
type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an
integer constant.
 When applied to an operand that has type char, unsigned char ,or signed char ,
(or a qualified version thereof) the result is 1. When applied to an operand that has array
type, the result is the total number of bytes in the array.
When applied to an operand that has type char, unsigned char ,or signed char ,
(or a qualified version thereof) the result is 1. When applied to an operand that has array
type, the result is the total number of bytes in the array.
When applied to an operand
that has structure or union type, the result is the total number of bytes in such an object,
including internal and trailing padding.
The value of the result is implementation-defined, and its type (an unsigned integer type)
is size_t, defined in <stddef.h>(and other headers).
EXAMPLE 1 A principal use of thesizeof operator is in communication with routines such as storage
allocators and I/O systems. A storage-allocation function might accept a size (in bytes) of an object to
allocate and return a pointer to void. For example:
extern void *alloc(size_t);
double *dp = alloc(sizeof *dp);
The implementation of the allocfunction should ensure that its return value is aligned suitably for
conversion to a pointer todouble.
EXAMPLE 2 Another use of the sizeof operator is to compute the number of elements in an array:
sizeof array / sizeof array[0]
EXAMPLE 3 In this example, the size of a variable-length array is computed and returned from a
function:
#include <stddef.h>
size_t fsize3(int n)
{
char b[n+3]; // variable length array
return sizeof b; // execution time sizeof
}
When applied to a parameter declared to have array or function type, the sizeof operator yields the
size of the adjusted (pointer) type (see 6.9.1).
 Language 

int main()
{
size_t size;
size = fsize3(10); // fsize3 returns 13
return 0;
}
Forward references: common definitions <stddef.h>(7.17), declarations (6.7),
structure and union specifiers (6.7.2.1), type names (6.7.6), array declarators (6.7.5.2).

PDF截图可以点击下载

1

2

3

抱歉!评论已关闭.