PDA

View Full Version : [C] Come passare array a funzioni


elect
12-07-2008, 11:16
Nell'header ho

typedef struct mossa_t
{
int numero_mossa;
char coordinataBianco[COORD + 1];
char coordinataNero[COORD + 1];
}mossa;

typedef struct partita_t
{
char *luogo;
long int fixed_data;
char *giocatoreBianco;
char *giocatoreNero;
int numeroMosse;
struct mossa_t *P_mosse;
}partita;

typedef partita *list;
typedef mossa *mox;


Nel mio fun.c invece

for(j = 0; j < numeroPartite; j++)
for(k = 0; k <= (P_testa[j].numeroMosse - numeroMosse); k++)
if(!strcmp(P_testa[j].P_mosse[k].coordinataBianco, P_sequenza[0].coordinataBianco ) )
if(!strcmp(P_testa[j].P_mosse[k].coordinataNero, P_sequenza[0].coordinataNero ) )
analizza_e_stampa(P_testa[j].P_mosse[k], P_sequenza[1], numeroMosse);

Vorrei passare alla funzione

int analizza_e_stampa(struct mossa_t P_testa[j].P_mosse[k], mox P_sequenza[1], int numeroMosse)

Ovviamente ho una serie di errori, qual e' il modo corretto per passare Array?

Nell'analizza_e_stampa ho bisogno di continuare a scalare il vettore di struct P_mosse e P_sequena...

Come si fa? :p

DanieleC88
12-07-2008, 16:21
Non puoi sapere al momento della compilazione quale sarà la dimensione dell'array da ricevere nella funzione, quindi ti toccherà usare un puntatore.
int analyzeAndPrint(struct mossa_t *vec, /* ... */)
{
/* ... */
}

elect
12-07-2008, 18:25
Infatti, ho optato per passare anche gli indici separatamente

elect
12-07-2008, 20:49
Ora pero' se provo a fare una stupidissima bubblesort mi da' errore


list bubblesort(list v, int N)
{
int i, j;
list tmp;

for(i = 1; i < N; i++)
{
for(j = N - 1; j >= 1; j--)
if(v[j - 1].fixed_data > v[j].fixed_data)
{
tmp = v[j - 1];
v[j - 1] = v[j];
v[j] = tmp;
}
}
return v;
}

dove faccio le assegnazioni con tmp mi da

error: incompatible types in assignment

Perche'? :confused:

E soprattutto come faccio a risolverlo? :p

Ps: la chiamo con

P_testa = bubblesort(P_testa, numeroPartite);

Albi89
12-07-2008, 20:59
[...]

temp deve essere di tipo partita, non partita* (ossia list)

DanieleC88
13-07-2008, 00:15
temp deve essere di tipo partita, non partita* (ossia list)
No, temp è correttemente un puntatore che puoi assegnare, altrimenti una struttura non la puoi assegnare direttamente con un uguale, servirebbe una memcpy(). :)

Il fatto è che la funzione dovrebbe ricevere un puntatore a list, altrimenti dereferenziando un singolo elemento (con v[j-1] e simili) perdi il puntatore e torni ad ottenere una struttura.

Io solitamente faccio così le mie dichiarazioni:
struct __node
{
int data;
struct __node *next;
};

typedef struct __node *node;
typedef node *list;
in modo da non perdermi i puntatori, che sono comodi per questo tipo di operazioni.

ciao ;)

elect
13-07-2008, 09:13
In teoria dovrei cercarlo di farlo con la bubblesort restando il più fedele possibile a come l'ho impostato, è possibile?

DanieleC88
13-07-2008, 14:33
Intendi con "un puntatore in meno"? Certo che puoi, ma o devi fare una copia membro a membro, o usi memcpy(&destinazione, &sorgente, sizeof(partita)).

elect
13-07-2008, 18:47
Voglio dire, ho un vettore statico di struct partita, e vorrei ordinarlo secondo l'algoritmo della bubblesort...come devo modificare di conseguenza la mia funzione?

DanieleC88
13-07-2008, 18:56
E te l'ho detto un attimo fa... :stordita:
Allora, tu non puoi usare un puntatore, che è "assegnabile" perché è solo un numero, e non un tipo di dato "strutturato". Le soluzioni sono:
o ti fai una funzione apposita che copi dei valori da una struttura ad un'altra, e in tale modo puoi fare lo scambio usi memcpy() come ti ho scritto su, ti eviti di fare un'altra funzione appositamente, e fai lo scambio con quello invece che con l'assegnazione

