interpretare vettore monodimensionale come matrice

Stato
Discussione chiusa ad ulteriori risposte.

Cynical

Utente Silver
10 Febbraio 2011
2
1
0
51
Salve a tutti.

ho un problema...ho bisogno che ad un certo punto dell'esecuzione di interpretare un vettore di lunghezza [n] come una matrice di tipo [n][1]....
Speravo di risolvere la cosa banalmente con un casting del tipo (float (*)[1]), ha compilato ma ha dato errori....consigli? idee? è la prima volta che mi capita una cosa così.

grazie in anticipo.
 
guarda concettualmente è una stupidaggine (anche perchè è gia una matrice n x 1), ma se spieghi meglio a cosa ti serve
 
già teoricamente lo è ma in pratica da warning e non da i risultati che dovrebbe....
Allora io ho un programma riguardo al quale per il momento non scendo in dettaglio, ad un certo punto richiamo una funzione scritta da me che fa il prodotto tra matrici ( riga per colonna ) e questa funzione lavora perfettamente con array bidimensionali dando risultati corretti e nessun warning o error.
Ho bisogno di fare il prodotto matriciale tra una matrice ed un vettore.... quando stampa i risltati dice -nan al posto dei numeri...

il codice delle funzioni è questo...

Codice:
float rigaXcolonna (unsigned int n, unsigned int p, float r[n], float B[n][p], unsigned int j)
{ unsigned int z; float x;

  for(z=0,x=0; z<n; z++)
         x+=r[z]*B[z][j];
  return x;
}

void prodottoRigaColonna(unsigned int m, unsigned int n, unsigned int p,float C[m][p], float A[m][n], float B[n][p])
{ int i,j;

  for(i=0;i<m;i++)
      for(j=0;j<p;j++)
          C[i][j] = rigaXcolonna(n,p,A[i],B,j);
}

io chiamo prodottoRigaColonna, devo passare al posto di C ed B array monodimensionali che devono essere interpretati come matrici colonna, quindi di dim [n][1].
 
io non riesco manco a compilarlo (credo sia perché usare [n][m] nella dichiarazione della funzione non sia standard)... io consiglierei di scrivere diversamente
 
non saprei, ha funzionato bene fin'ora. ho scritto un file pieno di funzioni definite nello stesso modo e le ho usate per fare numerosi programmini perfettamente funzionanti....qual è il problema secondo te? come lo scriveresti?
 
float B[n][p] come parametro di una funzione equivale a martellarsi numerose parti del corpo..

1) già di per se var[a] non dovrebbe andare (non con un compilatore normale quantomeno), in quanto per questioni di allocazione occorrono valori costanti, oppure bisogna malloccare (o neware in C++ se è una tantum)
2) come parametro proprio non si può, infatti in C/C++ praticamente ogni funzione che richieda il passaggio di vettori/matrici hanno una lista parametri del tipo
Codice:
tipo* arr, int size
(ovviamente devi usare due parametri per le matrici).

Oppure puoi usare una struct per rappresentare la matrice (intuisco che è C dalle dichiarazioni delle var del for, se è C++ usare una classe forse è la scelta migliore);
struct nella quale definisci i parametri n e p.

Eh sì, purtroppo (o per fortuna, a seconda dei punti di vista), il C ha queste limitazioni, che però consentono di pensare il programma in modo più complessivo e stare più attenti.

Spero di essere stato utile e che si sia capito, in caso chiedi.


edit: ma poi, nella prima funzione, che te ne fai di B? se un parametro non è necessario, il non passarlo fa spesso risparmiare qualche bit ;)
 
Devo per forza passare B, realizzare il prodotto mediante i suoi elementi e quelli di A.
C deve contenere il risultato. Mi serve così ahimè non c'è molto da risparmiare :D

In realtà dallo standard c99 è consentita l'allocazione dinamica, anche dei parametri.
L'importante è che il compilatore sappia in quale variabile cercare la dimensione, tant'è vero che quando ho compilato mi ha dato un warning perchè avevo usato int, correndo il riscio (secondo il compilatore perchè io avevo controllato l'input) che venissero scelte dimensioni negative, ragione per cui ho usato unsigned int.

Non è quello il problema.
 
ok, ma quello che dico è:

Codice:
nomefunzione( float miao[h][k])

il compilatore semplicemente non può riempire quelle variabili, non gliele puoi passare (che io sappia quantomeno). Per quello si usano struct o puntatori ed un maggior numero di argomenti.
 
Whivel ha detto:
che compilatori usi? (almeno lo uso anch'io e ti do una risposta)
uso gcc.

a Malex : capisco ciò che dici, mi incuriosisce il fatto che tutte le altre funzioni definite allo stesso modo funzionino senza alcun problema!
Può darsi che ci sia un modo di definirle che sia meno soggetto a rischi di errori o più preciso, ma non credo sia questo il motivo per cui la funzione non fa il laboro che deve fare...
 
in teoria un gcc con -Wall e -pedantic come minimo dovrebbe trucidarti per quello, almeno da quello che mi risulta. Sinceramente non so che dire.
 
Malex ha detto:
in teoria un gcc con -Wall e -pedantic come minimo dovrebbe trucidarti per quello, almeno da quello che mi risulta. Sinceramente non so che dire.

Prova ad aggiungere agli switch di gcc -std=c99 e vedi come non mi trucida nessuno XD quello che faccio è conforme allo standard c99. Anzì mi è spuntato un warning in una funzione perchè leggevo un unsigned int con %d nella stringa di formato xD

Cmq ripeto, non è questo il problema che devo risolvere xD
 
ansi è uno standard precendente al c99... il problema del c99 è che i compilatori compatibili al 100% sono pochi e poco usati (quindi se poi lo devi dare ad un altro, è una brutta cosa)... mo vedo un pò

le funzioni sono corrette in linea di massima (sono riuscito a far fare il prodotto anche passando 2 vettori).
I warning sono riuscito ad eliminarli, ma con il cast, quindi puoi semplicemente ignorare gli errori (funziona anche con i warning).

L'unica cosa è che credo calcoli la matrice trasposta... devo controllare meglio


gcc -Wall -Wextra -std=c99 -pedantic -pedantic-errors

se metti anche -ansi ti da errori dicendo che lo standard c90 ( e non c99) non permette di fare il passaggio di parametri incriminato

(ovviamente con tutti sti parametri, il cast diventa d'obbligo)
 
come hai fatto il cast precisamente?
posso vedere cosa hai fatto al codice?

Off topic : Whivel ti dispiace se ti frego la firma e l'aggiungo alla mia? XD tutti mi tormentano affinchè io mi iscriva a facebook.....COSA CHE NON AVVERRA' MAI.
E' decisamente deleterio.
 
questo è il codice da affiancare alle 2 funzioni che mi hai dato tu
Codice:
int main()
{
	float riga[]={8,1,2,3,4,5};
	float colonna[]={18,11,12,13,14};
	float res[5][6]={0};


	//prodottoRigaColonna(5,1,6,res,(float (*)[(unsigned int)(1)])colonna,(float (*)[(unsigned int)(6)])riga);
	prodottoRigaColonna(5,1,6,res,colonna,riga);

	for(int i=0;i<5;i++)
	{
		for(int j=0;j<6;j++)
		{
			printf("%f\t",res[i][j]);
		}
		printf("\n");
	}
	return 0;
}

quello commentato è con il cast (a me funziona anche senza)

[ot]la firma la puoi prendere liberamente ^^[/ot]
 
se ti può essere utile, l'ho scritto a mio modo:
http://pastebin.com/G8euu1UK

funziona sia con matrici che con vettori, anche con scalari. L'unica cosa è che anche uno scalare viene definito come una matrice 1x1, quindi per il programma esso è una matrice, quindi se vuoi assegnarlo ad una variabile scalare float devi prendere il valore [0][0]

ps. la variabile int d è in più
ps.. per lo standard c89 non si può nemmeno dichiarare la dimensione di un array tramite delle variabili!
 
cyd ha detto:
ps.. per lo standard c89 non si può nemmeno dichiarare la dimensione di un array tramite delle variabili!

c99...


cmq io mi sto esercitando per un esame e mi sono dovuto limitare a ciò che abbiamo usato nel primo modulo del corso....non abbiamo fatto l'allocazione dinamica coi puntatori. L'avrei fatto anch'io così grossomodo, dopo di che una volta che lo standard consente alcune leggerezze per esercizio mi sono lasciato andare, grazie cmq dei consigli :)
 
Stato
Discussione chiusa ad ulteriori risposte.