这只是我今天玩一些代码时所拾取的东西。我仍然是C新手,请善待。
下面的代码基本上是一个只有一个元素的数组,并检查它的大小和值(分别为4和0)。然后,它会在数组中创建新元素,并在再次检查数组大小之前为这些新元素分配值。
我发现阵列的大小不会增加。如果我从start开始创建包含5个元素的数组,则数组大小为20.如果我从start开始只创建1个元素并在之后添加其他4个元素,则数组大小保持为4但仍保留5个带有值的元素。
有人可以解释为什么会这样吗?这是一种在节省空间的同时为数组赋值的安全方法吗?或者这有什么问题吗?
我错过了什么吗?
如果我在错误的Stack Exchange论坛中发布此内容,请告知我,以便我可以将其删除并在其他地方提问,谢谢。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
int n = 5;
char temps[257] = "1 -2 -8 4 5\n";
int arr[1] = {0};
int c;
printf("\n-- START of Test area --\n\n");
// sizeof arr = 4
printf("Initial sizeof(arr) = %d\n\n", sizeof(arr));
// Initial values of arr
printf("Value of arr[0] = %d\n", arr[0]); // 0
printf("Value of arr[1] (no value assigned) = %d\n", arr[1]); // random number
printf("Value of arr[2] (no value assigned) = %d\n\n", arr[2]); // Random number
// sizeof arr = 4
printf("sizeof(arr) = %d\n\n", sizeof(arr));
// -- Creates new array elements and assigns values using temps
sscanf(temps, "%d\n %d\n %d\n %d\n %d\n", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4]);
printf("New array elements and values using temps\n\n");
printf("Value of arr[0] = %d\n", arr[0]); // 1
printf("Value of arr[1] = %d\n", arr[1]); // -2
printf("Value of arr[2] = %d\n", arr[2]); // -8
printf("Value of arr[3] = %d\n", arr[3]); // 4
printf("Value of arr[4] = %d\n", arr[4]); // 5
printf("Value of arr[5] = %d\n\n", arr[5]); // 0
// Sizeof array = 4
printf("sizeof(arr) = %d\n\n", sizeof(arr));
printf("\n-- END of Test area --\n\n");
return 0;
}
答案 0 :(得分:4)
声明数组后,您无法向其添加或减去任何元素,但可以修改
还有一件事是arr
的大小为1
,并且您正在某些语句中访问数组,例如
sscanf(temps, "%d\n %d\n %d\n %d\n %d\n", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4]);
它调用未定义的行为。
答案 1 :(得分:3)
根据定义,数组是一块连续的内存。这意味着你只能告诉编译器一次数组的大小,它将为你的数组分配内存。
例如,如果编写int n[10];
,编译器将在堆栈上保留10个整数值的内存(例如,每个int为8个字节)。
在这种情况下,n[9]
是数组中的最后一个元素,因为n[0]
是第一个元素。
让我更详细地解释一下:
n
实际上是数组第一个元素的内存地址。实际上n[0]
和n
具有相同的内存地址。
如果你有int i;
来表示你想要访问的数组的索引:
n[i]
告诉编译器查看内存位置n + (i * sizeof(int));
编译器知道数组的类型,因此它知道在使用n[i];
时如何计算适当的地址
现在如果i
无效,编译器会提供一个可能包含垃圾的内存地址,或者您可能无权访问。如果你不小心,这会给你带来麻烦。
存在可以根据需要增长和缩小的其他数据结构(例如链表),但是那些通常使用&#34;免费商店&#34;或者&#34;堆内存&#34;并且工作方式与在堆栈上分配的内置数组不同。
答案 2 :(得分:1)
当您声明数组时,无法访问设置的维度的元素&gt; =。 设置的参数应该是常量并且在编译时间
中已知例如
int n;
int arr[n]; // error: this is not known in compilation-time
int arr[2];
arr[5] = 6; // error: arr[5] doesn't actually exists!