在C语言中,什么是在编译时计算的?

在C语言中,什么是在编译时计算的?,c,C,我可以在编译时将变量设置为某个值吗 如果我有一个函数在程序初始化时更改所有structs的值,如果我在编译时这样做,我可以节省大量时间和处理器的使用,可以吗 我了解到静态和全局变量将其值初始化为0。如果我声明likestatic int a=3,将在编译或运行时分配编号3?如果是,复合文字也是真的吗?我怎么知道这是不是真的?(我不知道如何使用调试来实现这一点。) 我也学过常数C表达式,但我不明白这是什么。这对我有用吗?这是什么 更新:我只是问我是否可以在编译时更改变量的值!!!(还有一些事情…优

我可以在编译时将变量设置为某个值吗

如果我有一个函数在程序初始化时更改所有
struct
s的值,如果我在编译时这样做,我可以节省大量时间和处理器的使用,可以吗

我了解到静态和全局变量将其值初始化为
0
。如果我声明like
static int a=3,将在编译或运行时分配编号
3
?如果是,复合文字也是真的吗?我怎么知道这是不是真的?(我不知道如何使用调试来实现这一点。)

我也学过常数C表达式,但我不明白这是什么。这对我有用吗?这是什么

更新:我只是问我是否可以在编译时更改变量的值!!!(还有一些事情…

优化的一些基本原则:

  • 只优化测量(分析)的瓶颈,不要浪费时间优化假想或假设的问题,除非您是重新实现已知计算时间问题的主题专家
  • 不要优化任何东西,除非它处于循环中
但要回答你的问题

始终在编译时:

  • 静态初始化
  • #if
    和其他预处理器宏表达式
通常在编译时:

  • 任何只涉及常数的表达式

    • 如果我理解你的问题,你会好奇哪种变量被放入哪种类型的变量中

      未初始化的全局变量和函数级别
      static
      变量进入
      bss
      部分,这实际上只是对象文件中的一个数字,告诉链接器/加载程序在加载程序或库时为该部分留出多少空间:

      $ readelf --sections /bin/sh
      There are 28 section headers, starting at offset 0x195e8:
      
      Section Headers:
        [Nr] Name              Type             Address           Offset
             Size              EntSize          Flags  Link  Info  Align
      ...
        [26] .bss              NOBITS           0000000000619500  00019500
             0000000000002bd0  0000000000000000  WA       0     0     32
      
      即0x2bd0==11216字节,在运行时为未初始化的变量留出

      初始化的全局变量存储在
      数据
      rodata
      部分:

      $ readelf --sections /bin/sh
      There are 28 section headers, starting at offset 0x195e8:
      
      Section Headers:
        [Nr] Name              Type             Address           Offset
             Size              EntSize          Flags  Link  Info  Align
      ...
        [16] .rodata           PROGBITS         0000000000412de0  00012de0
             0000000000003482  0000000000000000   A       0     0     32
      ...
        [25] .data             PROGBITS         0000000000619300  00019300
             0000000000000200  0000000000000000  WA       0     0     32
      
      抱歉,我忘记了编译器/链接器用来决定哪些变量进入只读部分,哪些变量进入读/写部分的确切规则。但只需说明链接器将为
      rodata
      节将页面保护设置为只读,尝试写入此节将产生页面错误,并可能终止程序

      char *string = "hello world"; /* "hello world\0" goes into rodata
                                       char *string goes into data */
      
      我希望任何仅基于文字整数、浮点和
      sizeof()
      操作的计算都能在编译时进行

      一个很小的例子:

      $ cat test.c
      int i;
      int main(int argc, char *argv[]) {
          return 0;
      }
      $ gcc -o test test.c
      $ size test
         text    data     bss     dec     hex filename
         1044     496      24    1564     61c test
      
      C库带来了很多额外的负担。但是请注意当我们初始化
      i
      时会发生什么,
      bss
      大小会减小,
      数据
      大小会增大:

      $ cat test.c
      int i=1+2;
      int main(int argc, char *argv[]) {
          return 0;
      }
      $ gcc -o test test.c
      $ size test
         text    data     bss     dec     hex filename
         1044     500      16    1560     618 test
      $ 
      
      我假设在我的系统上,
      bss
      被限制为
      8
      的倍数,因为它是兼容AMD64的CPU。其他系统可能需要4的倍数

      $ cat test.c
      int i=sizeof(int);
      int main(int argc, char *argv[]) {
          return 0;
      }
      $ gcc -o test test.c
      $ size test
         text    data     bss     dec     hex filename
         1044     500      16    1560     618 test
      $ 
      

      请注意,切换到
      sizeof(int)
      不会增加
      文本(可执行代码)的大小,也不会更改
      数据的大小。

      如果您无法解释,我们无法回答。您这样说可能是因为您停止了“我不知道如何解释它”,如果你坚持阅读,你会理解我的引文。绝对!如果在编译时初始化结构,将节省数百微秒。也许几千!一个更简单的优化指南——“一点也不要”。在我所有的编程职业中,我从未发现优化任何东西的必要性。对不起,这不是一个关于优化原则的问题,我只想知道如何做到这一点。优化是在后面进行的。@Neil:这是一个广泛的领域。一、 例如,我就在另一端;我的工作就是优化@尼尔:你说优化不能让它更快吗?有些领域的目标是让代码尽可能快——没有“足够快”(也就是说,你尽可能快地编写代码,这决定了你可以处理的数据速率——而不是有一个预定义的数据速率,然后只需要让代码快到足以处理该速率)@Neil:我不知道——游戏,视频编辑和图像处理对我来说似乎很流行。游戏中更高的性能意味着你可以拥有更高分辨率的艺术品、更多的敌人等。视频和图像编辑中更高的性能意味着你可以处理更高的分辨率(这是一个软限制——一些用户愿意让计算机长时间编码他们的视频——但这是一个限制)。在很多领域中,结构良好的代码不需要特别的优化就可以足够快。但我认为还有很多地方我们还没有达到这一点。