即使在向数组中添加更多具有值的元素后,数组的大小仍保持不变

Size of array stays the same even after adding more elements with values to the array

这只是我今天在玩代码时得到的东西。本人还是C菜鸟,还请多多指教

下面的代码基本上是获取一个只有一个元素的数组并检查其大小和值(分别为 4 和 0)。然后它在数组中创建新元素并为这些新元素赋值,然后再次检查数组的大小。

我发现数组的大小没有增加。如果我从一开始创建包含 5 个元素的数组,则数组大小为 20。如果我从一开始仅创建 1 个元素并稍后添加其他 4 个元素,则数组大小保持为 4,但仍包含 5 个具有值的元素。

有人可以解释为什么会这样吗?这是在保存 space 的同时为数组赋值的安全方法吗?或者这有什么问题吗?

我是不是漏了什么?

如果我在错误的 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;
}

一旦声明了数组,您就不能向其添加或减去任何元素,但可以修改。
还有一件事是 arr 的大小为 1 并且您在某些语句中访问数组超出范围,例如

sscanf(temps, "%d\n %d\n %d\n %d\n %d\n", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4]); 

它调用未定义的行为。

声明数组时,无法访问 >= 所设置维度的元素。 设置的参数应该是常量并且在编译时已知

例如

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!

根据定义,数组是一块连续的内存。这意味着你只能告诉编译器一次数组的大小,它会为你的数组分配内存。

例如,如果您编写 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 无效,编译器将提供一个可能包含垃圾的内存地址,或者您可能无法访问。一不小心就会出问题。

由于 C 在某种程度上属于低级语言,因此它不支持数组边界检查,也不会为您跟踪数组大小。这意味着你应该自己跟踪它!否则您将面临未定义行为的风险。

存在其他可以根据需要增长和收缩的数据结构(例如链表),但这些数据结构通常使用 "the free store" 或 "heap memory" 并且工作方式不同于分配在堆栈。