【问题标题】:Is sizeof a function or an operator?sizeof 是函数还是运算符?
【发布时间】:2021-04-27 02:25:30
【问题描述】:

为什么我们说sizeof(variable) 是一个运算符,而不是一个函数?

它看起来像一个函数调用,当我思考运算符的含义时,它在我看来类似于 +-* 等等

【问题讨论】:

  • 因为sizeof(全一个字)是一个运算符,而不是一个函数,例如sizeof myvartype 需要括号。
  • 如果后面是表达式,你只需要括号。
  • 你可以写x = +(y)。括号不会使 + 成为函数。
  • 这能回答你的问题吗? Why is sizeof considered an operator?

标签: c operators sizeof function-call


【解决方案1】:

它是一个运算符,因为它不像函数那样接受参数。它在语法级别运行。

f(int) 不是有效的函数调用,但sizeof(int)sizeof 的有效用法。

它还可以对变量或类型进行操作,它的设计非常灵活,这是一个操作符可以做的事情,因为它已经深入到 C 语法中。

更多详情can be found here.

【讨论】:

  • sizeof int 未在 C 标准中指定。
  • @EricPostpischil 那是 C++ 主义吗?
  • 你在想sizeof expression而不是sizeof (type)吗?
【解决方案2】:

它是一个运算符,不需要使用括号,除了“当操作数是类型名时,必须用括号括起来”。这是一个语法限制,但不应与函数调用混淆。

请参阅下面来自 GNU documentation 的最后一个示例:

size_t a = sizeof(int);
size_t b = sizeof(float);
size_t c = sizeof(5);
size_t d = sizeof(5.143);
size_t e = sizeof a;

如果类型名称没有括号,使用 gcc 编译器时,您可能会看到如下错误:

test.c:7:20: error: expected expression before ‘int’
    7 |  size_t s = sizeof int;
      |                    ^~~

但是使用sizeof 12sizeof a 很好。

【讨论】:

    【解决方案3】:

    这是一个在编译时评估的运算符。

    实际上,当T 是类型而不是类型的实例时,它只需要类似函数的语法sizeof(T)

    因此,例如,如果您有一个变量int x,则sizeof x 是允许的;但是sizeof(int)int 类型所必需的。

    【讨论】:

    • sizeof 是编译时常量(技术上:必须符合整数常量),仅当其操作数不具有可变长度数组类型时。
    【解决方案4】:

    如语法所示:

    unary-expression:
      postfix-expression
      ++ unary-expression
      -- unary-expression
      unary-operator cast-expression
      sizeof unary-expression
      sizeof (type-name)
      _Alignof (type-name)
    
    unary-operator: one of
      & * + - ~ !
    

    它是一个运算符,在接受 unary-expression 参数时不仅不需要括号,而且使用括号的行为与函数调用不同。

    考虑给定_Static_assert(sizeof(0)==4,"");,以下成立:

    _Static_assert(sizeof(0)==4,"");
    #include <assert.h>
    int takeIntGive4(int X){ (void)X; return 4; }
    int main()
    {
        assert(sizeof(0)["foobar"] == 1  && 1 == sizeof(char)); //if sizeof were more function-like you'd get 'a'
        assert(takeIntGive4(0)["foobar"] == 'a');
    }
    

    您可以通过将其包装在宏中来使其更像函数:

    #define SIZEOF(X) (sizeof(X))
    

    sizeof 还额外返回整数常量表达式(与可变长度数组 (VLA) 一起使用时除外),您可以在case 标签、位域大小和数组大小以及哪些函数调用表达式无法使用这些表达式返回。

    【讨论】:

      【解决方案5】:

      它是一个运算符,因为它内置在语言中。就像+&lt; 一样,它包含在语言语法中。因此,与用户定义的函数不同,sizeof 运算符可以在编译程序时进行评估。例如,我们可以定义一个函数宏,它返回一个(非可变长度)数组的长度:

      #define LENGTH(array) (sizeof (array) / sizeof (array)[0])
      

      长度表达式在程序编译时计算。在运行时,数组的长度不可用(除非您将其存储在单独的变量中)。

      【讨论】:

      • sizeof 通常不会在编译可变长度数组时进行评估。
      • 并且大多数算术和关系运算符的使用不能在编译时进行评估。
      • @EricPostpischil 感谢您提供信息。我已经更新了答案。
      • @JohnBollinger 确实,操作数必须是常量表达式。
      【解决方案6】:

      sizeof 是一个操作员。它列在C standard 的第 6.5.3p1 节中的一元运算符列表中:

      6.5.3 一元运算符

      语法

      unary-expression:
        postfix-expression
        ++ unary-expression
        -- unary-expression
        unary-operator cast-expression
        sizeof unary-expression
        sizeof (type-name)
        _Alignof (type-name)
      
      unary-operator: one of
        & * + - ~ !
      

      如上所示,它有两种形式。第一种形式是sizeof,后跟一个表达式。请注意,这种形式的括号不是必需的,这与它们所在的函数调用不同。第二种形式是sizeof,后跟括号中的类型名称。只有第二种形式需要括号,并且函数不能传递类型名称。

      在 6.5.3.4 节中进一步将其称为运算符:

      6.5.3.4 sizeof_Alignof 运算符

      ...

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

      【讨论】:

        【解决方案7】:

        sizeof 是函数还是运算符?
        为什么我们说 sizeof(variable) is operator not function?

        除了其他人回答的,代码可以取函数的地址,但不能取sizeof的地址。很喜欢不能取=*的地址。

        size_t (*f1)() = strlen;
        size_t (*f2)() = sizeof;
        //                     ^ error: expected expression before ';' token
        

        对于对象,sizeof 不需要 (),这与函数调用不同。

        char array[42];
        size_t n1 = sizeof array;
        size_t n2 = strlen(array) + 1;
         
        

        sizeof 可以与 types 一起使用,但不能与函数调用一起使用。

        size_t sz1 = sizeof(double);
        size_t sz2 = printf(double);
        //                  ^ error: expected expression before 'double'
        

        【讨论】:

          猜你喜欢
          • 2011-04-26
          • 1970-01-01
          • 1970-01-01
          • 2012-07-20
          • 2011-12-12
          • 2011-02-16
          • 2010-11-26
          • 2011-04-23
          • 2023-03-03
          相关资源
          最近更新 更多