Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Samsung Galaxy Z Fold7: un grande salto generazionale
Recensione Samsung Galaxy Z Fold7: un grande salto generazionale
Abbiamo provato per molti giorni il nuovo Z Fold7 di Samsung, un prodotto davvero interessante e costruito nei minimi dettagli. Rispetto al predecessore, cambiano parecchie cose, facendo un salto generazionale importante. Sarà lui il pieghevole di riferimento? Ecco la nostra recensione completa.
The Edge of Fate è Destiny 2.5. E questo è un problema
The Edge of Fate è Destiny 2.5. E questo è un problema
Bungie riesce a costruire una delle campagne più coinvolgenti della serie e introduce cambiamenti profondi al sistema di gioco, tra nuove stat e tier dell’equipaggiamento. Ma con risorse limitate e scelte discutibili, il vero salto evolutivo resta solo un’occasione mancata
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello
AMD ha aggiornato l'offerta di CPU HEDT con i Ryzen Threadripper 9000 basati su architettura Zen 5. In questo articolo vediamo come si comportano i modelli con 64 e 32 core 9980X e 9970X. Venduti allo stesso prezzo dei predecessori e compatibili con il medesimo socket, le nuove proposte si candidano a essere ottimi compagni per chi è in cerca di potenza dei calcolo e tante linee PCI Express per workstation grafiche e destinate all'AI.
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


Recensione Samsung Galaxy Z Fold7: un grande salto generazionale Recensione Samsung Galaxy Z Fold7: un grande sal...
The Edge of Fate è Destiny 2.5. E questo è un problema The Edge of Fate è Destiny 2.5. E questo ...
Ryzen Threadripper 9980X e 9970X alla prova: AMD Zen 5 al massimo livello Ryzen Threadripper 9980X e 9970X alla prova: AMD...
Acer TravelMate P4 14: tanta sostanza per l'utente aziendale Acer TravelMate P4 14: tanta sostanza per l'uten...
Hisense M2 Pro: dove lo metti, sta. Mini proiettore laser 4K per il cinema ovunque Hisense M2 Pro: dove lo metti, sta. Mini proiett...
Sharkoon punta sui case a basso costo, m...
La tua rete Wi-Fi fa pena? Questi FRITZ!...
Amazon, un weekend di fuoco per gli scon...
Ancora 3 smartwatch Amazfit in forte sco...
Sharkoon A60 RGB: dissipatore ad aria du...
HONOR 400 Pro a prezzo bomba su Amazon: ...
Offerte da non perdere: robot aspirapolv...
Apple Watch e Galaxy Watch ai minimi sto...
Il rover NASA Perseverance ha ''raccolto...
NASA e ISRO hanno lanciato il satellite ...
Switch 2 ha venduto 5,82 milioni di cons...
Assassin's Creed Black Flag Remake: le m...
Cosa ci fa una Xiaomi SU7 Ultra alle por...
Promo AliExpress Choice Day: prezzi stra...
Nostalgico, ma moderno: il nuovo THEC64 ...
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: 14:25.


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