在C语言中,什么是在编译时计算的?
我可以在编译时将变量设置为某个值吗 如果我有一个函数在程序初始化时更改所有在C语言中,什么是在编译时计算的?,c,C,我可以在编译时将变量设置为某个值吗 如果我有一个函数在程序初始化时更改所有structs的值,如果我在编译时这样做,我可以节省大量时间和处理器的使用,可以吗 我了解到静态和全局变量将其值初始化为0。如果我声明likestatic int a=3,将在编译或运行时分配编号3?如果是,复合文字也是真的吗?我怎么知道这是不是真的?(我不知道如何使用调试来实现这一点。) 我也学过常数C表达式,但我不明白这是什么。这对我有用吗?这是什么 更新:我只是问我是否可以在编译时更改变量的值!!!(还有一些事情…优
struct
s的值,如果我在编译时这样做,我可以节省大量时间和处理器的使用,可以吗
我了解到静态和全局变量将其值初始化为0
。如果我声明likestatic 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:我不知道——游戏,视频编辑和图像处理对我来说似乎很流行。游戏中更高的性能意味着你可以拥有更高分辨率的艺术品、更多的敌人等。视频和图像编辑中更高的性能意味着你可以处理更高的分辨率(这是一个软限制——一些用户愿意让计算机长时间编码他们的视频——但这是一个限制)。在很多领域中,结构良好的代码不需要特别的优化就可以足够快。但我认为还有很多地方我们还没有达到这一点。