繁体   English   中英

变量的编译时初始化如何在 c 内部工作?

[英]How compile time initialization of variables works internally in c?

编译时初始化仅在我们在变量声明期间为变量赋值时才发生。 更具体地说,声明int a=2期间初始化变量和声明int a; a=2之后初始化变量有什么区别int a; a=2 int a; a=2 ?

在声明int a=2期间和声明int a; a=2之后初始化变量有什么区别int a; a=2 int a; a=2 ?

不同之处在于第二个不是初始化 这是一个任务 当涉及到您非常简单的示例时,实践中没有区别。

结构体和数组

一个很大的区别是一些初始化技巧在常规赋值中不可用。 例如数组和结构初始化。 您将需要 C99 或更高版本。

int x[5] = {1, 2, 3, 4, 5}; // Ok
x = {1, 2, 3, 4, 5};        // Not ok

struct myStruct {
    int x;
    char y;
};

struct myStruct a = {1, 'e'};     // Ok
a = {1, 'e'};                     // Not ok
a = (struct myStruct) {1, 'e'};   // But this is ok
struct myStruct b = {.y = 'e'};   // Also ok
b = (struct myStruct) {.y = 'e'}; // Even this is ok
b = {.y = 'e'};                   // But not this

你可以用一个小技巧来分配数组。 您将数组包装在一个结构中。 但是,我不建议为此目的。 这不值得。

struct myArrayWrapper {
    char arr[5];
};

struct myArrayWrapper arr;
arr = (struct myArrayWrapper) {{1,2,3,4,5}}; // Actually legal, but most people
                                             // would consider this bad practice 

常量变量

如果你已经将一个变量声明为const那么你以后不能改变它,所以它们“必须”被初始化。

const int x = 5; // Ok
x = 3; // Not ok, x is declared as const
const int y;     // "Ok". No syntax error, but using the variable is 
                 // undefined behavior
int z = y;       // Not ok. It's undefined behavior, because y's value
                 // is indeterminate

常量变量并不是严格要求初始化的,但如果你不初始化,它们就会变得毫无价值。

静态变量

它还以一种特殊的方式影响静态变量。

void foo() {
    static int x = 5; // The initialization will only be performed once
    x = 8;            // Will be performed everytime the fuction is called

因此,如果此函数之前已被调用,则该函数将返回 1,否则返回 0:

int hasBeenCalled() {
    static int ret = 0;
    if(!ret) {
        ret = 1;
        return 0;
    }
    return 1;
}

关于静态变量的另一件事是,如果它们没有显式初始化,它们将被初始化为零。 局部变量(具有自动存储的变量)将包含垃圾值。 另外,请注意全局变量是自动静态的。

static int x; // Will be initialized to 0 because it's static
int y;        // Is also static, because it's global
auto int z;   // Not ok. You cannot declare auto variables in global space

int main(void)
{
    int a;        // Will be auto as b
    auto int b;   
    static int c; 
    
    int d;
    d = a;        // Not ok because b is not initialized.
    d = b;        // Not ok
    d = c;        // Ok because static variables are initialized to zero
    d = x;        // Ok
    d = y;        // Ok

在实践中,你永远不会在 C 中使用auto关键字。实际上,没有任何情况下auto是合法的,如果你省略它,它不会默认为auto 对于static并非如此。

您可以在 C 标准的第 6.7.9 章中阅读有关初始化的信息。 作业在第 6.5.16 章中找到

该标准没有定义编译时初始化。 这取决于您的代码开发和运行的环境。

变量如何初始化取决于它们的存储持续时间。 你没有提到它。

每次到达它们的声明时都会写入初始化的自动变量 因此,您展示的拆分版本没有任何区别。

静态变量总是在程序启动前初始化并且只初始化一次。 因此,您的拆分版本不是初始化,每次达到分配时都会完成。

来自现实世界的例子:

大多数(如果不是全部)PC 系统将显式(而不是零)初始化的静态变量的初始值存储在称为data的特殊部分中,该部分由系统的加载程序加载到 RAM。 这样,这些变量在程序启动之前就获得了它们的值。 未显式初始化或具有类似零值的静态变量放置在bss部分中,并在程序启动之前由启动代码填充零。

许多嵌入式系统的程序都保存在不可更改的非易失性存储器中。 在此类系统上,启动代码将段data的初始值复制到其在 RAM 中分配的空间中,产生类似的结果。 相同的启动代码也将bss部分bss

注 1:这些部分不必像这样命名。 但这是常见的。

注2:存储时间的种类较多,见标准第6.2.4章。

只要符合标准,系统就可以自由地实现任何其他类型的初始化,包括将初始值逐步写入其变量中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM