在C语言中,变量初始化和赋值是两个相关、但不完全相同的概念,它们都涉及给变量赋予一个值,但发生的时机和使用的方式有所不同。接下来,让我们讨论一下这两个概念的区别,以及它们在实际编程中的应用。

变量初始化是在变量声明的同时给它赋予一个初始值,这个过程发生在变量的生命周期开始时。初始化可以确保变量在首次使用时已经有一个明确的、可预测的值,从而避免使用未初始化变量可能带来的不确定行为。

变量赋值则是在变量声明之后的任何时候,给变量赋予一个新的值。这个过程可以在程序执行过程中多次发生,每次赋值都会覆盖变量之前的值。

让我们通过一些具体的例子来说明这两个概念的区别:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 变量初始化的例子
int age = 25; // 在声明的同时初始化
float pi = 3.14159; // 初始化浮点数
char grade = 'A'; // 初始化字符

// 变量赋值的例子
int count; // 声明变量,但没有初始化
count = 0; // 赋值操作
count = count + 1; // 再次赋值

// 既有初始化又有赋值的例子
int score = 80; // 初始化
score = 95; // 后续赋值

在上面的例子中,我们可以看到初始化和赋值的不同使用场景。初始化通常在变量声明的同时完成,而赋值可以在之后的任何时候进行。

值得注意的是,变量初始化在某些情况下是必要的,而在其他情况下则是可选的,这取决于变量的存储类别和作用域。例如:

1
2
3
4
5
6
7
// 全局变量和静态变量如果不显式初始化,会被自动初始化为 0
int global_var; // 自动初始化为 0
void function() {
static int static_var; // 自动初始化为 0
int local_var; // 不会自动初始化,值是未定义的,但是在clion里会被自动初始化为1
// ...
}

在上面的例子中,全局变量 global_var 和静态变量 static_var 如果不进行显式初始化,会被自动初始化为 0。而局部变量 local_var 如果不初始化,其值是未定义的,使用未初始化的局部变量可能导致不可预测的结果。

初始化和赋值还有一个重要的区别,就是在于它们的效率。初始化通常比先声明后赋值更高效,特别是对于大型数组或复杂结构体。这是因为初始化可以在编译时完成,而赋值则是在运行时执行的。

让我们看一个数组初始化的例子:

1
2
3
4
5
6
7
8
9
// 数组初始化
int numbers[5] = {1, 2, 3, 4, 5}; // 高效的初始化
// 等效的赋值操作,但效率较低
int numbers[5];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;

在实际编程中,正确地使用初始化和赋值可以提高代码的可读性和效率。初始化应该用于给变量赋予初始值,而赋值则用于在程序执行过程中更新变量的值。

此外,C99 标准引入了指定初始化器(designated initializers),这为数组和结构体的初始化提供了更灵活的方式:

1
2
3
4
5
6
7
8
// 使用指定初始化器初始化数组
int days[7] = {[1] = 31, [3] = 30, [5] = 31}; // 其他元素自动初始化为 0
// 使用指定初始化器初始化结构体
struct Point {
int x;
int y;
};
struct Point p = {.y = 5, .x = 10}; // 顺序可以任意

总结一下,变量初始化和赋值虽然都是给变量赋予值的操作,但它们在使用时机、效率和某些特性上有所不同。初始化发生在变量声明时,可以提高效率并确保变量有一个明确的初始值。赋值则可以在程序执行的任何时候进行,用于更新变量的值。

变量不初始化的情况下
在 C 语言中,如果变量没有显式初始化,那么它的默认值将取决于该变量的类型和其所在的作用域。
对于全局变量和静态变量(在函数内部定义的静态变量和在函数外部定义的全局变量),它们的默认初始值为零。
以下是不同类型的变量在没有显式初始化时的默认值:
整型变量(int、short、long等):默认值为0。
浮点型变量(float、double等):默认值为0.0。
字符型变量(char):默认值为’\0’,即空字符。
指针变量:默认值为NULL,表示指针不指向任何有效的内存地址。
数组、结构体、联合等复合类型的变量:它们的元素或成员将按照相应的规则进行默认初始化,这可能包括对元素递归应用默认规则。
需要注意的是,局部变量(在函数内部定义的非静态变量)不会自动初始化为默认值,它们的初始值是未定义的(包含垃圾值)。因此,在使用局部变量之前,应该显式地为其赋予一个初始值。
总结起来,C 语言中变量的默认值取决于其类型和作用域。全局变量和静态变量的默认值为 0,字符型变量的默认值为 \0,指针变量的默认值为 NULL,而局部变量没有默认值,其初始值是未定义的。

参考: