C 分工与轮班的区别
我正在读一个问题。在阅读了第一个答案后,我无法理解C 分工与轮班的区别,c,floating-point,division,bit-shift,C,Floating Point,Division,Bit Shift,我正在读一个问题。在阅读了第一个答案后,我无法理解-5>>1=-3的原因。我还对它做了一些调整 您还可以看到代码和输出。 以下是我所做的: #include<stdio.h> int main(){ printf("5/2 = %d\n",5/2); printf("5 >> 1 = %d\n",5 >> 1); printf("5/2 = %lf\n",5/2); printf("5 >> 1 = %f\n",5 >> 1); p
-5>>1=-3
的原因。我还对它做了一些调整
您还可以看到代码和输出。
以下是我所做的:
#include<stdio.h>
int main(){
printf("5/2 = %d\n",5/2);
printf("5 >> 1 = %d\n",5 >> 1);
printf("5/2 = %lf\n",5/2);
printf("5 >> 1 = %f\n",5 >> 1);
printf("-5/2 = %d\n",-5/2);
printf("-5 >> 1 = %d\n",-5 >> 1);
printf("-5/2 = %f\n",-5/2);
printf("-5 >> 1 = %f\n",-5 >> 1);
return 0;
}
我无法理解5/2==2.168831,5>>2==2.168831,5>>1==3
为什么会发生这种情况?(可能答案很基本,我遗漏了一些基本的东西,所以请指导我)。
-5/2
的结果是int
,而不是float
或double
。但是,您的格式说明符是%f
,因此您的int
会被解释为float
,这毫无意义,因此会产生不稳定的值。你所做的被称为未定义行为:任何事情都可能发生。的-5/2
结果是整数
,而不是浮点
或双精度
。但是,您的格式说明符是%f
,因此您的int
会被解释为float
,这毫无意义,因此会产生不稳定的值。你所做的被称为未定义行为:任何事情都可能发生。你看到结果的原因是:
当您传递一个int
参数,但对double
使用printf说明符时(请记住,在这种情况下,float
被转换为double
),大多数C实现都会根据将int
参数传递给变量函数的常规规则传递int
参数(一个接受不同参数类型的函数),但是printf
例程解释机器状态,就像传递了double
参数一样,如下所述。(这不一定总是会发生;一旦您离开C标准定义的行为,C实现可能会做其他事情。特别是,与优化器的复杂交互可能会导致意外的结果。但是,这是最常见的情况。您不能依赖它。)
每个计算平台都有一些参数传递规则。一个平台可能会指定从右到左将所有参数推送到堆栈上,并且每个参数只使用所需的字节数放到堆栈上。另一个平台可能会指定从左到右将参数推送到堆栈上或该参数ts被填充到四个字节的下一个倍数,以保持堆栈对齐。许多现代平台指定在通用寄存器中传递特定大小的整数参数,在浮点寄存器中传递浮点参数,在堆栈上传递其他参数
当printf
看到%f
并查找一个double
参数,但您传递了一个int
,那么printf
找到了什么?如果此平台将这两个参数都推到堆栈上,那么printf
会找到int
的位,但它会将这些位解释为所做的uble
。这会导致printf
打印一个由int
确定的值,但它与int
没有明显的关系,因为这些位在int
和double
的编码中具有完全不同的含义
如果此平台将int
参数放在一个位置,而将double
参数放在另一个位置,则printf
会找到一些与int
参数完全无关的位。它们是刚好留在浮点寄存器中的位,例如,double
参数应该是。这些位只是以前工作的剩余。您得到的值基本上是随机的,与您传递的int
有关。您还可以得到一个混合,通过将传递的int
的四个字节与四个字节一起,使用printf
查找八个字节的双
附近还有什么
当你多次运行该程序时,你经常会看到打印出相同的值。发生这种情况的原因有两个。首先,计算机是机械的。它们以很大程度上确定的方式运行,因此它们会一次又一次地做相同的事情,即使这些事情不是专门为你使用它们的方式设计的。其次,环境每次启动程序时,操作系统传递给程序的环境基本相同。它的大部分内存被清除或从程序文件中初始化。一些内存或其他程序状态是从计算机中的其他环境中初始化的。这些数据可能因程序的不同运行而不同例如,当前时间在不同的运行中明显不同。您的命令历史记录以及命令shell在其环境变量中放置的值也是如此。有时多次运行一个程序会产生不同的结果
当您使用的代码的行为不由某些规范(可能是C规范、编译器规范、机器和操作系统规范或其他文档)定义时,您不能依赖该代码的行为。(即使C标准没有完全指定,也可以依赖由特定C编译器指定的特定C编译器编译的代码的行为。)看到结果的原因是: 当您传递一个
int
参数,但对double
使用printf说明符时(请记住,在这种情况下,float
被转换为double
),大多数C实现都会根据将int
参数传递给变量函数的常规规则传递int
参数(一种接受不同信息的功能
5/2 = 2
5 >> 1 = 2
5/2 = 2.168831
5 >> 1 = 2.168831
-5/2 = -2
-5 >> 1 = -3
-5/2 = 2.168833
-5 >> 1 = 2.168833