在C语言(也包括C++)中,“&”运算符如何同时作为地址运算符和位运算符?由于C不支持运算符重载。

4

运算符'&'可以用两种方式,分别是: int a; scanf("%d",&a);printf("%d",1&2)。 但在第一种情况下是地址运算符,在第二种情况下是按位运算符。我知道C语言中没有运算符重载,那么它是如何工作的呢?同时请说明C++中的情况。


它的工作原理是在语言规范中以不同的方式定义为一元运算符和二元运算符。 - Sami Kuhmonen
有许多运算符在不同的上下文中具有不同的含义。C语言与C++语言在这方面存在差异,因为在C++中,“&”“运算符”可以用于不同于C语言的事情。更不用说在C++中还存在运算符重载,而这在C语言中是不存在的。 - Some programmer dude
它们在C++中一元和二元也是分别定义的吗? - Rishi
@Someprogrammerdude 为什么你在“operator”一词上使用引号?据我所知,它是正式的运算符。 - RobertS supports Monica Cellio
@RobertS支持MonicaCellio,可能只是我使用了更老式的术语。 - Some programmer dude
显示剩余4条评论
6个回答

6
我知道在C语言中没有运算符重载。但这是不正确的。如果a和b是整数,则"a + b"执行整数加法;如果a和b是浮点数,则执行浮点加法;如果a或b是指针,则执行指针算术。C语言将运算符重载内置于语言中,但不支持程序定义的自定义运算符重载。对于"&"既可用于取地址又可用于按位AND运算符的情况,区分二者是由语言语法来实现的。取地址的"&"只能出现在语法中应用于“cast-expression”之后,而按位AND的"&"只能出现在“AND-expression”之后、“equality-expression”之前。这些“tokens”(即“cast-expression”、“AND-expression”和“equality-expression”)可能对您来说不太熟悉,但它们在C语言的语法中被正式定义,当编译器解析源代码时,它会识别表达式的结构并将源代码匹配到语法的标记上。对于C++也是如此,只有一个微小的技术差别:在C++中,其中一个标记是“and-expression”,而不是“AND-expression”。语法的定义使得识别这些标记始终可以唯一地区分“&”运算符的使用方式。

2
在"C"语言中,运算符在用作表达式前缀、表达式后缀或“中缀”(两个表达式之间)时具有不同的含义。
考虑'*',作为“中缀”运算符执行乘法,作为前缀时执行指针间接引用。类似地,'-'运算符作为“中缀”运算符执行减法,在作为前缀时执行否定。
基本上,这并不是关于覆盖,而是如果运算符出现在两个表达式之间,或者作为单个表达式的前缀。
同样地,“C”编译器知道'&'是位与还是地址,基于它在表达式中的位置:如果它在两个表达式之间,则是AND;如果它在表达式之前,则是“地址”。
请参阅https://en.wikipedia.org/wiki/Infix_notation了解中缀。

你还可以补充说明,当在声明中使用时,*表示“声明为指针”,因此它不仅仅是表达式中的运算符。 - Some programmer dude

1
C不支持运算符重载(除了语言内置的内容)。如您在这个维基百科Operators in C中所看到的。
取地址运算符("address of a")"&a"被定义为R* K::operator &();
而位与运算符("&")"a & b"被定义为R K::operator &(S b);
因此,当作为一元运算符和二元运算符使用时,“&”运算符有不同的含义。其他各种运算符(如“*”,“-”等)也是如此。

0

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


0

语言首先根据其操作数来分配运算符。其中一类可以内置重载。你的例子是关于第一类的。取地址是一元运算符,位与是二元运算符。当你在C++中编写运算符函数时,你将看到这两个类别之间的差异。 运算符重载是语言内置的。例如简单的算术加法运算符。它可以使用简单的一字节整数数据以及浮点数(显著性和指数)进行计算。基本上这就是数学。因此,在制作C语言时,他们只是将这些转化为功能。在C规范中,您无法找到“overloading”作为此行为的关键字。根据他们的说法,在公式表达式之后,任何东西都必须表示为不同的函数。每个函数应基于其提供的功能命名。当C++引入创建新类型的机会时,带有基本n-nary形式的运算符允许操作新类型。简而言之,C的哲学是不同的。


0
运算符&可以在以下两种方式中使用:int a; scanf("%d",&a);printf("%d",1&2)
请注意,在C++的情况下,您忘记了另一个重要的第三种用法。运算符&也可以用于声明引用
int x = 24;
int& r_x = x;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接