sizeof-function还是宏?

在c中,我们使用sizeof()来获取数据类型的大小。 那么它是如何定义的。 它是一个宏或一个函数。

因为我们可以用两种方式,

 sizeof int 

 sizeof(int) 

这是如何在头文件中定义的。

它既不是。 它是一个内置运算符,其值在编译时计算,除非参数是可变长度数组的名称(在C99中添加)。

您经常看到的括号不是 “调用”的一部分,因为sizeof不是函数。 它们是参数的一部分,仅在参数为强制转换表达式时才需要,即括在括号中的类型的名称。

我个人建议尽可能使用带有类型名称的sizeof作为参数,因为通常不需要它,并且会产生可能导致错误的断开/解耦。

考虑这样的事情:

 float *vector = malloc(100 * sizeof(double)); 

当然,上面包含一个错误:如果float小于double ,则会浪费大量内存。 很容易想象最终会出现类似上面的内容,如果vector开始是一个double数组但后来改为float 。 为了保护这个,我总是写:

 float *vector = malloc(10 * sizeof *vector); 

上面使用参数*vectorfloat类型的表达式)来定义sizeof ,它不是类型名称,因此不需要括号。 它还将元素的大小“锁定”到用于保持它的指针,这更安全。

Sizeof既不是宏也不是函数。它是在编译时计算的运算符。

在预处理阶段评估宏。

正如@Yu Hao所指出的,可变长度数组是唯一的例外。

更多了解解决这个问题;

 #include char func(char x) { x++; return x; } int main() { printf("%zu", sizeof(func(3))); return 0; } A) 1 B)2 C)3 D)4 

来自ISO / IEC9899

6.5.3.4 sizeof运算符

约束

1 sizeof运算符不应应用于具有函数类型或不完整类型的表达式,此类型的带括号的名称,或应用于指定位字段成员的表达式。

所以它既不是宏也不是函数。它是一个运算符!

它的处理方式是编译器的一个方面。

但是关于编译时间和运行时确定,标准说:

语义

2 sizeof运算符产生其操作数的大小(以字节为单位),可以是表达式或类型的带括号的名称。 大小由操作数的类型确定。 结果是整数。 如果操作数的类型是可变长度数组类型,则计算操作数; 否则,不评估操作数,结果是整数常量。

因此,除了VLA案例之外,它甚至可以在编译时确定。

句法

  1. sizeof(类型)
  2. 列出sizeof表达式

两个版本都返回std :: size_t类型的常量。

说明

  1. 返回类型的对象表示的字节数。
  2. 返回类型的对象表示的字节数,如果已计算,则由表达式返回。

一元运算符sizeof用于计算任何数据类型的大小,以表示类型所需的字节数来度量。

在许多程序中,有些情况下知道特定数据类型的大小是有用的(最常见的例子之一是使用库函数malloc的动态内存分配)。 虽然对于C或C ++的任何给定实现,特定数据类型的大小是常量,但C和C ++中的偶数基本类型的大小是实现定义的(即,标准没有精确定义)。 尝试分配适当大小的内存块时,这可能会导致问题。 例如,假设程序员想要分配一个足够大的内存块来容纳十个int类型的变量。 因为我们的假设程序员不知道int类型的确切大小,程序员不知道要求malloc的字节数。 因此,有必要使用sizeof: