C语言中的文字和变量在内存和处理时间方面有什么区别?

vfwfrxfs  于 2023-06-05  发布在  其他
关注(0)|答案(2)|浏览(417)

让我们考虑以下两段代码:

#include <stdio.h>
int main(){
    float pi = 3.14;
    float r,circumference ;
    scanf("%f",&r);
    circumference  = 2*pi*r;
    printf("Circumference:%f\n",circumference );
    return 0;
}

在这个例子中,我将值3.14存储在变量pi中。

#include <stdio.h>
int main(){
    float r,circumference ;
    scanf("%f",&r);
    circumference  = 2*3.14*r;
    printf("Circumference:%f\n",circumference );
    return 0;
}

在这个例子中,我直接使用了3.14的文字值。
哪一个是最好的选择,为什么?这两个选项在内存消耗和处理时间方面有何区别?

jum4pzuy

jum4pzuy1#

哪一个是最好的选择,为什么?这两个选项在内存消耗和处理时间方面有何区别?
内存消耗和处理时间差别不大。
2*3.14*r;double计算,2*pi*rfloat计算,因此第二个可能会占用更少或更多的内存和时间。不是因为常数与变量的差异,而是因为类型的差异和转换。
即使示例代码被纠正并始终使用相同的浮点类型,差异也很小。保存您的编码时间进行更大的优化,并让一个功能良好的编译器做低级别的优化。Is premature optimization really the root of all evil?

  • 代码说明。
  • 统一使用类型。
  • 使用double浮点。只有在有令人信服的理由时才使用floatlong double
#define MY_PI     3.1415926535897932384626433832795
    #define MY_PI_F   3.1415926535897932384626433832795f
    #define MY_PI_LD  3.1415926535897932384626433832795L
  
    float r = ...
    float circumference = 2*MY_PI_F*r;
    // or with double
    double r = ...
    double circumference = 2*MY_PI*r;

请注意,OP的2个代码在39.4%的时间内 * 功能上 * 不相同,这是由于类型更改,double计算提供了更好的答案。

#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <math.h>

int main() {
  unsigned long fi = 0, di = 0;
  float pi = 3.14;
   for (float r = FLT_MAX; r > 0.0; r = nextafterf(r, 0.0)) {
     fi++;
     float circumference1  = 2*3.14*r;
     float circumference2  = 2*pi*r;
     if (circumference1  != circumference2) {
       if (di == 0) printf("%.9g %.9g %.9g\n", r, circumference1, circumference2);
       di++;
     }
   }
   printf("Differences: %.1f%%\n", 100.0*di/fi);
}

当使用float circumference1 = 2*3.14f*r;时,我没有发现功能上的差异,但这在C中并不确定。

e4yzc0pl

e4yzc0pl2#

简短的回答是,字面量通常比变量更适合内存。或者由于编译器优化而没有区别。
立即值,a.k.数字文字直接存储在指令 * 内。它存储在代码段中。如果使用变量,则在运行时在堆栈上分配内存。除非编译器优化了输出的值。
字符串文字作为字符数组存储在.text段中。无论如何都要消耗内存。字符串变量是指针。数组的起始地址的值存储在变量中并在堆栈上分配。
如果将字符串文字作为参数传递,则地址的立即值将被推送到堆栈,并占用很少的内存。
如果你想同时获得可读性和内存的优势,你可能会喜欢使用#define宏。它将允许给予魔法数字命名。

#define PI 3.14

宏是在预处理器编译之前将被其实际值替换的字。有很多有趣的事情你可以用它们来实现。

  • 取决于体系结构。例如,在ARM中,一些值不能由指令表示,并且必须存储在只读存储器中。

相关问题