0

Hi I'm trying to insert an element inside a list following a certain order(I have to add a equilateral triangle). When I try to use the code I can insert data(triangle measurements) but when I try to print list nothing appear :/.So I think that I wrote bad something in "inserisciPerPerimetro". Some word is written in italian and this is only a part of the code(two functions to add a triangle in my list),if u have to see also other parts let me know. Thanks all! This is my code:

typedef struct punto {
    int x;
    int y;
} PUNTO;

typedef struct triangolo {
    PUNTO v;
    int lato;
} TRIANGOLO;

typedef struct nodo {
    TRIANGOLO t;
    struct nodo *next;
} NODO;

int perimetro(TRIANGOLO t) {
    return t.lato*3;
}

void stampaTriangolo(TRIANGOLO t) {
    printf("Il triangolo ha il lato uguale a: %d con un perimetro pari a %d, il vertice in alto ha coordinate (%d,%d)\n",
    t.lato, perimetro(t),t.v.x,t.v.y);
}

void stampaLista(NODO *head) {
    if(head->next==NULL) {
        printf("Lista vuota!\n");
    } else {
        while(head->next != NULL) {
            head = head->next;
            stampaTriangolo(head->t);
        }
    }
}

TRIANGOLO creaTriangolo() {
    TRIANGOLO nuovo;
    printf("Inserisci il lato del nuovo triangolo: ");
    scanf("%d", &nuovo.lato);
    printf("\n");
    printf("Inserisci le coordinate del vertice con y maggiore:\n");
    printf("x: ");
    scanf("%d",&nuovo.v.x);
    printf("\n");
    printf("y: ");
    scanf("%d",&nuovo.v.y);
    printf("\n");
    
    return nuovo;
}

void inserisciPerPerimetro(NODO *head) {
    NODO* nuovoNodo;
    nuovoNodo = malloc(sizeof(NODO));
    nuovoNodo->t = creaTriangolo();
    nuovoNodo->next = NULL;
    
    if(head==NULL) {
        head = nuovoNodo;
    } else {
        //Ordinamento per perimetro crescente
        while(head->next != NULL) 
            if(perimetro(nuovoNodo->t) < perimetro(head->t)) {
                nuovoNodo->next = head->next;
                head->next = nuovoNodo;
            } else {
                head = head->next;
            }
        
        printf("Inserimento effettuato!\n");
    }
}

int main() {
    /* inizializza la lista */
    NODO *head = malloc(sizeof(NODO));
    head->next = NULL;
    
    int risposta = -1;          // per interazione con utente

    while(risposta != 0) {
        /* richiedi un'operazione all'utente */
        printf("Che operazione vuoi svolgere?\n");
        printf("1 -> Inserisci un triangolo nella lista ordinata secondo il perimetro crescente\n");
        printf("2 -> Cancella il triangolo in testa alla lista\n");
        printf("3 -> Visualizza la lista di triangoli\n");
        printf("0 -> Termina il programma\n");
        scanf("%d", &risposta);

        /* gestisci le operazioni dell'utente */
        if(risposta==1) {
            inserisciPerPerimetro(head);
        }
        //else if(risposta==2)
            //lista = cancellazione(lista);
        else if(risposta==3) {
            stampaLista(head);
        }
        else if(risposta==0) {
            printf("Finito!\n\n");
        }
        else {
            printf("Selezione non valida!\n\n");
        }
    }
}

  • 1
    "*this is only a part of the code*". Debugging questions must provide a complete [mre]. Please take the [tour] and review [ask]. – kaylum Feb 03 '22 at 10:24
  • 1
    Does this answer your question? [Changing address contained by pointer using function](https://stackoverflow.com/questions/13431108/changing-address-contained-by-pointer-using-function) – kaylum Feb 03 '22 at 10:25
  • 1
    Function parameters in C are passed by value. This means `head` is a local variable in `inserisciPerPerimetro`. Setting it in the function does not set the caller's value. See the duplicate post for more details and how to fix. – kaylum Feb 03 '22 at 10:26
  • @kaylum I edited my code.However I think that there is a issue in while cicle into "inserisciPerPerimetro" but idk – Daniele Sadun Feb 03 '22 at 10:37
  • Did you read and understand the other two comments and the answer below? The way you set `head` is wrong. If you don't see that then you'll need to read the answers again more carefully. – kaylum Feb 03 '22 at 10:44

1 Answers1

0

I'm going to assume that you're holding a NODO* in some outer scope, and calling inserisciPerPerimetro on that pointer. If you consider just the first time you do this (when the list is empty), your code will do head = nuovoNodo; so you will be putting the address of the newly allocated node into the pointer head. But this is a local copy of the parameter that you passed to the function, so the pointer in the outer scope will remain unchanged (and its value will be NULL). The next time you call the function, the list will still be empty.

One possible way to solve this is by passing a pointer to your head pointer to the function, so that the value of the pointer in the outer scope can be modified. That is, the function should be defined like this:
void inserisciPerPerimetro(NODO **head) Inside the function, modifications to head should be implemented as: *head = nuovoNodo; And in the outer scope you should have something like:

/*...*/
NODO* head = NULL;
inserisciPerPerimetro(&head);
/*...*/

EDIT:

Note that you are somewhat inconsistent with the node allocations: The head node is allocated in the outer scope (does it ever get its own triangle?), and all the others are allocated within the function. On the other hand, you check inside the function whether head is NULL - how can that happen if you allocate the list head in the outer scope?

Secondly, note that in the first call to inserisciPerPerimetro the while loop will be skipped because head->next is always NULL. This is because you don't handle the case where the new node needs to be inserted after the last node in the list.

AviH
  • 1
  • 2
  • nope also if I add a triangle when my list is empty it doesn't work.However I updated my code perhaps it is more understandable now – Daniele Sadun Feb 03 '22 at 10:39
  • Edited my reply. Note that the issue I mentioned in the original answer is still true. – AviH Feb 03 '22 at 10:53