14

I'm trying to make a program which

  1. Takes the user input (let's say all of it is int)
  2. Store it in an array without a starting size (i.e. not -> array[5];); and then
  3. Use the information stored in the array for whatever sinister purposes.

I'm asking for help so that I can learn how to do this on my own if needed.

  • How do I make a dynamic array without a set size?
  • How can I use/access/reach the elements in the above array?

Reading just didn't explain enough for me.

I know it's a very noobish question, and yes, I am a noob, but to change that I need some help.

4

5 回答 5

18

对于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或 cmemcopy以及):

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;
于 2012-11-17T14:46:24.617 回答
16

这可能是最聪明的(对某些人来说神秘过度使用 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, " "));
于 2012-11-17T14:49:52.727 回答
10

这是我用 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_arrayint my_dynamic_array[]. 起初,这似乎有点微不足道,但是您需要了解 C 和 C++ 中发生的事情。

当您静态声明一个数组时,您是在告诉程序您要留出该内存供您使用。它实际上就在那里;开始使用它是你的。当你动态创建一个数组时,你从一个指针开始。指针只是对某些内存的引用。该内存尚未分配。如果您尝试使用 访问其中的某些内容my_dynamic_array[3],您将得到一个令人讨厌的错误。那是因为在那个位置的内存中实际上没有任何东西(至少没有任何东西被提供给程序使用)。

还要注意使用delete[]代替delete。这就是您在完成数组后释放内存的方式。

如果您在 C 中执行此操作,您几乎可以以相同的方式考虑这一点,但您有and而不是newand 。delete[]mallocfree

了解动态数组和指针之间的细微差别是很棘手的。我花了一段时间才完全明白发生了什么。祝你好运并坚持下去。

于 2012-11-17T14:47:24.030 回答
1

在 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));

通过这种方式,如果您想要的整数数量少于分配的内存,您可以释放剩余的分配内存。

于 2012-11-17T14:59:07.513 回答
1

我有一个建议给你。如果要使用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);
   }

}
于 2012-11-17T15:35:49.250 回答