【问题标题】:In C (also C++), how '&' operator works as both address operator and bitwise operator ? As operator overloading is not supported by C在 C(也是 C++)中,'&' 运算符如何同时用作地址运算符和位运算符?由于 C 不支持运算符重载
【发布时间】:2020-07-26 11:54:05
【问题描述】:

运算符 '&' 可用于以下两种方式 int a; scanf("%d",&a);printf("%d",1&2)。 但不同的行为(第一次作为地址运算符,第二次作为按位运算符)。 我知道 C 中不存在运算符重载。那么它是如何工作的?也为 c++ 突出显示。

【问题讨论】:

  • 它的工作原理是在语言规范中被定义为一元和二元运算符
  • 许多个运算符,在不同的上下文中具有不同的含义。 C 在这里与 C++ 不同,因为 &“操作符”在 C++ 中的用途与在 C 中不同。更不用说 C++ 中不存在 C 中的运算符重载了。
  • 那么在 C++ 中它们是否也分别为一元和二进制定义了?
  • 非常感谢您的精彩解释。@Someprogrammerdude
  • 感谢您的精彩解释。 @SamiKuhmonen

标签: c++ c operator-overloading bitwise-operators address-operator


【解决方案1】:

我知道 C 中没有运算符重载。

这是不正确的。如果ab 是整数,a + b 执行整数加法,ab 是浮点数的浮点加法,如果ab 是指针,则执行指针运算。

C 语言中内置了运算符重载。不支持程序定义的自定义运算符重载。

如果& 是一个用于获取地址和执行按位与的运算符,则由语言语法来区分。用于获取地址的& 只能出现在语法中的cast-expression 上。用于按位与的& 只能出现在 AND 表达式 之后和 平等表达式 之前。这些“标记”(cast-expressionAND-expressionequality-expression)您可能不熟悉,但它们是正式定义的在 C 语言的语法中,当编译器解析源代码时,它会识别表达式的结构并将源代码与语法的标记相匹配。这对于 C++ 也是如此,除了一个小的技术差异:在 C++ 中,标记之一是 and-expression 而不是 AND-expression

语法的定义是,对这些标记的识别始终可以唯一区分& 运算符的使用方式。

【讨论】:

    【解决方案2】:

    在“C”语言中,运算符用作表达式的前缀、表达式的后缀或“中缀”(两个表达式之间)时具有不同的含义。

    考虑“*”,它将乘法作为“中缀”运算符,当用作前缀时使用指针间接。类似地,'-' 运算符,它作为'infix' 运算符执行减法,当用作前缀时执行否定。

    基本上,它不是关于覆盖,如果运算符出现在两个表达式之间,或者作为单个表达式的前缀。

    同样,“C”编译器知道 '&' 是按位和还是地址,基于它的位置是表达式:如果它在两个表达式之间,它是 AND,如果它在表达式之前,它是'address-of'。

    请参阅https://en.wikipedia.org/wiki/Infix_notation 了解中缀。

    【讨论】:

    • 您还可以添加 * 在声明中使用时表示“声明为指针”。所以它不仅仅用作表达式中的运算符。
    【解决方案3】:

    C 不支持运算符重载(超出它内置的语言)。 正如你在这个维基百科中看到的那样Operators in C

    Address-of ("address of a") "&a" 定义为 R* K::operator &(); 而

    按位与“a & b”定义为 R K::operator &(S b);

    所以基本上“&”运算符在用作一元运算符和二元运算符时具有不同的含义。其他各种运算符也是如此,例如 "*" 、 "-" 等。

    【讨论】:

      【解决方案4】:

      当应用于左值(在这种情况下为一元运算符)或用于具有两个操作数的数学表达式时,它具有简单的不同含义。

      【讨论】:

        【解决方案5】:

        “运算符&可以两种使用int a; scanf("%d",&a);printf("%d",1&2)。”

        请注意,对于 C++,您忘记了另一个重要的第三个用途。 & 运算符也可用于声明references

        int x = 24;
        int& r_x = x;
        

        【讨论】:

          【解决方案6】:

          该语言首先根据其操作数划分运算符。在一个类别中,可以内置重载。 你的例子是关于第一师的。 Address-of 是一元运算符,按位 AND 是二元运算符。当您在 C++ 中编写运算符函数时,您会看到这两个类别的区别。 运算符重载是语言内置的。示例简单的算术加法运算符。它可以处理简单的单字节整数数据以及浮点数(有效和指数)。基本上它与数学有关。因此,在制作 C 语言时,他们只是将其翻译成功能。在 C 规范中,您找不到重载作为此行为的关键字。在他们看来,公式表达之后,任何东西都必须表达为不同的功能。每个函数都应该根据它提供的功能来命名。当 C++ 引入了创建新类型的机会时,具有基本 n 元形式的运算符允许对新类型进行操作。简而言之,C 的哲学是不同的。

          【讨论】:

            猜你喜欢
            • 2012-11-26
            • 2016-02-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多