このコードには非常に多くの問題があるため、ポインターと引数の受け渡しについて詳しく読んだほうがよいと思います。ただし、いくつかの点があります。
関数で「リスト」を宣言すると、main
すでにスタックに割り当てられています。次に、関数でそれを新たに割り当てようとしadd
ます。
関数内でノードを割り当てたい場合は、add
参照によってポインターを渡す必要があります。つまり、ポインターへのポインターです。これは、それ以外の場合、ポインターが値で渡され、関数が戻るときにポインターへのすべての変更 (つまり、ポインターが指すものではなく、実際のポインター) が失われるためです。
このmalloc
関数は、割り当てられたメモリをクリアしません。それを自動的に行いたい場合は、calloc
関数を使用する必要があります。
nast
ノードをリストにリンクするのではなく、(初期化されていない)ポインターでリストの先頭を上書きするだけです。
構造体でを使用typedef
しますが、実際には this の名前を定義しませんtypedef
。
どうぞ、使わないでくださいgoto
!使いすぎると、コードを読みにくく、理解するのが非常に難しくなる可能性があります (使いすぎると、多くの人は、一度でも使いすぎると主張します)。
これを行う場合add
、リストに追加する値とともに、引数としてポインターへの参照を関数に持たせることになります。次に、その値に新しいノードを割り当て、ポインターが古いリストを指すようにしてリストにリンクしnext
、リスト ポインターを新しいノードを指すように再割り当てします。渡されたリストが の場合、リストがNULL
新しいノードを指すようにします。
このようなもの:
struct node
{
struct node *next;
double value;
};
void add(struct node **l, const double value)
{
/* Allocate a new node, use `calloc` to clear the memory automatically */
struct node *n = calloc(1, sizeof(struct node));
/* Set the value of the new node */
n->value = value;
/* Is the list non-null? */
if (*l != NULL)
{
/* Yes, make the `next` pointer point to the old list */
n->next = *l;
}
/* Make the list point to the new node */
*l = n;
}
この関数は、次のように呼び出すことができます。
/* Initialize to `NULL` to mark the list as empty */
struct node *list = NULL;
/* Add two nodes, passing the list pointer by reference */
add(&list, 12.34);
add(&list, 56.78);
リストには 2 つのノードがあります。
- リストの最初のノードには値が含まれます
56.78
- リストの 2 番目のノードには値が含まれます
12.34