繁体   English   中英

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

[英]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个带有值的元素。

有人可以解释为什么会这样吗? 这是在节省空间的同时将值分配给数组的安全方法吗? 或者这有什么问题吗?

我想念什么吗?

如果我在错误的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[10]; 编译器将在堆栈上为10个整数值保留内存(例如,每个int为8个字节)。

在这种情况下, n[9]是数组保留的最后一个元素,因为n[0]是第一个元素。

让我更详细地解释一下: n实际上是数组第一个元素的内存地址。 实际上, n[0]n具有相同的存储器地址。 如果你有int i; 表示您要访问的数组的索引:

n[i]告诉编译器查看内存位置n + (i * sizeof(int));

编译器知道数组的类型,因此知道使用n[i];时如何计算适当的地址n[i];

现在,如果i无效,编译器将提供一个可能包含垃圾的内存地址,或者您可能无权访问。 如果您不小心,将会给您带来麻烦。

由于C某种程度上是一种较低级的语言,所以它不支持数组范围检查,也无法为您跟踪数组大小。 这意味着您应该自己跟踪它! 否则您将面临不确定的行为风险。

还有其他数据结构可以根据需要增长和收缩(例如链表),但通常使用“免费存储”或“堆内存”的数据结构,其工作方式不同于在堆栈上分配的内置数组。

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

例如

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!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM