include <stdio.h>
int main() {
int num = 10;
int arr[num];
for(int i = 0; i < num; i++){
arr[num] = i+1;
}
}
我的一些同事说这段代码不正确,而且是非法的。但是,当我运行它时,它没有任何错误。而且他不知道如何解释它为什么有效以及为什么我不应该像这样编码。你能帮我么。我是初学者,我想学习C.
虽然不一定非法,但此代码不会按照您的意图执行。声明数组时,声明要存储的项目数,在此实例中为num
。因此,当你声明num = 10
和arr[num]
时,你得到一个可以容纳10个整数的数组。 C数组从0开始索引,因此索引为0-9,而不是1-10。这可能是非法的意思。由于您正在写入arr[num]
或arr[10]
,因此您尝试使用超出为阵列分配的内存的内存。
另外,如果我正确理解程序的意图,你想用数字1-10填充数组。为此,您需要单独访问每个索引。你几乎就在那里,唯一的问题是arr[num] = i + 1;
。如前所述,它超出了数组的末尾。但是,您应该使用i作为索引,所以arr[i]
,因为这将访问每个索引,0-9。
你在学习C或C ++吗?
你的同事意味着在你的代码中,你正在做一些与你想要的不同的事情。它的工作原因是一些其他因素。因为C / C ++标准正在发展,编译器也是如此。让我演示给你看。
当你是初学者时,通常建议坚持“编译给定大小的类型数组”是int arr[N]
的概念,其中N是常数。你在stack上分配它,你不管理它的内存。
在C ++ 11中,您可以使用constexpr(常量表达式),但仍然不是任意变量。
在C ++ 14中,你可以使用“简单表达式”来表示大小,但在预先获得数组概念之前不应该尝试很多。此外,GCC编译器提供了一个扩展来支持可变大小的数组,它可能是“为什么代码完全正常工作”的解释。
注意:可变大小的数组与动态数组不同。它们不是C / C ++指南第一章中的静态数组。
还有一种现代的方法 - std::array<int, 10>
,但再一次,不要从它开始。
当你需要在运行时创建一个数组时,一切都会改变。首先,你在heap上分配它,你自己管它的内存(如果你没有,你得到内存泄漏,纯C方式)或使用像std::vector
这样的特殊C ++类。在了解Pure C数组之后,应该再次使用向量。
你的同事一定是这样的意思:
int* arr = new int[some_variable]; // this is dynamic array allocation
delete[] arr; // in modern C/C++ you can write "delete arr;" as well
所以,你的编译器使它在这个确切的情况下工作,但你绝对不应该依赖于你尝试过的方法。它根本不是数组分配。
TL; DR:
arr[i] = i + 1
,否则你将始终分配给相同的数组项如果要动态分配长度为n int
s的数组,则需要使用malloc或calloc。 Calloc是数组分配的首选,因为它具有内置的乘法溢出检查。
int num = 10;
int *arr = calloc(num, sizeof(*arr));
//Do whatever you need to do with arr
free(arr);
arr = NULL;
无论何时使用malloc
或calloc
分配内存,请务必记住之后的free
,然后将指针设置为NULL以防止任何意外的,将来的引用,以及防止双重释放。