在 C 中初始化数组
Initializing arrays in C
下面的 C 程序创建了一个包含固定数量元素的数组。即使我们再分配三个超过最大数组元素数量的值也能正常工作。
#include <stdio.h>
int main(){
//declares a fixed sized array
int balance[5];
//initializing
balance[0] = 1;
balance[1] = 2;
balance[2] = 3;
balance[3] = 4;
balance[4] = 5;
//three more
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[7]);
//and it works fine!
return 0;
}
但是当我们尝试分配三个以上的元素时它会抛出异常
#include <stdio.h>
int main(){
//declares a fixed sized array
int balance[5];
//initializing
balance[0] = 1;
balance[1] = 2;
balance[2] = 3;
balance[3] = 4;
balance[4] = 5;
//three more
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
//one more again
balance[8] = 9;
printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[7]);
printf("%d \n", balance[8]);
//throws an exception!
return 0;
}
但是在使用整数文字声明和初始化数组后,我们可以插入更多元素而不会出错。
#include <stdio.h>
int main(){
//declares and initialize a fixed sized array
int balance[5] = {1,2,3,4,5};
//let's add few more
balance[5] = 6;
balance[6] = 7;
//and even more
balance[7] = 8;
balance[8] = 9;
balance[9] = 10;
printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[6]);
printf("%d \n", balance[7]);
printf("%d \n", balance[8]);
printf("%d \n", balance[9]);
//and it works fine!
return 0;
}
C语言出现这种行为的原因是什么?
您正在访问未分配的内存,这将调用未定义的行为。什么事情都可能发生。这些都是越界访问
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
balance[8] = 9;
数组越界访问导致未定义的行为。您的数组可以容纳 5 个整数元素,因此您的数组的有效索引是 0
到 4
除此以外的任何数组都是越界访问。
当您尝试越界访问数组时,您的代码调用了未定义行为,这是不安全的内存,因此结果是未定义的。
我想给出一个更通用的答案。这里的每个人都得到了正确的答案,但我想解释为什么并且解释得更冗长一些。
假设您有一个包含 3 个案例的字符数组。
char tab[3];
在内存方面,我们得到的是分配了3例数据。因为它是一个数组,所以它在你的记忆中是对齐的。让我们初始化该数组:
tab[0] = 'A';
tab[1] = 'B';
tab[2] = 'C';
在你的记忆中,它看起来像这样:
现在,如果你写 tab[6]
会发生什么?因为它是 C,你可以清楚地做到这一点,没有任何问题。 (没有electric-fence ;))
在这种情况下,tab[6] 尚未分配给您的程序。从现在开始你可以有任何场景:
- 也许这个数据对系统来说是关键的,你的程序将无法访问那个内存(即分段错误)
- 也许您的程序在某处有另一个数组,您可能会幸运地从那里得到一些东西。
- (其他比这更糟糕的事情)
- ???
基本上,当您引发 越界错误 时,您会导致意外行为。你应该做的是始终注意那些错误,它们可能是你心爱的应用程序的致命杀手。
下面的 C 程序创建了一个包含固定数量元素的数组。即使我们再分配三个超过最大数组元素数量的值也能正常工作。
#include <stdio.h>
int main(){
//declares a fixed sized array
int balance[5];
//initializing
balance[0] = 1;
balance[1] = 2;
balance[2] = 3;
balance[3] = 4;
balance[4] = 5;
//three more
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[7]);
//and it works fine!
return 0;
}
但是当我们尝试分配三个以上的元素时它会抛出异常
#include <stdio.h>
int main(){
//declares a fixed sized array
int balance[5];
//initializing
balance[0] = 1;
balance[1] = 2;
balance[2] = 3;
balance[3] = 4;
balance[4] = 5;
//three more
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
//one more again
balance[8] = 9;
printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[7]);
printf("%d \n", balance[8]);
//throws an exception!
return 0;
}
但是在使用整数文字声明和初始化数组后,我们可以插入更多元素而不会出错。
#include <stdio.h>
int main(){
//declares and initialize a fixed sized array
int balance[5] = {1,2,3,4,5};
//let's add few more
balance[5] = 6;
balance[6] = 7;
//and even more
balance[7] = 8;
balance[8] = 9;
balance[9] = 10;
printf("%d \n", balance[0]);
printf("%d \n", balance[1]);
printf("%d \n", balance[2]);
printf("%d \n", balance[3]);
printf("%d \n", balance[4]);
printf("%d \n", balance[5]);
printf("%d \n", balance[6]);
printf("%d \n", balance[7]);
printf("%d \n", balance[8]);
printf("%d \n", balance[9]);
//and it works fine!
return 0;
}
C语言出现这种行为的原因是什么?
您正在访问未分配的内存,这将调用未定义的行为。什么事情都可能发生。这些都是越界访问
balance[5] = 6;
balance[6] = 7;
balance[7] = 8;
balance[8] = 9;
数组越界访问导致未定义的行为。您的数组可以容纳 5 个整数元素,因此您的数组的有效索引是 0
到 4
除此以外的任何数组都是越界访问。
当您尝试越界访问数组时,您的代码调用了未定义行为,这是不安全的内存,因此结果是未定义的。
我想给出一个更通用的答案。这里的每个人都得到了正确的答案,但我想解释为什么并且解释得更冗长一些。 假设您有一个包含 3 个案例的字符数组。
char tab[3];
在内存方面,我们得到的是分配了3例数据。因为它是一个数组,所以它在你的记忆中是对齐的。让我们初始化该数组:
tab[0] = 'A';
tab[1] = 'B';
tab[2] = 'C';
在你的记忆中,它看起来像这样:
现在,如果你写 tab[6]
会发生什么?因为它是 C,你可以清楚地做到这一点,没有任何问题。 (没有electric-fence ;))
在这种情况下,tab[6] 尚未分配给您的程序。从现在开始你可以有任何场景:
- 也许这个数据对系统来说是关键的,你的程序将无法访问那个内存(即分段错误)
- 也许您的程序在某处有另一个数组,您可能会幸运地从那里得到一些东西。
- (其他比这更糟糕的事情)
- ???
基本上,当您引发 越界错误 时,您会导致意外行为。你应该做的是始终注意那些错误,它们可能是你心爱的应用程序的致命杀手。