簡體   English   中英

指針和值

[英]pointers and values

我編寫了以下代碼,它可以正確打印根值,但不能正確打印ret值。 此處可能會打印一個內存地址(1707388)。 我認為現在可以修改ret了,並且可以在main中看到結果。 任何幫助表示贊賞。

#include <stdlib.h>

struct node{
int value;
    int order;
    struct node *left;
    struct node *right;
};

typedef struct node node_t;

node_t array[10];

void createTree(node_t *p, int order){
    p->value = rand()%10;
    p->order = order;
    printf("%i", p->value);
    printf(" ");
    printf("%i\n", p->order);
    if (!order){
        p->left = NULL;
        p->right = NULL;
        return; 
    }
    order--;
    createTree(&p->left, order);
    createTree(&p->right, order);
}

void traverse(node_t *current, node_t *ret, int size){
    printf("%i\n", current->value); 
    if (current->value > size){
        ret = current;
        traverse(&current->left, &ret, size);
        traverse(&current->right, &ret, size); 
    } 
    return;
}

int main(void){
    node_t *root = &array[0];
    node_t *ret;
    srand(time(NULL));
    createTree(root, 4);
    int i = 3;
    printf("%s", "root-value: ");
    printf("%i\n", root->value);
    traverse(root, ret, i);
    printf("%s", "root-value: ");
    printf("%i\n", root->value);
    printf("%i\n", ret->value);
    return 1;
}

這個:

void createTree(node_t *p, int order)

應該

void createTree(node_t **p, int order)

否則,您將修改本地 node_t指針,而不是函數外部的指針。 您的樹也沒有正確構建。

您正在按價值傳遞ret

void traverse(node_t *current, node_t *ret, int size){

當函數更改為ret ,更改不會傳播回調用者。

這意味着main()中的ret仍未初始化,並且代碼的行為未定義。

要解決此問題,請traverse返回ret或將其作為node_t**

代碼很少有問題。

首先,您沒有為節點正確分配內存。 在您的代碼中,您傳遞了錯誤的指針類型,此外,還傳遞了指向未初始化區域的指針。

在這里,可以如何不同地使用它:

 node_t *createTree(int order)
 {
     node_t *result = malloc(sizeof(*result));
     result->value = rand() % 10;
     result->order = order;
     if (order)
     {
         result->left = createTree(order - 1);
         result->right = createTree(order - 1);
     }
     else
     {
         result->left = result->right = 0;
     }
     return result;
 }

然后,遍歷函數需要一些塊來限制再次失敗的搜索:

node_t *traverse(node_t *current, int size)
{
    node_t *ret = NULL;

    if (current->value > size)
    {
        // assuming current node fit - stops the search
        ret = current;
    } 

    if (!ret && current->left)
    {
        // try left node
        ret = traverse(current->left, size);
    }
    if (!ret && current->right)
    {
        // try right node
        ret = traverse(current->right, size); 
    }
    return ret;
}

如果您需要(通常需要這樣做),則這里有一個destroyTree

void destroyTree(node_t *node)
{
    if (!node) return; // we treat NULL as a valid pointer for simplicity

    destroyTree(node->left);
    destroyTree(node->right);
    free(node);
}

這是一個用法示例:

node_t *root, *found;

root = createTree(4);
found = traverse(root, 3);
if (found)
{
   printf("Found!");
}
destroyTree(root);

traverse(node_t *current, node_t *ret, int size)ret是一個堆棧變量。 換句話說,您是按值傳遞指針,而不是按引用傳遞指針。

您目前所做的基本上與以下內容相同:

int f(int i) {
   ...
   i = <any value>;
   ...
}

在這種情況下,您僅修改值的副本。

在程序中,您還正在修改指針的副本。 在函數之外,指針保持不變。

如果要修改它,則需要傳遞一個指向它的指針:

void traverse(node_t *current, node_t **ret, int size){
    ...
    *ret = current;
    ...
    return;
}

createTree()相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM