yCa*_*ran 19 c static const c-preprocessor
我已经读过,当每次调用函数时不希望变量值改变/初始化时,静态变量在函数内部使用.但是如何在"main"之前在主程序中定义变量static,例如
#include <stdio.h>
static double m = 30000;
int main(void)
{
value = m * 2 + 3;
}
Run Code Online (Sandbox Code Playgroud)
这里变量m具有一个常量值,以后不会在主程序中修改.在同样的思路中,它有什么不同,而不是使用静态定义:
const double m = 30000;
Run Code Online (Sandbox Code Playgroud)
要么
#define m 30000 //m or M
Run Code Online (Sandbox Code Playgroud)
然后确保在主代码中使用双重操作,以便将m转换为正确的数据类型.
nat*_*ose 16
static double m = 30000;
double foo(double x, double y) {
return x/m + y;
}
Run Code Online (Sandbox Code Playgroud)
这不会赢得任何东西.必须制作m的副本来进行计算.如果你这样做:
double bar( double x, double y) {
m += x + y;
return m;
}
Run Code Online (Sandbox Code Playgroud)
然后所有对bar的调用都会改变m.函数(或类)之外的静态变量实际上是具有文件范围的全局变量.其他文件无法通过extern获取
函数内部的静态变量仍然类似于全局变量,除了即使同一文件中的其他函数也无法直接看到它们.
const double m = 30000;
Run Code Online (Sandbox Code Playgroud)
这是更好的,在许多情况下是最好的.如果编译器看到这个全局const,然后看到对m的引用,那么它知道而不是生成代码来从任何地方加载值(这可能需要先将文本地址加载到寄存器中)到寄存器或堆栈位置要进行计算,它只能使寄存器为30000,或者有时会生成30000编码的指令.
这方面的缺点是编译器必须假设其他源文件将要读取m并且必须实际将副本存储为目标文件中的变量(但是常量变量).
我不确定它是否是标准的,但你有时可以这样做extern const double m = 30000;,编译器将使用30000进行优化,并假设另一个文件实际上有一个m的副本,它将存储在可执行文件中.您也可以这样做static const double m = 30000;,并且编译器可以假设没有其他人会期望m的副本存储在从此源文件生成的目标代码中.
干
#define m 30000
Run Code Online (Sandbox Code Playgroud)
风险更大.如果之前有另一个m声明为变量,常量或函数,则不会收到警告或错误.此外,对于像这样的预处理器宏,它很容易搞砸.例如:
#define BASE_ADDRESS 48
#define MY_OFFSET 9
#define MY_ADDRESS BASE_ADDRESS+MY_OFFSET
...
return MY_ADDRESS*4;
Run Code Online (Sandbox Code Playgroud)
是的,这是一个愚蠢的例子,但在预处理器完成之后看起来是这样的
...
return 48+9*4;
Run Code Online (Sandbox Code Playgroud)
这是
return 48+(9*4);
Run Code Online (Sandbox Code Playgroud)
那不是你想要的.
宏是坏的另一个地方是你有大的常量,比如字符串.字符串要求它们可以通过指针寻址,并且比整数和浮点字面值或常数更难以优化.如果你有很多东西,你可以很容易地制作一个非常大的程序:
#define JIM "Jim"
#define JOHN "John"
Run Code Online (Sandbox Code Playgroud)
然后在你的程序中使用JIM和JOHN,因为编译器可能无法在程序中看到你真的只需要字符串"Jom"和"John".
话虽这么说,看到常量被这样宣告的情况并不少见,而且通常他们是那些知道他们在做什么的人那样做的.
static对于在函数外部声明的对象,仅使对象成为转换单元的本地对象(即,不能从其他.c文件访问它).它不会使它保持不变.它const是为了.它们是正交的,因此您可以拥有一个或另一个或两者.
例如
static const double m = 5;
Run Code Online (Sandbox Code Playgroud)
的#define声明了(在这种情况下)可以被用作一个恒定值的宏.没有对象,所以const不适用,因为没有对象可以更改.因此,您也无法获取宏的地址.
在编写时,const double m=3000;您告诉编译器m在目标文件中创建一个可以从其他文件访问的符号.编译器可以内联的价值m在那里它被定义在文件中,但符号仍然有被分配单独编制的目的.
当你编写时,#define m 3000你只是使用语法方便在源文件中的几个地方写入相同的常量.