Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Nioh 3: souls-like punitivo e Action RPG
Nioh 3: souls-like punitivo e Action RPG
Nioh 3 aggiorna la formula Team NINJA con aree esplorabili più grandi, due stili di combattimento intercambiabili al volo (Samurai e Ninja) e un sistema di progressione pieno di attività, basi nemiche e sfide legate al Crogiolo. La recensione entra nel dettaglio su combattimento, build, progressione e requisiti PC
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
La facilità di installazione e la completa automazione di tutte le fasi di utilizzo, rendono questo prodotto l'ideale per molti clienti. Ecco com'è andata la nostra prova in anteprima
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto
be quiet! debutta nel settore mouse da gaming con Dark Perk Ergo e Dark Perk Sym: due modelli gemelli per specifiche, con polling rate di 8.000 Hz anche in wireless, sensore PixArt PAW3950 da 32.000 DPI e autonomia dichiarata fino a 110 ore. Nel test, a 8.000 Hz si arriva a circa 30 ore reali, con ricarica completa in un'ora e mezza
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 15-12-2017, 16: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, 11: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, 17: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


Nioh 3: souls-like punitivo e Action RPG Nioh 3: souls-like punitivo e Action RPG
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti Test in super anteprima di Navimow i220 LiDAR: i...
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto Dark Perk Ergo e Sym provati tra wireless, softw...
DJI RS 5: stabilizzazione e tracking intelligente per ogni videomaker DJI RS 5: stabilizzazione e tracking intelligent...
AMD Ryzen 7 9850X3D: Zen 5, 3D V-Cache e frequenze al top per il gaming AMD Ryzen 7 9850X3D: Zen 5, 3D V-Cache e frequen...
L'UE dà ragione ad Apple: Maps e ...
Droni accecati e comunicazioni isolate: ...
Accesso alla memoria su Windows 11 solo ...
Regali di San Valentino: 15 idee tech sf...
Stellantis a picco in Borsa: 22 miliardi...
Baldur's Gate 3 diventa una serie TV: pr...
Intel riapre la sfida con Steam Deck: Pa...
Pompa di calore vs Caldaia, si risparmia...
AirDrop su Android? Quick Share sta per ...
iOS 27: Apple ridimensiona il progetto A...
Il camion elettrico eActros 600 scende i...
eFootball Kick-Off! è ufficiale: ...
Fallout 4: Anniversary Edition arriva su...
The Elder Scrolls IV: Oblivion Remastere...
18 articoli su Amazon super scontati da ...
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:05.


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