ciao ;)

elect
13-07-2008, 19:10
Hai ragione scusami...:doh:

ora mi studio un pò la memcopy :p

elect
15-07-2008, 13:00
Continua a darmi "incompatible types" anche con la memcpy :confused:

memcpy(tmp, v[j - 1], sizeof(partita) );
memcpy(v[j - 1], v[j], sizeof(partita) );
memcpy(v[j], tmp, sizeof(partita) );

Edit: dimenticavo le &... :P


Edit: segmentation fault

elect
15-07-2008, 13:08
memcpy(&tmp, &v[j - 1], sizeof(partita) );
memcpy(&v[j - 1], &v[j], sizeof(partita) );
memcpy(&v[j], &tmp, sizeof(partita) );


Mi va in segmentation fault sulla memcpy di mezzo, come mai?

Edit: noto che appena faccio la prima memcopy mi sputtana gli indici i e j, assumono dei valori enormi..

DanieleC88
15-07-2008, 16:01
La variabili locali i e j ti si sputtanano perché tmp non ha bisogno di essere passato come &tmp a memcpy(). ;)

memcpy(tmp, &v[j - 1], sizeof(partita));
memcpy(&v[j - 1], &v[j], sizeof(partita));
memcpy(&v[j], tmp, sizeof(partita));

Prova un po'. :)

elect
15-07-2008, 22:34
E' davvero strano, cosi' come hai detto tu funza, ho provato con un po' di watch ed e' tutto ok

arrivo pero' alla printf per vedere se ordina correttamente...segmentation fault

for(i = 0; i < numeroPartite; i++)
{
printf("\n\nLuogo: %s\tData: %ld\tBianco: %s\nNero: %s\tNumero Mosse: %i\n", P_testa[i].luogo,
P_testa[i].fixed_data, P_testa[i].giocatoreBianco, P_testa[i].giocatoreNero,
P_testa[i].numeroMosse);
for(j = 0; j < P_testa[i].numeroMosse; j++)
printf("\nMossa Bianco: %s\tMossa Nero: %s\t\n", P_testa[i].P_mosse[j].coordinataBianco,
P_testa[i].P_mosse[j].coordinataNero);
}


allora vado a vedere elemento per elemento che stampa e sono tutti a posto! :confused:

elect
15-07-2008, 22:37
Anche se tolgo quella parte della stampa continua a farmi Seg Fault

qui il mio fun.c completo

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "fun.h"

#define MAX 10
#define MAX_S 350

static int numeroPartite;

list leggi_e_carica(void)
{
char filename[MAX + 1], buffer[MAX_S], *luogo, s[] = "# .\n";
char *data_gg, *data_mm, *data_aaaa, *giocatoreBianco, *giocatoreNero, *numeroMosse;
char *coordinataBianco, *coordinataNero;
FILE *stream;
int i = 0, j;
list P_testa;

printf("\nInserisci il nome del file contenente l'archivio delle partite: ");
scanf("%s", filename);

if( (stream = fopen(filename, "r") ) == NULL)
{
printf("\Errore nell'apertura del file %s !", filename);
getchar();
return NULL;
}
fgets(buffer, MAX_S, stream); //niente MAX_S - 1
numeroPartite = atoi(buffer);
P_testa = calloc(numeroPartite, sizeof(partita) );

while(fgets(buffer, MAX_S, stream) )
{
if(buffer[0] == '#')
{
luogo = strtok(buffer, s);
P_testa[i].luogo = calloc(strlen(luogo), sizeof(char) );
strcpy(P_testa[i].luogo, luogo);

data_gg = strtok(NULL, s);
data_mm = strtok(NULL, s);
data_aaaa = strtok(NULL,s);
P_testa[i].fixed_data = aggiustaData(data_gg, data_mm, data_aaaa);

giocatoreBianco = strtok(NULL, s);
P_testa[i].giocatoreBianco = calloc(strlen(giocatoreBianco), sizeof(char) );
strcpy(P_testa[i].giocatoreBianco, giocatoreBianco);

giocatoreNero = strtok(NULL, s);
P_testa[i].giocatoreNero = calloc(strlen(giocatoreNero), sizeof(char) );
strcpy(P_testa[i].giocatoreNero, giocatoreNero);

numeroMosse = strtok(NULL, s);
P_testa[i].numeroMosse = atoi(numeroMosse);

}
if(P_testa[i].numeroMosse != 0)
{
P_testa[i].P_mosse = calloc(P_testa[i].numeroMosse, sizeof(mossa) );
j = 0;

while(j < P_testa[i].numeroMosse)
{
fgets(buffer, MAX_S, stream);

coordinataBianco = strtok(buffer, s);
strcpy(P_testa[i].P_mosse[j].coordinataBianco, coordinataBianco);

coordinataNero = strtok(NULL, s);
strcpy(P_testa[i].P_mosse[j].coordinataNero, coordinataNero);

j++;
}
}
i++;
}
P_testa = bubblesort(P_testa, numeroPartite);

for(i = 0; i < numeroPartite; i++)
{
printf("\n\nLuogo: %s\tData: %ld\tBianco: %s\nNero: %s\tNumero Mosse: %i\n", P_testa[i].luogo,
P_testa[i].fixed_data, P_testa[i].giocatoreBianco, P_testa[i].giocatoreNero,
P_testa[i].numeroMosse);
for(j = 0; j < P_testa[i].numeroMosse; j++)
printf("\nMossa Bianco: %s\tMossa Nero: %s\t\n", P_testa[i].P_mosse[j].coordinataBianco,
P_testa[i].P_mosse[j].coordinataNero);
}

return P_testa;
}

int aggiustaData(char *data_gg, char *data_mm, char *data_aaaa)
{
int dataAssoluta;

dataAssoluta = (atoi(data_aaaa) * 100);
dataAssoluta += atoi(data_mm);
dataAssoluta *= 100;
dataAssoluta += atoi(data_gg);

return dataAssoluta;
}

list bubblesort(list v, int N)
{
int i, j;
list tmp;

for(i = 1; i < N; i++)
{
for(j = N - 1; j >= 1; j--)
if(v[j - 1].fixed_data > v[j].fixed_data)
{
/*memcpy(tmp, &v[j - 1], sizeof(partita) );
memcpy(&v[j - 1], &v[j], sizeof(partita) );
memcpy(&v[j], tmp, sizeof(partita) );*/

}
}
return v;
}


int leggi_e_ricerca(char *filename, list P_testa)
{
char coordinataBianco[MAX + 1], coordinataNero[MAX + 1];
FILE *stream;
int numeroMosse, i, j;
mox P_sequenza;

if( (stream = fopen(filename, "r") ) == NULL)
printf("\nErrore nell'apertura del file %s", filename);
else
{
fscanf(stream, "%i", &numeroMosse);
P_sequenza = calloc(numeroMosse, sizeof(mossa) );

for(i = 0; i < numeroMosse; i++)
{
fscanf(stream, "%s%s", coordinataBianco, coordinataNero);
strcpy(P_sequenza[i].coordinataBianco, coordinataBianco);
strcpy(P_sequenza[i].coordinataNero, coordinataNero);
}
for(i = 0; i < numeroPartite; i++)
for(j = 0; j <= (P_testa[i].numeroMosse - numeroMosse); j++)
if(strcmp(P_testa[i].P_mosse[j].coordinataBianco, P_sequenza[0].coordinataBianco ) == 0)
if(strcmp(P_testa[i].P_mosse[j].coordinataNero, P_sequenza[0].coordinataNero ) == 0)
analizza_e_stampa(P_testa, i, j, P_sequenza, numeroMosse);
}
return 0;
}

int analizza_e_stampa(list P_testa, int i, int j,mox P_sequenza, int numeroMosse)
{
int x = 1;
j++;

while(x < numeroMosse &&
strcmp(P_testa[i].P_mosse[j].coordinataBianco, P_sequenza[x].coordinataBianco) == 0 &&
strcmp(P_testa[i].P_mosse[j].coordinataNero, P_sequenza[x].coordinataNero) == 0)
{
j++;
x++;
}
if(x == numeroMosse)
{
j -= numeroMosse;
printf("\nLuogo: %s\tData: ", P_testa[i].luogo);
stampaData(P_testa[i].fixed_data);
printf("\nGiocatore Bianco: %s", P_testa[i].giocatoreBianco);
printf("\tGiocatore Nero: %s", P_testa[i].giocatoreNero);
printf("\nLa sequenza desiderata e' stata riconosciuta dal numero della");
printf(" coppia di mosse %i\n", j + 1);
}

return 0;
}

