“的定义是什么?”;算术运算“;在C99中?

“的定义是什么?”;算术运算“;在C99中?,c,c99,language-lawyer,C,C99,Language Lawyer,在C99中,算术运算这个术语出现了16次,但我没有看到它的定义 术语算术运算符在文本中仅出现两次(同样没有定义),但它确实出现在索引中: 算术运算符 添加剂,6.5.6,G.5.2 按位,6.5.10,6.5.11,6.5.12 增量和减量,6.5.2.4,6.5.3.1 乘法6.5.5,G.5.1 班次,6.5.7 一元,6.5.3.3 然后我们有+-|&+-*%~/code>作为算术运算符,如果索引被认为是规范的话 也许我们应该将算术运算定义为算术运算符的使用。但是F9.4.5说,sqrt(

在C99中,算术运算这个术语出现了16次,但我没有看到它的定义

术语算术运算符在文本中仅出现两次(同样没有定义),但它确实出现在索引中:

算术运算符

添加剂,6.5.6,G.5.2
按位,6.5.10,6.5.11,6.5.12
增量和减量,6.5.2.4,6.5.3.1
乘法6.5.5,G.5.1
班次,6.5.7
一元,6.5.3.3

然后我们有
+
-
|
&
+
-
*
%
~/code>作为算术运算符,如果索引被认为是规范的话


也许我们应该将算术运算定义为算术运算符的使用。但是F9.4.5说,
sqrt()
函数也是一种算术运算,有关详细信息,请参考IEC 60559(又称IEEE754)。因此,必须有算术运算,而不仅仅是算术运算符的使用。

算术运算涉及数字的操作
sqrt
也可以处理数字,这可能是标准称其为算术运算的原因

因为我们没有正式的定义,让我们看看是否可以拼凑出算术运算应该是什么的基本原理解释。这将是推测性的,但我找不到任何明显的缺陷报告或未解决的问题

我想我会从什么被认为是算术类型开始,这在
6.2.5节
types第18段中有介绍(重点放在后面):

整数和浮点类型统称为算术类型。 每个算术类型都属于一个类型域:实类型域 包含实类型,复杂类型域包含 复杂类型

好的,我们知道算术运算必须对整数或浮点类型进行运算。那么什么是手术呢?似乎我们在定义第2节
5.1.2.3
程序执行第2段时做得很好,该段说:

访问易失性对象、修改对象、修改文件或 调用执行任何这些操作的函数都是侧面的 影响,11),即执行状态的变化 环境[……]

因此,修改一个对象或调用一个函数,这是一个操作。什么是物体?第3.14节规定:

执行环境中的数据存储区域 哪些可以表示值

尽管该标准似乎更宽松地使用术语“操作”来表示评估,例如在第7.12.1节“错误条件的处理”中,它说:

中每个函数的行为都是为所有 其输入参数的可表示值,除非另有说明 否则每个函数的执行都应像单个函数一样 操作时不会产生任何外部可见的异常 条件

在第6.5节中,第8段说:

浮动表达式可以收缩,也就是说,其计算方式类似于 这是一次原子行动[……]

因此,这似乎意味着评估是一种操作


因此,从这些章节看来,几乎所有的算术运算符和任何数学函数都属于算术运算的常识定义。

我能找到的最有说服力的一点是隐式定义在7.14信号处理,第3段,在SIGFPE信号的定义中:

SIGFPE-一种错误的算术运算,如零除法或导致溢出的运算

人们可能会得出结论,任何可能导致SIGFPE升高的操作都可以被视为算术运算;只有算术运算才能导致SIGFPE信号升高

这几乎涵盖了
和算术运算符中的任何内容,如果实现了
。虽然整数类型可能不会引发信号,但允许有符号溢出和其他“异常”条件生成陷阱表示,这意味着在获得有效值之前,不可能可靠地执行其他操作-这只能通过赋值来完成。换句话说,该定义同样适用于整数值的运算


因此,除了获取对象/类型的大小、取消引用指针和获取对象的地址之外,几乎任何操作都可以被视为算术操作。请注意,
a[n]
*((a)+(n))
,因此即使使用数组也可以被视为一种算术运算。

大概
中的所有内容都是“算术”的?确切地说,
sqrt在IEC 60559中完全指定为基本算术运算。
@chux so,你应该排除位运算符吗?@Matt是的,位运算符更适合描述为逻辑运算符而不是算术运算符。当然这是在意见的范围内。@ChronoKitsune有些事情是用算术运算来规定的。6.2.6.2#1脚注“任何对有效值的算术运算都不能生成陷阱表示法”促使我提出了这个问题;然而,至少7.14#3、F.8.1和H.3也规定了仅适用于算术运算的行为。在算术运算符中,只有复合赋值运算符实际修改对象,所以这个定义是错误的。@BenVoigt它说的是存储区域,如果它产生一个值,就必须修改存储区域。C中的运算符不“返回”值。它们出现在计算的表达式中。只在C++中使用用户定义的运算符