Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marathon: arriva il Fortnite hardcore
Marathon: arriva il Fortnite hardcore
Marathon è il titolo multiplayer competitivo del momento. Ecco quali sono le caratteristiche di gioco principali, insieme alle nostre prime considerazioni dopo qualche "run" nell'extraction shooter di Bungie
HP Imagine 2026: abbiamo visto HP IQ all’opera, ecco cosa può (e non può) fare
HP Imagine 2026: abbiamo visto HP IQ all’opera, ecco cosa può (e non può) fare
A New York HP ha messo al centro della scena HP IQ, la piattaforma di IA locale da 20 miliardi di parametri. L’abbiamo vista in funzione: è uno strumento che funziona, pensato per un target specifico, con vantaggi reali e limiti altrettanto evidenti
PNY RTX 5080 Slim OC, sembra una Founders Edition ma non lo è
PNY RTX 5080 Slim OC, sembra una Founders Edition ma non lo è
La PNY GeForce RTX 5080 Slim OC si distingue nel panorama delle GPU di fascia alta per il design compatto a due slot, ispirato alla NVIDIA GeForce RTX 5080 Founders Edition. In questo test analizziamo comportamento termico e prestazioni in gioco, valutando se il formato ridotto comprometta o meno l'esperienza complessiva rispetto alle soluzioni più ingombranti presenti sul mercato.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 15-12-2017, 15:22   #1
pepperamy
Junior Member
 
Iscritto dal: Jun 2008
Messaggi: 5
[C] Lista di Lista

Salve a tutti ragazzi, ho iniziato da qualche mese a studiare il linguaggio C ed è anche il mio primo linguaggio di programmazione. Ho qualche problema con le liste di liste. Sto cercando di fare un programma (in questo momento fa tutto l'inserimento in lista e in sottolista automaticamente con dei cicli for) che mi permette di inserire degli elementi in una lista e in una sottolista di un elemento scelto.

Il codice che ho scritto è il seguente e quello che dovrebbe fare è: inserire gli interi da 1 a 9 in una lista principale con inserimento in testa, e questo lo fa, poi dovrebbe inserire i caratteri da "a" a "k" nella sottolista dell'intero 5, e anche questo sembra che lo faccia, e lo fa attraverso la funzione trova che mi cerca l'elemento 5 e mi restituisce il puntatore al nodo. Poi attraverso la funzione inserimento_sottolista alla quale passo il puntatore restituito dalla funzione trova e i caratteri che voglio inserire il secondo ciclo for mi fa l'inserimento nella sottolista . Ho messo dei printf qua a la per cercare di capire dove fosse il problema, ma non sono ancora riuscito a trovarlo.
Il problema che mi viene dato è che quando faccio la stampa degli elementi, la stampa della sottolista è sbagliata, perchè in corrispondenza dell'elemento 5 ci dovrebbe essere la sottolista con i caratteri invece c'è NULL.


ecco il codice
Codice:
#include <stdio.h>
#include <stdlib.h>

/***** S T R U T T U R E ******/
struct sotto_nodo
{
    char carattere;
    struct sotto_nodo *nextPtr1;
};

struct nodo
{
    int intero;
    struct nodo *nextPtr;               //puntatore al nodo successivo
    struct sotto_nodo *sottonodoPtr;   //puntatore al tipo struct sotto_nodo di nome sottonodoPtr

};

/****** T Y P E D E F ******/

typedef struct sotto_nodo SottoNodo;
typedef struct nodo Nodo;

typedef SottoNodo *SottoNodoPtr;
typedef Nodo *NodoPtr;

/****** P R O T O T I P I    D I     F U N Z IO N E ******/

void menu();
NodoPtr crea_lista(int elemento1);
void inserisci_lista (NodoPtr *head, int elementi);
SottoNodoPtr trova (NodoPtr head, int elemento);
void inserisci_sottolista (SottoNodoPtr *head1, char caratteri);
void stampa(NodoPtr testalistaPtr);


/****** M A I N ******/

int main (void)
{
    NodoPtr testaPtr = NULL;
    SottoNodoPtr testaPtr1 = NULL;


    menu();
    int scelta;
    do {

        printf("Fai una scelta: ");
        fflush(stdin);
        scanf("%d", &scelta);
        switch (scelta)
        {
            case 1:
                {
                int i;
                char j;
                int elem1 = 0 ;

                testaPtr = crea_lista(elem1);
                for (i = 1; i < 10;  i++)
                {
                    inserisci_lista(&testaPtr, i);
                    printf("inserito %d in lista principale\n", testaPtr->intero);
                }

                testaPtr1 = trova(testaPtr, 5);
                printf("\ntrovato l'elemento cercato\n\n");

                for (j = 'a' ; j < 'l'; j++)
                {

                    inserisci_sottolista(&testaPtr1, j);
                    printf("inserito %c in lista secondaria\n", testaPtr1->carattere);
                }
            }
            break;

            case 2:
                stampa(testaPtr);

            break;
        }
    }
    while (scelta != 3);
}


/****** I M P L E M E N T A Z I O N E   F U N Z I O N I ******/


void menu()
{
    printf("1. Inserire elementi nella lista principale e nella sottolista\n");
    printf("2. Stampare elementi\n");
    printf("3. Termina programma\n");
};

NodoPtr crea_lista (int elemento1)
{
NodoPtr headPtr = malloc(sizeof(Nodo));

headPtr->intero = elemento1;
headPtr->nextPtr = NULL;
headPtr->sottonodoPtr = NULL;

return headPtr;
};

void inserisci_lista (NodoPtr *head, int elementi)
{
    NodoPtr newPtr = malloc(sizeof(Nodo));
    newPtr->intero=elementi;
    newPtr->nextPtr = *head;
    *head = newPtr;
};

SottoNodoPtr trova (NodoPtr head, int elemento)
{
    while (head->intero != elemento && head != NULL)
    {
        head = head->nextPtr;
    }
    if (head->intero == elemento)
        return head->sottonodoPtr;
    else
        return NULL;
};

void inserisci_sottolista (SottoNodoPtr *head1, char caratteri)
{
   SottoNodoPtr newPtr = malloc(sizeof(SottoNodo));
   newPtr->carattere = caratteri;
   newPtr->nextPtr1 = *head1;
   *head1 = newPtr;
};

void stampa(NodoPtr testalista)
{
    printf("head -> ");
    NodoPtr copia_testalista = testalista;
    while (testalista != NULL)
    {
        printf("%d -> ", testalista->intero);
        testalista = testalista->nextPtr;
    }
    printf("NULL\n");

    SottoNodoPtr SubPtr = copia_testalista->sottonodoPtr;

    while (copia_testalista != NULL)
    {
    printf("headsub -> (%d) -> ", copia_testalista->intero);

    while (SubPtr != NULL)
    {
        printf("%c -> ", SubPtr->carattere);
        SubPtr = SubPtr->nextPtr1;
    }
    printf("NULL\n");
    copia_testalista = copia_testalista->nextPtr;
    }
};
pepperamy è offline   Rispondi citando il messaggio o parte di esso
Old 18-12-2017, 10:29   #2
pepperamy
Junior Member
 
Iscritto dal: Jun 2008
Messaggi: 5
up
pepperamy è offline   Rispondi citando il messaggio o parte di esso
Old 18-12-2017, 16:16   #3
pabloski
Senior Member
 
Iscritto dal: Jan 2008
Messaggi: 8406
Ci sono un paio di errorucci ma importanti.

Innanzitutto hai fatto bene in crea_lista ha porre headPtr->sottonodoPtr = NULL. Però perchè non hai fatto lo stesso in inserisci_lista, cioè newPtr->sottonodoPtr = NULL.

Il puntatore alla sottolista per tutti gli elementi della lista principale diversi dal primo è indefinito, cioè contiene valori a casaccio. Questo ti crea problemi in inserisci_sottolista quando fai newPtr->nextPtr1 = *head1, in quanto il primo elemento punterà al valore a casaccio. E ovviamente andrà in segmentation fault il programma. Il perchè adesso non vada in fault è dovuto al fatto che tutti gli elementi della lista principale hanno fortuitamente sottonodoPtr uguale a 0, cioè NULL.

Inoltre trova non ha senso così com'è fatta. In condizioni normali ritornerebbe sempre NULL, altrimenti il valore a casaccio contenuto in sottonodoPtr.

Ma il problema serio è il fatto che in inserisci_sottolista non fai nulla per aggiornare il valore di sottonodoPtr dell'elemento della lista principale relativo alla sottolista.

Cioè il sottonodoPtr dell'elemento 5 conterrà sempre NULL ( il compilatore sta facendo magheggi e settando implicitamente a NULL, altri compilatori ti lasciano il valore che trovano in memoria e le cose possono sfuggire di mano ).

Per cui quando inserisci un nuovo valore sotto l'elemento 5, il relativo sottonodoPtr dovrà puntare al sottonodo che rappresenta questo nuovo valore.

Pertanto trova deve restituirti il puntatore all'elemento 5 della lista, che poi dovrai passare a inserisci_sottolista che lo userà per individuare il sottonodoPtr da aggiornare.

Infine c'è un errore pure in stampa, dove assegni a SubPtr il valore della testa della sottolista dell'elemento di testa della lista. Poi però scorri tutti gli elementi della vista, ma non pone SubPtr al valore della testa della sottolista per OGNUNO degli elementi della vista.

In codice sarebbe

Codice:
void inserisci_sottolista (SottoNodoPtr *head1, char caratteri, NodoPtr lPtr)
{
   SottoNodoPtr newPtr = malloc(sizeof(SottoNodo));
   newPtr->carattere = caratteri;
   newPtr->nextPtr1 = *head1;
   *head1 = newPtr;
   lPtr->sottonodoPtr = newPtr; // aggiornamento sottonodoPtr per l'elemento 5
};
nel main

Codice:
testaPtr2 = trova(testaPtr, 5); // testaPtr2 è di tipo NodoPtr
....
inserisci_sottolista(&testaPtr1, j, testaPtr2);
Codice:
void inserisci_lista (NodoPtr *head, int elementi)
{
    NodoPtr newPtr = malloc(sizeof(Nodo));
    newPtr->intero=elementi;
    newPtr->nextPtr = *head;
    newPtr->sottonodoPtr = NULL; // non puoi lasciarlo al caso o alla bontà del compilatore
    *head = newPtr;
};
Codice:
NodoPtr trova (NodoPtr head, int elemento)
{
    NodoPtr p = head;
    while (p->intero != elemento && p != NULL)
    {
        p = p->nextPtr;
    }
    if (p->intero == elemento)
        return p; // ritorna il puntatore all'elemento della lista non al relativo sottonodoPtr che è ovviamente NULL a questo punto
    else
        return NULL;
};
Codice:
SottoNodoPtr SubPtr;

    while (copia_testalista != NULL)
    {
    printf("headsub -> (%d) -> ", copia_testalista->intero);

    SubPtr = copia_testalista->sottonodoPtr; // questo qui deve puntatore alla sottolista dello specifico elemento della lista, invece prima puntava sempre a quella della testa della lista
pabloski è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Marathon: arriva il Fortnite hardcore Marathon: arriva il Fortnite hardcore
HP Imagine 2026: abbiamo visto HP IQ all’opera, ecco cosa può (e non può) fare HP Imagine 2026: abbiamo visto HP IQ all’opera, ...
PNY RTX 5080 Slim OC, sembra una Founders Edition ma non lo è PNY RTX 5080 Slim OC, sembra una Founders Editio...
Wi-Fi 7 con il design di una vetta innevata: ecco il nuovo sistema mesh di Huawei Wi-Fi 7 con il design di una vetta innevata: ecc...
Core Ultra 7 270K Plus e Core Ultra 7 250K Plus: Intel cerca il riscatto ma ci riesce in parte Core Ultra 7 270K Plus e Core Ultra 7 250K Plus:...
GTA 6: i costi di sviluppo sono impressi...
SSD Kioxia EXCERIA PRO G2 4TB, prestazio...
TSMC ha raggiunto il limite: starebbe ri...
Tutte le offerte Amazon più pesan...
Microsoft unisce GPT e Claude in Copilot...
MacBook Neo è una trappola second...
Meta testa Instagram Plus: abbonamento a...
Recensione ASUSTOR LockerStor 2 Gen2+: l...
SpaceX conferma anomalia per il satellit...
Apple rilascia le prime beta 26.5 di iOS...
Warhorse Studios sostituisce i traduttor...
Ecco perché in tanti stanno comprando Ap...
Intesa Sanpaolo, multa da 31,8 milioni d...
Stellantis, rinnovo di 5 anni con Palant...
Google Pixel 11 si mostra nei render CAD...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 12:44.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v