int stampaData(int dataAssoluta)
{
int anno, data, mesi, giorni;

anno = dataAssoluta / 10000;
printf("%i.", anno);

data = dataAssoluta - anno * 10000;

mesi = data / 100;
printf("%i.", mesi);

giorni = data - mesi * 100;
printf("%i", giorni);

return 0;
}

DanieleC88
16-07-2008, 00:20
E' davvero strano, cosi' come hai detto tu funza, ho provato con un po' di watch ed e' tutto ok
Non è strano, è normalissimo, andava fatto in quel modo (prima invece avevi, diciamo, "un puntatore di differenza", e scrivevi roba sullo stack modificando le variabili locali...).
printf("\n\nLuogo: %s\tData: %ld\tBianco: %s\nNero: %s\tNumero Mosse: %i\n"
%i??

DanieleC88
16-07-2008, 00:25
qui il mio fun.c completo

[...]
:eekk:

Ma scordati che io faccia il debugging di tutto quel file... almeno, non oggi, non è certo l'ora di fare questa roba... :p

ciao ;) :D

elect
16-07-2008, 07:03
Non è strano, è normalissimo, andava fatto in quel modo (prima invece avevi, diciamo, "un puntatore di differenza", e scrivevi roba sullo stack modificando le variabili locali...).

%i??

Strano perche' va in Seg Fault pur avendo controllato ogni cosa coi watches

%i o %d e' uguale per gli interi

:eekk:

Ma scordati che io faccia il debugging di tutto quel file... almeno, non oggi, non è certo l'ora di fare questa roba... :p

ciao ;) :D

lol :P io speravo nella vostra incredibile capacita' di debuggare a vista in 2 minuti :D

DanieleC88
16-07-2008, 08:20
Strano perche' va in Seg Fault pur avendo controllato ogni cosa coi watches
E ci dev'essere qualcosa che sfugge... Hai fatto il debugging con GDB? Un backtrace potrebbe chiarire le idee.
%i o %d e' uguale per gli interi
Appunto, perché ne usi uno ora e subito dopo usi l'altro? Fai una scelta e mantienila uniformemente nel codice! :p
lol :P io speravo nella vostra incredibile capacita' di debuggare a vista in 2 minuti :D
Vabbe', non se devo andare analizzare un intero file e sto andando a letto, visto che stamattina ho da fare... :D

elect
16-07-2008, 11:33
Daniele, ti ringrazio di tutto l'aiuto che mi hai dato :)
Oramai e' andata, non ho piu' bisogno di andare oltre :D

E ci dev'essere qualcosa che sfugge... Hai fatto il debugging con GDB? Un backtrace potrebbe chiarire le idee.

un giorno o l'altro devo informarmi su che cos'e' sto GDB :D
Mi e' uscito fuori in qualche occasione di segmentation fault


Appunto, perché ne usi uno ora e subito dopo usi l'altro? Fai una scelta e mantienila uniformemente nel codice! :p

Hai ragione...quale sarebbe quello piu' corretto da un punto di vista logico?


Vabbe', non se devo andare analizzare un intero file e sto andando a letto, visto che stamattina ho da fare... :D

lol, nn ti preoccupare piu', grazie ancora

DanieleC88
16-07-2008, 11:51
Daniele, ti ringrazio di tutto l'aiuto che mi hai dato :)
Oramai e' andata, non ho piu' bisogno di andare oltre :D
Ovvero? Funziona o no? :mbe:
un giorno o l'altro devo informarmi su che cos'e' sto GDB :D
Mi e' uscito fuori in qualche occasione di segmentation fault
È un debugger. :D
Hai ragione...quale sarebbe quello piu' corretto da un punto di vista logico?
È indifferente, io personalmente uso e preferisco %d, ma basta che fai una scelta consistente in tutto il progetto e va benissimo come ti pare. :D
lol, nn ti preoccupare piu', grazie ancora
Vabbe' ma io lo faccio così per curiosità mia, quando avrò tempo se mi va provo a dargli uno sguardo di preciso.

ciao ;)

elect
16-07-2008, 12:02
Ovvero? Funziona o no? :mbe:

Vabbe' ma io lo faccio così per curiosità mia, quando avrò tempo se mi va provo a dargli uno sguardo di preciso.

ciao ;)

No, va in segmentation se provo ad ordinarlo, cmq non e' piu' importante perche' ormai la relazione e' andata

grazie ancora :)