C 中的静态、定义和常量 [英] Static, define, and const in C
问题描述
我已经读过静态变量在函数内部使用,当人们不希望每次调用函数时变量值都改变/初始化.但是如何在main"之前在主程序中定义一个静态变量,例如
I've read that static variables are used inside function when one doesn't want the variable value to change/initialize each time the function is called. But what about defining a variable static in the main program before "main" e.g.
#include <stdio.h>
static double m = 30000;
int main(void)
{
value = m * 2 + 3;
}
这里的变量 m 有一个常量值,以后在主程序中不会被修改.在同一思路下,使用这些而不是使用静态定义有什么不同:
Here the variable m has a constant value that won't get modified later in the main program. In the same line of thought what difference does it make to have these instead of using the static definition:
const double m = 30000;
或
#define m 30000 //m or M
然后确保这里在主代码中使用双重操作,以便将 m 转换为正确的数据类型.
and then making sure here to use double operations in the main code so as to convert m to the right data type.
推荐答案
static double m = 30000;
double foo(double x, double y) {
return x/m + y;
}
这不会为你赢得任何东西.必须制作 m 的副本才能进行计算.如果你这样做:
This doesn't win you anything. A copy of m has to be made to do the computation. Also if you do:
double bar( double x, double y) {
m += x + y;
return m;
}
那么所有对 bar 的调用都会改变 m.函数(或类)之外的静态变量实际上是具有文件范围的全局变量.其他文件无法通过 extern 获取
Then all calls to bar will change m. Static variables outside of functions (or classes) are really global variables with file scope. Other files can't get at them by extern
函数内部的静态变量仍然和全局变量一样,只是同一个文件中的其他函数不能直接看到它们.
Static variables inside a function are still like global variables, except that even other functions in the same file can't see them directly.
const double m = 30000;
这更好,在许多情况下是最好的.如果编译器看到这个全局常量,然后看到对 m 的引用,那么它知道而不是生成代码来将值从它所在的位置加载(这可能需要首先将文字地址加载到寄存器中)到寄存器或堆栈位置要进行计算,它可以只使寄存器为 30000,或者有时会生成一条编码为 30000 的指令.
This is better and in many cases best. If the compiler sees this global const and then sees a reference to m then it knows that rather than generate code to load the value from where ever it is (which likely requires loading a literal address into a register first) to a register or stack position to do computations it can just make a register be 30000 or sometimes generate an instruction with 30000 encoded right in there.
这样做的缺点是编译器必须假设其他源文件将要读取 m 并且必须将副本实际存储为目标文件中的变量(但一个常量变量).
The down side to this is that the compiler has to assume that other souce files will want to read m and has to actually store a copy as a variable (but a constant variable) in the object file.
我不确定它是否是标准的,但您有时可以这样做 extern const double m = 30000;
编译器将使用 30000 进行优化并假设另一个文件实际上有 m 的副本这将存储在可执行文件中.您也可以执行 static const double m = 30000;
并且编译器可以假设没有其他人会期望 m 的副本存储在从该源文件生成的目标代码中.
I'm not sure if it is standard but you can sometimes do extern const double m = 30000;
and the compiler will use 30000 to optimize and assume that another file actually has a copy of m that will be stored in the executable. You can also do static const double m = 30000;
and the compiler can assume that no one else will expect that a copy of m is stored in the object code generated from this source file.
在做
#define m 30000
风险更大.如果之前有另一个 m 声明为变量、常量或函数,您将不会收到警告或错误.此外,对于像这样的预处理器宏,很容易搞砸.例如:
is more risky. You will not get a warning or error if previously there was another m declared as a variable, constant, or function. Also, for preprocessor macros like this it is easy to mess up. For example:
#define BASE_ADDRESS 48
#define MY_OFFSET 9
#define MY_ADDRESS BASE_ADDRESS+MY_OFFSET
...
return MY_ADDRESS*4;
是的,这是一个愚蠢的例子,但是在预处理器完成它之后的样子是
Yes, this is a stupid example, but what this looks like after the preprocessor gets done with it is
...
return 48+9*4;
这是
return 48+(9*4);
这可能不是你想要的.
宏不好的另一个地方是当你有很大的常量时,比如字符串.字符串要求它们可以通过指针寻址,并且比整数和浮点文字或常数更难优化.如果你有很多东西,你可以很容易地制作一个非常大的程序:
Another place where macros are bad is when you have large constants, such as strings. Strings require that they be addressable by pointer and are more difficult to optimize away than integers and floating point literal or constant numbers. You could easily make a very large program if you had lots of stuff like:
#define JIM "Jim"
#define JOHN "John"
然后在整个程序中使用 JIM 和 JOHN,因为编译器可能无法看到您在程序中真的只需要字符串Jom"和John"一次.
and then used JIM and JOHN all over your programs because the compiler might not be able to see that you really only needed the strings "Jom" and "John" once in the program.
话虽如此,这样声明常量的情况并不少见,而且通常由知道自己在做什么的人正确地这样做.
That being said, it is not uncommon to see constants being declared like that, and often they are properly done that way by people who know what they are doing.
这篇关于C 中的静态、定义和常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!