What & How & Why

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:programming:cpp:cpp_primer:4_expressions [2024/01/14 13:46] – ↷ 页面programming:cpp:cpp_primer:4_expressions被移动至cs:programming:cpp:cpp_primer:4_expressions codingharecs:programming:cpp:cpp_primer:4_expressions [2024/09/22 13:25] (当前版本) – [除法、末除和符号] codinghare
行 43: 行 43:
 </code> </code>
 很显然 '' << '' 运算符无法确定有关于 ''i'' 的表达式的执行顺序。如果前面的 ''i'' 先运算,那打印结果会是 ''0 1'';但如果后面的 ''++i'' 先执行,打印结果则是 ''1 1''。也有可能编译器根本就不会按我们想象来进行运算。\\ \\  很显然 '' << '' 运算符无法确定有关于 ''i'' 的表达式的执行顺序。如果前面的 ''i'' 先运算,那打印结果会是 ''0 1'';但如果后面的 ''++i'' 先执行,打印结果则是 ''1 1''。也有可能编译器根本就不会按我们想象来进行运算。\\ \\ 
-<wrap em>对于没有指定 operands 运算顺序的表达式,如果 operands 牵涉到并改变了同一个值,结果将是 undefined.</wrap>\\ \\ +<WRAP center round important 100%> 
 +<wrap em>对于没有指定 operands 运算顺序的表达式,如果 operands 牵涉到并改变了同一个值,结果将是 undefined.</wrap> 
 +</WRAP> 
 + 
 有四种运算符是保证了 operands 的执行顺序:''&&''、''||''、''?:''、'',''。''&&'' 会先执行左边的 operand, 当左边的 operand 为真的时候才会执行右边的 operand。 有四种运算符是保证了 operands 的执行顺序:''&&''、''||''、''?:''、'',''。''&&'' 会先执行左边的 operand, 当左边的 operand 为真的时候才会执行右边的 operand。
 ==优先级/结合律与表达式的执行顺序== ==优先级/结合律与表达式的执行顺序==
行 84: 行 87:
 iv % dv; //error iv % dv; //error
 </code> </code>
-C++11 中, 如果 ''m'' ''n'' 均为**非零整数**,有 ''m = (m / n) * n + m%n''。也就是说,''m%n'' 与 ''m'' 同号(早期的标准允许 ''m%n'' 向负无穷方向取整,但现在已经被禁止了)。因此,除非 ''-m'' 有溢出导致符号变化(比如 -127 溢出为 128),总有 ''m'' 与 ''m%n'' 同号。该规则只适用于**末除**,即:+C++11 中, 如果 ''m'' ''n'' 均为**非零整数**,有 ''m = (m / n) * n + m%n''。也就是说,''m%n'' 与 ''m'' 同号(早期的标准允许 ''m%n'' 向负无穷方向取整,但现在已经被禁止了)。因此,除非 ''-m'' 有溢出导致符号变化(比如 -127 溢出为 128),总有 ''m'' 与 ''m%n'' **同号**。该规则只适用于**末除**,即:
   * (-m) / n 和 m / -n 均等于 -(m/n)   * (-m) / n 和 m / -n 均等于 -(m/n)
   * m%(-n) 等于 m%n,而 (-m)%n = -(m%n)   * m%(-n) 等于 m%n,而 (-m)%n = -(m%n)
行 293: 行 296:
 \\ \\  \\ \\ 
 常见的位运算符如下: 常见的位运算符如下:
-{{ :programming:cpp:cpp_primer:bit_wise.jpg |}}+{{ cs:programming:cpp:cpp_primer:bit_wise.jpg |}}
 ===Bitwise Shift Operators=== ===Bitwise Shift Operators===
 位移运算符(//Bitwise Shfit Operators//)的作用是对指定的二进制数据进行位移操作。位移运算符具有两个 operands,左边的 operands 是需要被移动的二进制数据,右边的 operands 则是一个**非负整数**,用于指定移动的位数。位移运算最终会产生原有数据的位移过后一份拷贝。 位移运算符(//Bitwise Shfit Operators//)的作用是对指定的二进制数据进行位移操作。位移运算符具有两个 operands,左边的 operands 是需要被移动的二进制数据,右边的 operands 则是一个**非负整数**,用于指定移动的位数。位移运算最终会产生原有数据的位移过后一份拷贝。
行 305: 行 308:
     * 如果数据是 signed 类型,插入 0 或是符号位的拷贝视具体的情况而定。     * 如果数据是 signed 类型,插入 0 或是符号位的拷贝视具体的情况而定。
  
-{{ :programming:cpp:cpp_primer:bitwise_shift.jpg |}}+{{ cs:programming:cpp:cpp_primer:bitwise_shift.jpg |}}
 ===Bitwise NOT operator=== ===Bitwise NOT operator===
 位求反运算符 (//Bitwise NOT operator//) ''~'' 会将当前的二进制数据按位求反: 位求反运算符 (//Bitwise NOT operator//) ''~'' 会将当前的二进制数据按位求反:
-{{ :programming:cpp:cpp_primer:bitwise_not.jpg |}}+{{ cs:programming:cpp:cpp_primer:bitwise_not.jpg |}}
 上图的数据从 ''char'' 提升到了 ''int''(原因见后)。提升过后所有的空位都会被 0 填充,经过反转都变成了 1. 上图的数据从 ''char'' 提升到了 ''int''(原因见后)。提升过后所有的空位都会被 0 填充,经过反转都变成了 1.
 ===AND、OR 和 NOR=== ===AND、OR 和 NOR===
 位与(bitwise AND)''&'' 、位或(bitwise OR)''|'' 和位异或(bitwise NOR)''^'' 这三个运算符按照指定的规则组合 operands: 位与(bitwise AND)''&'' 、位或(bitwise OR)''|'' 和位异或(bitwise NOR)''^'' 这三个运算符按照指定的规则组合 operands:
-{{ :programming:cpp:cpp_primer:bitwise_and_or_nor.jpg?400 |}}+{{ cs:programming:cpp:cpp_primer:bitwise_and_or_nor.jpg?400 |}}
   * ''&'' :operands 都有 1,则为 1, 否则为 0   * ''&'' :operands 都有 1,则为 1, 否则为 0
   * ''|'': operands 两边至少有一个 1,则为 1,否则为 0   * ''|'': operands 两边至少有一个 1,则为 1,否则为 0
行 383: 行 386:
   * **整型提升**(//Intergral Promotion//): 小于 int 的类型,比如 bool / char /short 会在不超出范围内的情况下转化为 int; 在超出 int 表示的范围后转化为 unsigned int。   * **整型提升**(//Intergral Promotion//): 小于 int 的类型,比如 bool / char /short 会在不超出范围内的情况下转化为 int; 在超出 int 表示的范围后转化为 unsigned int。
   * 运算转化:为了保证运算 operand 的类型一致而存在的转换。转换的规则取决于是否有 unsigned 类型的参与(见图):   * 运算转化:为了保证运算 operand 的类型一致而存在的转换。转换的规则取决于是否有 unsigned 类型的参与(见图):
-<html><div align="center"> +{{ :cs:programming:cpp:cpp_primer:unsigned_conversion.svg?500 |}}
-<img src="/_media/programming/cpp/cpp_primer/unsigned_conversion.svg width="500"/> +
-</div> +
-</html> +
-\\+
  
 需要说明的是,//unsigned fit signed// 在这里指的是 signed operand 比 unsigned operand 大一号,并且可以表示 unsigned type。 按书上的例子来说,如果 ''long'' 大于 ''int'' ,且 unsigned int 所有的值都可以用 long 表示,那么所有的 unsigned int 都会被转化成 long。\\ \\ 需要说明的是,//unsigned fit signed// 在这里指的是 signed operand 比 unsigned operand 大一号,并且可以表示 unsigned type。 按书上的例子来说,如果 ''long'' 大于 ''int'' ,且 unsigned int 所有的值都可以用 long 表示,那么所有的 unsigned int 都会被转化成 long。\\ \\