|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 68
|
[C] Strutture,liste e puntatori..
Salve a tutti... ho questo codice fornito dal mio professore di fondamenti..
Codice:
typedef struct{
char titolo[30];
int video;
int audio;
char trama[255];
} film ;
struct StructLista {
film info;
struct StructLista *next;
} ;
typedef struct StructLista NodoLista;
typedef NodoLista* Lista;
// Inizializza e azzera la lista passata come parametro
void InizLista(Lista *lis){
*lis==NULL;
}
// Inserisce l'elemeno passato come parametro, in testa
void InserisciInTesta(Lista *lis, film elemento){
Lista paux;
paux=malloc(sizeof(NodoLista));
if(paux==NULL) exit(1);
paux->info=elemento;
paux->next=*lis;
*lis=paux;
}
// Restituisce la testa della lista
void TestaLista(Lista lis, film *elem){
if(lis==NULL)exit(1);
*elem=lis->info;
}
definisco un nuovo tipo -> typedef NodoLista* Lista; <- quindi Lista mi punta all'indirizzo del nodo della lista... Però nella prima funzione (ad esempio) passo come paramentro -> Lista *lis <-.. questo vuol dire che già Lista è un puntatore che associo ad un'altro puntatore (*lis), quindi il parametro non sarà un puntatore ma il suo contenuto interno, infatti poi uso tale puntatore con l'operatore * per settare il suo indirizzo in null... mi chiedo se non è possibile fare lo stesso nel seguente modo void InizLista(Lista lis){ lis==NULL; } in tale modo lis dovrebbe essere già un puntatore.. potreste spiegarmi bene questa situazione?? |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Dec 2006
Messaggi: 198
|
Innanzi tutto, == è un operatore di confronto, non di assegnamento. Probabilmente quello che vuoi fare tu è: lis = NULL;
Per quanto riguarda la tua domanda: si, non solo si può fare, ma è anche la via migliore (o meno deviata |
|
|
|
|
|
#3 | |
|
Member
Iscritto dal: Aug 2007
Messaggi: 68
|
Quote:
Quello che volevo chiedere è : il suo modo di passare il parametro il mio sono uguali giusto? un puntatore di puntatore annulla il puntatore stesso, quindi tantovale passare solo un puntatore a nodo ed usarlo senza derefenziamento! Ultima modifica di Honik : 01-06-2009 alle 21:54. |
|
|
|
|
|
|
#4 |
|
Registered User
Iscritto dal: May 2009
Messaggi: 300
|
A mio modo di vedere quel typedef copre il fatto che Lista sia in realtà un puntatore. Se tu usassi come argomento formale della funzione il tipo Lista qualcuno a prima vista (senza aver visto il typedef) potrebbe supporre che il passaggio stia avvenendo per valore. Questo lo indurrebbe a credere che l'assegnamento lis = NULL non abbia effetto sull'argomento attuale. Se tu indichi come argomento formale il tipo Lista* allora chi legge sa che maneggiando il contenuto puntato ottiene effetto anche all'esterno della funzione. Io lo interpreterei come un dettaglio di maggiore leggibilità. Anche io l'avrei fatto così, ha una sua logica: se stai passando per puntatore o per riferimento è perchè vuoi che all'esterno vi siano effetti, se passi per valore no. Se nascondi tutto col typedef non stai facendo una bella cosa! Chi deve leggere il tuo codice, vuole leggerlo non decifrarlo!
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 68
|
Non avevo considerato questo aspetto!! Sicuramente, visto che le funzioni dovrebbe essere scatole chiuse, io (client) non mi devo preoccupare tanto del loro contenuto.. il concetto dovrebbe essere questo
|
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Aug 2007
Messaggi: 68
|
Ho trovato non poche difficoltà a capire quel codice.. ho provato a "revisionarlo" a modo mio...
Ecco i due file: liste.c Codice:
typedef struct{
char titolo[30];
int video;
int audio;
char trama[255];
} film ;
struct StructLista {
film info;
struct StructLista *next;
} ;
typedef struct StructLista NodoLista;
// Inizializza e azzera la lista passata come parametro
void InizLista(NodoLista *lis){
lis=NULL;
if(lis==NULL) printf("\n\nLista inizializzata\n\n");
}
// Inserisce l'elemeno passato come parametro, in testa
void InserisciInTesta(NodoLista *lis, film elemento){
NodoLista *paux;
paux=malloc(sizeof(NodoLista));
if(paux==NULL) exit(1);
paux->info=elemento;
paux->next=lis;
lis=paux;
}
// Restituisce la testa della lista
void TestaLista(NodoLista *lis, film *uelem){
if(lis==NULL)printf("errore.. lista vuota!");
*uelem=lis->info;
}
// Visualizza la lista
void VediLista(NodoLista *lis){
while (lis!=NULL){
printf("%s", lis->info.titolo);
}
}
Codice:
#include <stdio.h>
#include <stdlib.h>
#include "liste.c"
#define MENU 200
#define OUT 255
void AcqElemento(film elem){
printf("Titolo film: ");
scanf("%s", elem.titolo);
printf("\nInsersci trama: ");
scanf("%s", elem.trama);
printf("\nQualità video: ");
scanf("%d", &elem.video);
printf("\nQualità audio: ");
scanf("%d", &elem.audio);
}
main(){
NodoLista *plist;
film elem;
film *uelem;
int scelta=MENU;
while (scelta==MENU){
printf("\n\n\t\t################-> Gestione Film <-################");
printf("\n\n 1. Crea la lista");
printf("\n\n 2. Inserisci in testa un'elemento");{}
printf("\n\n 3. Guarda il primo elemento in testa");
printf("\n\n 4. Guarda tutta la lista");
printf("\n\n 0. Esci");
printf("\n\n\n\t\t\t La tua scelta: ");
scanf("%d", &scelta);
switch(scelta){
case 0:
scelta=OUT;
break;
case 1:
InizLista(plist);
scelta=MENU;
break;
case 2:
AcqElemento(elem);
InserisciInTesta(plist, elem);
scelta=MENU;
break;
case 3:
TestaLista(plist, uelem);
scelta=MENU;
break;
case 4:
VediLista(plist);
scelta=MENU;
break;
}
}
}
GRAZIE |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Se te l'ha dato un professore quel codice allora stiamo messi male...
Ci sono alcune perle tipo questa: Codice:
if(paux==NULL) exit(1); ciao
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Quote:
Piuttosto metti l'implementazione del codice in un file C separato che compilerai a parte, e le definizioni dei tipi e delle costanti e i prototipi delle funzioni li metterai in un header da includere in giro dove ti serve. ciao
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
|
|
|
|
|
|
#9 | |
|
Member
Iscritto dal: Aug 2007
Messaggi: 68
|
Quote:
|
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Un po' di considerazioni su liste.c:
Codice:
struct StructLista {
film info;
struct StructLista *next;
} ;
Codice:
typedef struct StructLista NodoLista; Codice:
void InizLista(NodoLista *lis){
lis=NULL;
if(lis==NULL) printf("\n\nLista inizializzata\n\n");
}
Per farlo correttamente avresti dovuto usare: Codice:
(*lis) = NULL; if (*lis == NULL) /* ... */ Codice:
void InserisciInTesta(NodoLista *lis, film elemento){
NodoLista *paux;
paux=malloc(sizeof(NodoLista));
if(paux==NULL) exit(1);
paux->info=elemento;
paux->next=lis;
lis=paux;
}
Infine, riscrivi l'indirizzo di lis senza cambiare i contenuti della memoria a cui punta, come prima dicevo. Codice:
void VediLista(NodoLista *lis){
while (lis!=NULL){
printf("%s", lis->info.titolo);
}
}
ciao
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! Ultima modifica di DanieleC88 : 04-06-2009 alle 01:21. Motivo: Rimossi un po' di avvertimenti inutili, in effetti Mesh89 mi ricorda che l'assegnazione di strutture è standard. |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Quote:
)Non ti offendere eh, cerco di aiutare, non di sfottere. ciao
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
|
|
|
|
|
|
#12 |
|
Member
Iscritto dal: Dec 2006
Messaggi: 198
|
In effetti rileggendo il mio post mi rendo conto di aver scritto una hazzata
Come ha correttamente spiegato Daniele, tu stai si passando un puntatore, ma per valore, non per indirizzo; quindi le modifiche ad essp non si vedranno al di fuori della funzione. Conosci il passaggio di parametri per indirizzo? A mio avviso sarebbe il modo più pulito di fare la cosa. inoltre noto che hai lo stesso problema nell'ultima riga della funzione di inserimento. @Daniele: ho sempre saputo che struct = struct e memcpy fossero equivalenti. Perchè la prima via è sbagliata? |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Quote:
Il fatto è che se ti abitui che puoi "assegnare" una struttura la prendi come fosse un'operazione elementare, quando non è così (è in effetti una copia binaria di un blocco di memoria più o meno grande). Per piccole strutture non è un grosso problema, ma chi ti impedisce questo, per esempio? Codice:
struct s_MyBlob
{
short nIndex;
char szName[512];
char szBlobData[2097152];
};
int main()
{
struct s_MyBlob a, b;
int count;
memset(&a, 0, sizeof(struct s_MyBlob));
memset(&b, 0, sizeof(struct s_MyBlob));
for (count = 0; count < 10000; ++count)
{
++(b.nIndex);
a = b;
}
printf("Terminato.");
return 0;
}
Se invece fosse stato: Codice:
struct s_MyBlob
{
short nIndex;
char szName[512];
char szBlobData[16777216];
};
typedef struct s_MyBlob *p_MyBlob;
int main()
{
p_MyBlob a, b;
int count;
a = (p_MyBlob) malloc(sizeof(struct s_MyBlob));
if (!a)
{
fprintf(stderr, " [**] Allocazione di a fallita.\n");
return 1;
}
memset(a, 0, sizeof(struct s_MyBlob));
b = (p_MyBlob) malloc(sizeof(struct s_MyBlob));
if (!b)
{
fprintf(stderr, " [**] Allocazione di b fallita.\n");
return 1;
}
memset(b, 0, sizeof(struct s_MyBlob));
for (count = 0; count < 10000; ++count)
{
p_MyBlob c;
++(b->nIndex);
c = b;
}
free(a);
free(b);
printf("Terminato.");
return 0;
}
Sì, lo so, sono integralista, non ci posso fare niente. EDIT: tanto per curiosità ho voluto fare un confronto sulla mia macchina (che monta un AMD Athlon™ 64 X2 5200+ con 4GB di RAM, forse non il top ma direi che è abbastanza veloce), il primo programmino con l'assegnazione impiega 16 secondi a terminare, il secondo 100 millisecondi... circa 160 volte più veloce, mica male.
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! Ultima modifica di DanieleC88 : 02-06-2009 alle 22:28. Motivo: Avevo fatto un errore da principante, il Python mi sta deviando... |
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Jun 2002
Città: Dublin
Messaggi: 5989
|
Quote:
![]() In effetti c'ho buttato 32MB di memoria sullo stack, chiaramente il programmino va in segmentation fault.
__________________
C'ho certi cazzi Mafa' che manco tu che sei pratica li hai visti mai! |
|
|
|
|
|
|
#15 | |
|
Registered User
Iscritto dal: May 2009
Messaggi: 300
|
Quote:
|
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 10:02.












)








