C等效运算符造成混淆

Vis*_*ngh 6 c

计划1:

#include<stdio.h>
void main()
{
    int i=55;
    printf("%d %d %d %d\n",i==55,i=40,i==40,i>=10);
}
Run Code Online (Sandbox Code Playgroud)

计划2:

#include<stdio.h>
void main(){
    int i = 55;
    if(i == 55) {
        printf("hi");
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个程序0 40 0 1在此处输出输出printf i == 55,输出为0,在第二个程序中i ==55输出为hi.为什么

Dev*_*lus 9

在第一个示例中,运算符以相反的顺序进行计算,因为它们在堆栈中被这样推送.评估顺序是特定于实现的,不是由C标准定义的.所以顺序是这样的:

  1. i = 55初始分配
  2. i> = 10 == true 1
  3. 我== 40 ==假(这是55)0
  4. i = 40分配40
  5. 我== 55 ==假(这是40)0

第二个例子应该是显而易见的.


Jer*_*fin 5

无法保证评估函数参数的顺序.在评估函数的不同参数之间也没有序列点.

这意味着您的第一个电话给不确定的行为,因为这两者使用的现有价值i ,并写入新的值i,而不两者之间的序列点.

但是,在典型情况下,函数的每个参数都将作为单独的表达式进行求值,它们之间不会交错.换句话说,编译器会对评估施加一些顺序,即使标准不要求它这样做.

在可变参数函数的特定情况下,参数通常从右到左被压入堆栈,因此第一个参数(格式字符串)将位于堆栈的顶部.这使得printf查找格式字符串变得容易,然后(基于此)从堆栈的更下方检索其余参数.

如果(在相当典型的情况下)参数在被推入堆栈之前立即被评估,这将导致从右到左评估参数.

具有固定数量的参数的函数几乎不会经常从右到左进行求值,所以如果(例如)你写了一个小包装器,它接受固定数量的参数,然后将那些参数传递给printf,那么就有更大的机会i.在计算55第一个参数to时printf得到值,这样就会生成1而不是0.

但请注意,既不保证结果,也不保证任何有意义的结果 - 因为您有未定义的行为,所以允许任何事情发生.