私はプログラムを作ろうとしています
int
であるとしましょう)array[5];
ではありません)。その後必要に応じて自分でこれを行う方法を学ぶことができるように助けを求めています。
読むだけでは十分に説明できませんでした。
私はそれが非常に初心者の質問であることを知っています、そしてはい、私は初心者ですが、それを変えるには私はいくつかの助けが必要です。
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;
これはおそらく最も賢い方法です(一部の人にとっては暗号化された過度の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, " "));
以下は、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でこれを行っている場合、これはほとんど同じように考えることができますが、new
とdelete[]
の代わりにmalloc
とfree
があります。 。
動的配列とポインターの微妙な違いを知ることは難しいです。何が起こっているのか完全に理解するまでに少し時間がかかりました。頑張ってください。
あなたへの提案があります。 [〜#〜] 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);
}
}
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));
この方法で、必要な整数の数が割り当てられたメモリより少ない場合、割り当てられたメモリの残りを解放できます。