如何制作具有动态大小的数组?动态数组的一般用法(也可能是指针)? [关闭]
Posted
技术标签:
【中文标题】如何制作具有动态大小的数组?动态数组的一般用法(也可能是指针)? [关闭]【英文标题】:How to make an array with a dynamic size? General usage of dynamic arrays (maybe pointers too)? [closed] 【发布时间】:2012-11-06 01:30:00 【问题描述】:我正在尝试制作一个程序
-
接受用户输入(假设全部是
int
)
将其存储在没有起始大小的数组中(即不是 -> array[5];
);然后
将存储在数组中的信息用于任何险恶的目的。
我正在寻求帮助,以便我可以在需要时自行学习如何做到这一点。
如何制作没有设置大小的动态数组? 如何使用/访问/到达上述数组中的元素?阅读对我来说解释不够。
我知道这是一个非常菜鸟的问题,是的,我是菜鸟,但要改变这一点,我需要一些帮助。
【问题讨论】:
c 还是 c++?每个人都会有不同的建议。 如果使用 C++ 则查找 std::vector 对于C,你应该学会使用malloc
...
您可以使用 argc 获取参数的大小,并在此基础上执行 int data[argc -1]
C 和 C++ 是非常不同的语言。这是一个可怕的问题。
【参考方案1】:
对于C++:
如果您只需要一个容器,请使用std:vector
。它会照顾您所需的所有内存分配。但是,如果您想开发自己的动态容器(无论出于何种原因),您必须自己处理内存分配。也就是说,当您的数组增长时,您必须分配新的内存块,将当前的数组值复制到新的内存位置并将新值添加到新分配的内存中。通常将这种逻辑包装在一个单独的类中,例如GrowingArray
(像标准提供的vector
类)
编辑
详细说明我的答案(鉴于您将其用于学习目的):
将其存储在没有起始大小的数组中(即不是 -> array[5];)
在这里你想使用这样的东西:int * myDynamicArray;
当用户输入一些值时,您分配将存储这些值的内存块:myDynamicArray = new int[5];
与初始输入的大小。我也建议将数组的大小保存在某个变量中:int arraySize = 5;
如果稍后您想将新值附加到您的myDynamicArray
,首先您必须为增长的数组(当前数组元素+新数组元素)分配新的内存块。假设您有 10 个新值即将到来。然后你会这样做:int* grownArray = new int[arraySize+10];
这会为增长的数组分配新的内存块。然后,您想将项目从旧内存块复制到新内存块并添加用户附加值(我认为您将其用于学习目的,因此我为您提供了用于复制元素的简单循环。您可以使用 std:copy
或 c像memcopy
一样):
int i = 0;
for (; i < arraySize; ++i)
grownArray[i] = myDynamicArray [i];
// enlarge newly allocated array:
arraySize+= 10;
for (; i < arraySize; ++i)
grownArray[i] = newValues from somewhere
// release old memory
delete[] myDynamicArray;
// reassign myDynamicArray pointer to point to expanded array
myDynamicArray = gronwArray;
【讨论】:
感谢并排的代码/解释! 如果对您有帮助,请将答案标记为已接受 :)【参考方案2】:这可能是最聪明的(对某些人来说是过度使用 STL 的神秘方式)...
std::vector<int> vec;
// read integers 1 at a time from the user,
// will stop when non-integer input is entered
std::copy(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_inserter(vec));
// print out the vector
std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
【讨论】:
这里唯一有价值的答案。copy(std::istream_iterator<int>(std::cin), , std::ostream_iterator<int>(std::cout, " "));
很多 :)【参考方案3】:
这是我用 C++ 编写的一些基本代码。
#include <iostream>
int main(int argc, char *argv[])
int* my_dynamic_array;
int size;
std::cin >> size;
my_dynamic_array = new int[size];
for (int k=0; k<size; k++)
my_dynamic_array[k] = k;
for (int k=0; k<size; k++)
std::cout << my_dynamic_array[k] << std::endl;
delete[] my_dynamic_array;
return 0;
好的,这就是这段代码中发生的事情。我们使用 std::cin 提示数组的大小,然后使用 new 关键字为数组动态分配一些内存。这里有一些细节一开始看起来有点奇怪。这似乎让许多 C++ 新开发人员感到困惑。
所以首先我们用指针而不是数组声明来声明我们的动态数组,例如我们使用int *my_dynamic_array
而不是int my_dynamic_array[]
。起初,这似乎有点微不足道,但您需要了解 C 和 C++ 中发生的事情。
当您静态声明一个数组时,您是在告诉程序您要留出该内存供您使用。它实际上就在那里;开始使用它是你的。当你动态创建一个数组时,你从一个指针开始。指针只是对某些内存的引用。该内存尚未分配。如果您尝试使用my_dynamic_array[3]
访问其中的某些内容,您将得到一个严重的错误。那是因为在那个位置的内存中实际上没有任何东西(至少没有任何东西被提供给程序使用)。
还要注意使用delete[]
而不是delete
。这就是您在完成数组后释放内存的方式。
如果您在 C 中执行此操作,您几乎可以用同样的方式思考,但不是 new
和 delete[]
,而是 malloc
和 free
。
了解动态数组和指针之间的细微差别是很棘手的。我花了一段时间才完全明白发生了什么。祝你好运,坚持下去。
【讨论】:
你也是,这有助于填补上述代码中的一些空白 :) 谢谢! 如果数组是动态的,编译器如何知道delete[]
有多少元素?它是否以某种方式保留了对size
的引用?【参考方案4】:
在 C 中你可以使用这个方法。
int i=0;
int *p;
char c;
int size;
printf("Enter size :");
scanf("%d",&size);
int *p=malloc(sizeof(int)*size);
do
printf("Enter Number : ");
scanf("%d",&p[i]);
i++;
printf("Press 'q' or 'Q' to quit or any other key to continue : ");
scanf("%c",&c);
while(c!='q' && c!='Q' && i<=size);
p=realloc(p,i*sizeof(int));
如果您想要的整数数量少于分配的内存,则可以通过这种方式释放剩余的分配内存。
【讨论】:
【参考方案5】:我有一个建议给你。如果您要使用 C
进行开发,可以使用链表代替数组下面是一个例子:
typedef struct linked_list
int x,
struct linked_list *next
linked_list;
struct linked_list *head = NULL;
void add_element(int x)
struct linked_list *elem;
elem = malloc(sizeof(struct linked_list));
elem->x =x;
elem->next = head;
head = elem;
int main()
int x;
struct linked_list *p;
do
printf("Enter Number : ");
scanf("%d",&x);
add_element(x)
printf("Press 'q' or 'Q' to quit or any other key to continue : ");
scanf("%c",&c);
while(c!='q' && c!='Q');
for (p=head;p!=NULL;p=p->next)
printf(%d\r\n",p->x);
【讨论】:
不幸的是访问时间是 O(n)以上是关于如何制作具有动态大小的数组?动态数组的一般用法(也可能是指针)? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章