簡體   English   中英

代碼是打印指針地址(我認為)而不是值?

[英]Code is printing pointer address (I think) instead of value?

我有一個列表定義為

typedef struct node {
    Voo *voo;
    ListaReservas nodeReservas; /* Ignore this */
    struct node *next;
} *Node;

我創建了一些函數來幫助我從列表中添加或刪除節點,例如:

/* creates a node */
Node criaNode(Voo v) {
    Node new = (Node)malloc(sizeof(struct node));
    new->voo = &v; 
    /* I had new->voo = v; but vscode told me it was wrong so i changed it to &v */
    new->next = NULL;
    return new;
}

Voo 定義為:

typedef struct {
    int dia;
    int mes;
    int ano;
} Data;

typedef struct {
    int horas;
    int minutos;
} Tempo;

typedef struct {
    char codigo[LEN_CODIGO + 1];
    char partidaID[LEN_ID + 1];
    char chegadaID[LEN_ID + 1];
    Data datapartida;
    Tempo horapartida;
    Tempo duracao;
    Data datachegada;
    Tempo horachegada;
    int capacidade;
} Voo;

現在我想遍歷列表並打印它的值

Voo *v;
for (n = headVoos; n != NULL; n = n->next) {
    v = n->voo;                         
    printf("%s %s %s %.2d-%.2d-%d %.2d:%.2d\n",
           v->codigo, v->partidaID, v->chegadaID,
           v->datapartida.dia, v->datapartida.mes, v->datapartida.ano, 
           v->horapartida.horas, v->horapartida.minutos);
}

程序打印不正確。 例如它應該出現在哪里

AA1 AAA AAD 16-03-2022 14:50

它出現了

� 146187376-32765--1940381952 40355300:50

是什么原因造成的,以后我該如何避免?

編輯struct node中替換Voo *voo定義為Voo voo ,我現在在其中一個輔助功能中遇到錯誤:

/* deletes node */
Node eliminaNode(Node head, Voo v)
{
    Node n, prev;
    for (n = head, prev = NULL; n != NULL; prev = n, n = n->next)
    {
        if (n->voo == v) /* expression must have arithmetic or pointer error */
        {
            if (n == head)
                head = n->next;
            else
                prev->next = n->next;
            free(n->next);
            free(n);
            break;
        }
    }
    return head;
}

criaNode ,您獲取參數v的地址並通過指向動態 memory 的指針從 function 返回它。該地址在 function 返回后不再有效。 隨后取消對該無效地址的引用會觸發未定義的行為

struct node直接包含一個Voo而不是指向一個 Voo 的指針可能更有意義。 因此,將成員更改為非指針:

Voo voo;

並直接分配參數:

new->voo = v; 

這里有多個問題:

  • 結構和結構指針之間似乎存在混淆。 在 C 中,您必須了解操作對象(作為本地對象分配或從頭部分配,作為 arguments 傳遞或作為值返回)和指向對象的指針之間的區別,這是更慣用的 arguments 函數並允許函數修改 object他們指向。

  • 一個非常容易出錯的結構加劇了這種混亂:將指針隱藏在 typedef 后面。 不要那樣做,為實際結構定義 object 類型,使用與struct標記相同或不同的名稱,並使用*語法使所有指針顯式。

  • 您傳遞一個實際的Voo object 作為參數,並使用該參數的地址分配一個列表節點。 這是不正確的,因為一旦 function 返回,該參數將被丟棄,使列表指向無效的 memory 並解釋您觀察到的奇怪的 output。

  • Node eliminaNode(Node head, Voo v)應該采用指向頭節點的指針並返回成功指示符。 它應該有一個Voo *參數,它不應該是free(n->next)因為下一個節點在刪除后仍在使用中。

這是修改后的版本:

#include <stdio.h>
#include <stdlib.h>

#define LEN_CODIGO  30
#define LEN_ID      30

typedef struct Data {
    int dia;
    int mes;
    int ano;
} Data;

typedef struct Tempo {
    int horas;
    int minutos;
} Tempo;

typedef struct Voo {
    char codigo[LEN_CODIGO+ 1];
    char partidaID[LEN_ID + 1];
    char chegadaID[LEN_ID + 1];
    Data datapartida;
    Tempo horapartida;
    Tempo duracao;
    Data datachegada;
    Tempo horachegada;
    int capacidade;
} Voo;

typedef struct Node {
    struct Voo *voo;
    //ListaReservas nodeReservas; /* Ignore this */
    struct Node *next;
} Node;

/* creates a node */
Node *criaNode(Voo *v) {
    /* allocation with calloc is safer as the object will be initialized to 0 */
    Node *nodep = calloc(1, sizeof(*new));
    if (nodep) {
        nodep->voo = v; 
        nodep->next = NULL;
    }
    return nodep;
}

/* deletes node */
int eliminaNode(Node **head, Voo *v) {
    for (Node *n = *head, *prev = NULL; n != NULL; prev = n, n = n->next) {
        if (n->voo == v) {
            if (n == *head)
                *head = n->next;
            else
                prev->next = n->next;
            free(n);
            return 1;  /* article was found and freed */
        }
    }
    return 0;  /* article was not found */
}

void printList(const Node *head) {
    for (const Node *n = head; n != NULL; n = n->next) {
        const Voo *v = n->voo;                         
        printf("%s %s %s %.2d-%.2d-%.2d %.2d:%.2d\n",
               v->codigo, v->partidaID, v->chegadaID,
               v->datapartida.dia, v->datapartida.mes, v->datapartida.ano, 
               v->horapartida.horas, v->horapartida.minutos);
    }
}

暫無
暫無

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

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