web-dev-qa-db-ja.com

動的なサイズの配列を作成するにはどうすればよいですか?動的配列の一般的な使用法(おそらくポインターも)?

私はプログラムを作ろうとしています

  1. ユーザー入力を受け取ります(すべてがintであるとしましょう)
  2. 開始サイズなしで配列に格納します(つまり、-> array[5];ではありません)。その後
  3. どんな不吉な目的のために配列に格納された情報を使用してください。

必要に応じて自分でこれを行う方法を学ぶことができるように助けを求めています。

  • サイズを設定せずに動的配列を作成するにはどうすればよいですか?
  • 上記の配列の要素をどのように使用/アクセス/到達できますか?

読むだけでは十分に説明できませんでした。

私はそれが非常に初心者の質問であることを知っています、そしてはい、私は初心者ですが、それを変えるには私はいくつかの助けが必要です。

8
hilchev

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またはmemcopyのようなc)):

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;
17
Robertas

これはおそらく最も賢い方法です(一部の人にとっては暗号化された過度の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, " "));
13
David

以下は、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を使用して配列のサイズを要求し、次に新しいキーワードを使用して配列にメモリを動的に割り当てます。ここには、最初は少し奇妙に見える詳細がいくつかあります。多くの新しいC++開発者と混乱を引き起こしているようです。

したがって、最初に、配列宣言の代わりにポインタを使用して動的配列を宣言しました。 int *my_dynamic_arrayではなくint my_dynamic_array[]を使用しました。最初はこれはちょっとささいなことのように見えますが、CとC++で何が行われているのかを理解する必要があります。

静的に配列を宣言するときは、使用するメモリを確保しておくことをプログラムに伝えます。実際にあります。使い始めるのはあなた次第です。配列を動的に作成するときは、ポインタから始めます。ポインタは、一部のメモリへの参照にすぎません。そのメモリはまだ割り当てられていません。たとえばmy_dynamic_array[3]を使用してその中の何かにアクセスしようとすると、厄介なエラーが発生します。これは、その場所のメモリには実際には何もないためです(少なくとも、使用するプログラムに与えられたものは何もありません)。

また、deleteの代わりにdelete[]を使用していることに注意してください。これが、配列を使い終わったときにメモリを解放する方法です。

Cでこれを行っている場合、これはほとんど同じように考えることができますが、newdelete[]の代わりにmallocfreeがあります。 。

動的配列とポインターの微妙な違いを知ることは難しいです。何が起こっているのか完全に理解するまでに少し時間がかかりました。頑張ってください。

7
austin

あなたへの提案があります。 [〜#〜] 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);
   }

}
1
MOHAMED

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

この方法で、必要な整数の数が割り当てられたメモリより少ない場合、割り当てられたメモリの残りを解放できます。

0
Omkant