【C99标准翻译1】sizeof

《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截图可以点击下载

时间: 2024-11-07 06:50:12

【C99标准翻译1】sizeof的相关文章

C99标准的新特性

C语言标准的发展 C语言的发展历史大致上分为4个阶段:Old Style C.C89.C99和C11. C89是最早的C语言规范,于1989年提出,1990年先由ANSI(美国国家标准委员会,American National Standards Institute)推出ANSI版本,后来被接纳为ISO国际标准(ISO/IEC9899:1990),因而有时也称为C90,最经典的C语言教材[K&R]就是基于这个版本的,C89是目前最广泛采用的C语言标准,大多数编译器都完全支持C89,C99(ISO

C99标准新特性的说明

一.说明 ====== 这里的讨论的是C语言的国际标准,即国际标准化组织ISO,制定的C语言标准.历史上ISO制定过4个版本的C语言标准,他们分别是:C90(ISO/IEC9899:1990).C95(ISO/IEC 9899/AMD1:1995).C99(ISO/IEC9899:1999).C11(ISO/IEC 9899:2011) 这里主要介绍一下C99相对C90而增加的新特性,并且在Gcc编译器中对这些新特性的进行测试. 二.C99新特性介绍 ============= C99引入了很多

c99标准的restrict关键字

参考自restrict restrict关键字出现于C99标准,wiki上的解释restrict from wiki. In the C programming language, as of the C99 standard, restrict is a keyword that can be used in pointer declarations. The restrict keyword is a declaration of intent given by the programmer

GCC和C99标准中inline使用上的不同之处。inline属性在使用的时候,要注意以下两点:inline关键字在G

本文介绍了GCC和C99标准中inline使用上的不同之处.inline属性在使用的时候,要注意以下两点:inline关键字在GCC参考文档中仅有对其使用在函数定义(Definition)上的描述,而没有提到其是否能用于函数声明(Declare). 从 inline的作用来看,其放置于函数声明中应当也是毫无作用的:inline只会影响函数在translation unit(可以简单理解为C源码文件)内的编译行为,只要超出了这个范围inline属性就没有任何作用了.所以inline关键字不应该出现

DEV-C++支持C99标准设置方法

DEV-C++报Error如[Error] 'for' loop initial declarations are only allowed in C99 mode[Note] use option -std=c99 or -std=gnu99 to compile your code 1. 2. step1 工具->编译选项->编译器选项卡中,在"编译时加入以下命令"复选框前打钩,里面输入命令 -std=c99 (与GCC不同,这里c99中的字母c是小写) step2 工

用Gcc编译C文件时出现错误,提示用c99标准

c原文件 #include<stdio.h> #include<stdlib.h> #define MAX(A,B) A>B?A:B        //返回A,B中的最大值 #define LOOP(FROM,TO,CONTENT)         for(int index=FROM;index<TO;index++){                CONTENT         }                 int main(void) {         

C99标准中的部分新特性

我有点怀疑我会不会C语言了. 1.变长数组(VLA) int n = 0; scanf("%d", &n); int arr[n]; 2.数组初始化 int arr[10] = {[0] = 1, [5] = 6, [9] = 10}; for(int i = 0; i < 10; i++) { printf("%d\n", arr[i]); } 3.结构体初始化 struct Struct { int a; int b; int c; }; stru

64位系统和32位系统下的short、int、long数据的宽度

不同的编译器根据不同的 64 位模型有所不同. 比如 Visual C++,从第一个支持 64 位的版本起,一直就是使用 LLP64 内存模型,也就是说,编译出的代码除了 long 和指针是 64 位,int 保持 32 位不变. 可以运行下代码得到结果.#include <stdio.h>int main(){ printf("char: %d\n",sizeof(char)); printf("char *: %d\n",sizeof(char *)

C++11、C99下的sizeof

sizeof运算符 简单定义 sizeof是获取表达式结果的类型或一个类型占用内存空间大小的运算符. 标准上带来的Tips C99以前,sizeof的值是编译过程就决定了的,C99以后,引入了可变长数组,sizeof的值便也可以在运行时决定. 例子: int main(){ int n; scanf(%d,&n); int a[n];//可变长数组,内存空间还是在栈上 printf("%d\n", sizeof(a)); return 0: } 运行结果: 注:本gcc版本为4