Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando
Abbiamo giocato a lungo a Battlefield 6, abbiamo provato tutte le modalità multiplayer, Redsec, e le numerose personalizzazioni. In sintesi, ci siamo concentrati su ogni aspetto del titolo per comprendere al meglio uno degli FPS più ambiziosi della storia dei videogiochi e, dopo quasi due mesi, abbiamo tirato le somme. In questo articolo, condividiamo con voi tutto ciò che è Battlefield 6, un gioco che, a nostro avviso, rappresenta esattamente ciò che questo genere attendeva da tempo
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare
Abbiamo messo alla prova il drone Antigravity A1 capace di riprese in 8K a 360° che permette un reframe in post-produzione ad eliche ferme. Il concetto è molto valido, permette al pilota di concentrarsi sul volo e le manovre in tutta sicurezza e decidere con tutta tranquillità come gestire le riprese. La qualità dei video, tuttavia, ha bisogno di uno step in più per essere competitiva
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator
Dopo oltre 4 anni si rinnova la serie Sony Alpha 7 con la quinta generazione, che porta in dote veramente tante novità a partire dai 30fps e dal nuovo sensore partially stacked da 33Mpixel. L'abbiamo provata per un breve periodo, ecco come è andata dopo averla messa alle strette.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 27-03-2006, 12:24   #1
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
[c++]: dove sta l'errore in questo listato?

problema risolto.
vedere
http://www.hwupgrade.it/forum/showthread.php?t=1168051
per l'algoritmo
"prodotto di due matrici di grandezza qualsiasi"


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!







questo programma effettua il prodotto tra due matrici A, B e crea la matrice C=A*B

1)trovate l'errore per cui non funziona l'intestazione della funzione (la funzione è corretta se messa nel main ma messa esternamente in una funzione come ho fatto c'è errore di compilazione)
.
2)consigliate modifiche al programma per fare la stessa cosa in maniera più ottimizzata
3)in ingresso dico alla funzione anche quante righe e colonne hanno le matrici A e B che sono array. esiste un modo per estrarre il numero di "righe2 e "colonne" dall'array? ad esempio avendo un array "D=[a][b]", si può sapere quante righe "a" e colonne "b" è?


nota:le matrici A, B, C sono GLOBAL e devono essere modificate dalla funzione. già qui ho il dubbio se, per come ho scritto l'intestazione della funzione, in realtà sto creando due matrici locali e non sto mettendo i risultati dei calcoli nella globali)

listato:



#include<stdio.h>
#include <math.h>

double C [6][4];
double A [6][3]= { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14, 15}, {16, 17, 18} };
double B [3][4]= { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
double test;
int i,j,k;
double righeA, colonneA, righeB, colonneB;


//--------------------
//funzione
void prodottomatrici(double matA, double righeA, double colonneA , double matB, double righeB, double colonneB, double matC)
{
for (i=0; i<6; i++){
for (j=0; j<4; j++){
C[i][j]=0;
for (k=0; k<3; k++){
C[i][j]=C[i][j]+A[i][k]*B[k][j];
//test=A[i][k]*B[k][j];
//printf("%g\n", test );
}
printf("%g\n", C[i][j] );
}
}
}



//--------------------
void main(void)
{

prodottomatrici(A,6,3,B,3,4,C);

//stampa a video 2 elementi per test
printf("elemento C[1][1]: %g\n", C[0][0] );
printf("elemento C[4][4]: %g\n", C[3][3] );
//deve venire 38 e 272




}
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 29-03-2006 alle 11:15.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 13:29   #2
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Il problema principale nel sorgente è il passaggio degli array alla funzione prodottomatrici.
Bisogna ricordare innanzitutto che quando si passa un array (a 1, 2, ... n dimensioni) ad una funzione, non si passa l'intero array per valore ma solo il puntatore al primo elemento dell'array.

Se si ha un array:
double A [6][3] = { ... };
ci sono diversi modi per dichiarare il parametro della funzione:
a) double arr[6][3]
b) double arr[][3]
c) double (*arr)[3]
In ogni caso, la funzione non può conoscere la dimensione totale dell'array basandosi solo su questo argomento. Ad esempio facendo sizeof(arr) si ottiene 4 (la dimensione tipica di un puntatore).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 14:09   #3
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
anche mettendo nella dichiarazione della funzione

void prodottomatrici(double matA[6][4], double righeA, double colonneA , double matB[3][4], double righeB, double colonneB, double matC[6][4]) {


non funziona

appare il messaggio (visual studio .net)

error C2664: 'prodottomatrici' : cannot convert parameter 1 from 'double [6][3]' to 'double [][4]'

come risolvo?


listato modificato--------------








#include<stdio.h>
#include <math.h>

double C [6][4];
double A [6][3]= { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}, {13, 14, 15}, {16, 17, 18} };
double B [3][4]= { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
double test;
int i,j,k;
double righeA, colonneA, righeB, colonneB;


// PROGRAMMA PRINCIPALE ---------





//funzione
void prodottomatrici(double matA[6][4], double righeA, double colonneA , double matB[3][4], double righeB, double colonneB, double matC[6][4]) {

//i=righeA
//j=colonneB)
//k=colonneA=righeB

for (i=0; i<6; i++){
for (j=0; j<4; j++){
matC[i][j]=0;
for (k=0; k<3; k++){
matC[i][j]=matC[i][j]+matA[i][k]*matB[k][j];
//test=A[i][k]*B[k][j];
//printf("%g\n", test );
}
printf("%g\n", matC[i][j] );
}
}
}



void main(void)
{

prodottomatrici(A,6,3,B,3,4,C);

printf("elemento C[1][1]: %g\n", C[0][0] );
printf("elemento C[4][4]: %g\n", C[3][3] );





}


ps: ma matrC "locale" della funzione come fa apassare il risultato alla C globale con cui abbiamo richiamato la funzione?
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 27-03-2006 alle 14:12.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 14:20   #4
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
anche mettendo nella dichiarazione della funzione

void prodottomatrici(double matA[6][4], double righeA, double colonneA , double matB[3][4], double righeB, double colonneB, double matC[6][4]) {


non funziona
Dal listato mi risulta che l'array A è stato dichiarato double A [6][3] e non [6][4].

Quote:
Originariamente inviato da vermaccio
ps: ma matrC "locale" della funzione come fa apassare il risultato alla C globale con cui abbiamo richiamato la funzione?
Come ripeto, quando si passa un array ad una funzione si passa l'indirizzo del primo elemento. Se passi l'array C alla funzione, il parametro matrC contiene il puntatore al primo elemento di C. Essendo un puntatore, logicamente, puoi accedere al contenuto dell'array e leggere/scrivere nell'array.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 14:49   #5
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
Quote:
Originariamente inviato da andbin
Dal listato mi risulta che l'array A è stato dichiarato double A [6][3] e non [6][4].
opps! sono proprio un vermaccio! non me ne ero accorto!!!

grazie
ora funziona

__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 17:22   #6
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
ma posso passare alla funzione una matrice senza definire quanto è grande nell'intestazione della funzione?

es: ipotizziamo di avere

void prodottomatrici(double matA[4][4], double righeA, double colonneA , double matB[4][4], double righeB, double colonneB, double matC[4][4]) {
[...]
}


io, invece vorrei che al posto di matrici di grandezza fissata 4X4 (in questo esempio) double matA[4][4], double matB[4][4], double matC[4][4] io abbia matricI matA, matB, matC generiche e quando richiamo la funzione gli spedisco una matrice grosse come mi pare.

altrimenti posso passartgli solo matrici 4X4 mentre vorrei passargli matrici grandi a piacere. la loro dimensione la specifico con "righeA, colonneA, righeB, colonneB".

Se non faccio così ogni volta che moltiplico tra loro matrici di dimensioni diverse devo scrivere una funzione apposita!!!!!!!


io vorrei cioè creare una funzione che, se gli do in pasto due matrici MAT1=aXb e MAT2=bXc mi fa il loro prodotto e mi restituisce una matrice aXc:

la funzione la attiverei insomma con:

(nel main)
prodottomatrici(MAT1, a, b , MAT2, b, c, MATRICEPRODOTTO);



si può fare?
logicamente nei cicli interni "for" metto

or (i=0; i<a; i++){
for (j=0; j<c; j++){


il mio problema, ripeto, è l'intestazione della funzione, non il contenuto.
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 27-03-2006 alle 17:37.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 17:42   #7
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
Se ad esempio devo moltiplicare una matrice 3X4 e una 4X3 e poi una 4X5 con una 5X4 vorrei poter usare la stesa function senza dover scrivere 2 function distinte con in ingresso

void prodottomatrici(double matA[4][3], double righeA, double colonneA , double matB[3][4], double righeB, double colonneB, double matC[4][4]) {
[...]
}

e

void prodottomatrici(double matA[4][5], double righeA, double colonneA , double matB[5][4], double righeB, double colonneB, double matC[4][4]) {
[...]
}
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 17:55   #8
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
ma posso passare alla funzione una matrice senza definire quanto è grande nell'intestazione della funzione?

es:

void prodottomatrici(double matA[4][4], double righeA, double colonneA , double matB[4][4], double righeB, double colonneB, double matC[4][4]) {

//i=righeA
//j=colonneB
//k=colonneA=righeB !!!!!!! se colonneA diverso da righeB si ha errore

for (i=0; i<6; i++){
for (j=0; j<4; j++){
matC[i][j]=0;
for (k=0; k<3; k++){
matC[i][j]=matC[i][j]+matA[i][k]*matB[k][j];
//test=A[i][k]*B[k][j];
//printf("%g\n", test );
}
//printf("%g\n", matC[i][j] );
}
}


}


insomma invece che double matA[4][4], double matB[4][4], double matC[4][4] posso scrivere matriceA, B, c generiche e quando richiamo la funzione gli spedisco una matrice grosse come mi pare?
Diciamo che la risposta sarebbe (un si e un no, pressappoco).

Il problema in sostanza è il seguente. Come ho già detto in questo 3d, se si ha un array del tipo:

double A [6][3] = { ... };

Il parametro della funzione può essere dichiarato in questi modi:
a) double arr[6][3]
b) double arr[][3]
c) double (*arr)[3]

Cosa si può notare?? Il numero di colonne ([3] nell'esempio sopra) è sempre dichiarato. Il compilatore DEVE sempre conoscere quante colonne ci sono nell'array bidimensionale perché con questo valore è in grado, sfruttando l'aritmetica dei puntatori, di accedere alla cella [i][j].
Nella funzione, quando si fa arr[i][j], il compilatore è quindi in grado di "tradurre" questa istruzione in un qualcosa del tipo (spero di scriverlo giusto):

*(((double*) arr) + i*3 + j)

A questo punto si capisce bene che usando il solo argomento per il passaggio dell'array NON è possibile passare un array bidimensionale di dimensione qualsiasi, cioè con un numero di righe/colonne arbitrario.

In realtà la scappatoia ci sarebbe ma devi fare delle modifiche. In pratica devi fare tu quello che farebbe il compilatore per accedere ad una cella.

Esempio:

Codice:
double a[5][8] = { .... };

void funzione (double *arr, int nrig, int ncol)
{
    int i, j;   /* i due indici */
    double elem;

    ....
    elem = *(arr + i * ncol + j);
}
per chiamare la funzione si usa quindi, per esempio:
funzione (&a[0][0], 5, 8);

Spero, naturalmente, di aver spiegato la cosa in modo abbastanza chiaro!

P.S.: ho notato che passi alla funzione le dimensione tramite dei double. Non vedo per quale motivo devi passare dei double quando puoi tranquillamente passare degli int. Dopotutto le dimensioni sono dei numeri interi!
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 18:10   #9
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
passo dei double perchè prima di affinare il codice volevo risolvere questo problemino.

comunque.
non mi è molto chiaro nel caso devo passare due matrici:

Se abbiamo due matrici
double matA[5][8] = { .... };
double matB[8][3] = { .... };

come definisco l'intestazione della function?
(gli passo il numero di righe e colonne (5,8,8,3) delle due matrici matA e matB, la matrice "risultato" matC e, se ho ben capito, i puntatori alle due matrici, ma come lo scrivo?)

void funzione (...come lo scrivo?...)
{
int i, j; /* i due indici */

double elementomatriceA, elementomatriceB;

[...]
//se devo fare matC[x][y]=matA[i][j]+matB[m][n]
//un elemento di matriceA[i][j]
elementomatriceA= ... come lo definisco?
//un elemento di matriceB[m][n]
elementomatriceB= ... come lo definisco?



}


grazie per l'infinita pazienza che stai dimostrando
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 27-03-2006 alle 18:13.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 18:23   #10
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
passo dei double perchè prima di affinare il codice volevo risolvere questo problemino.

comunque.
non mi è molto chiaro nel caso devo passare due matrici:

Se abbiamo due matrici
double matrA[5][8] = { .... };
double matrB[8][3] = { .... };

come definisco l'intestazione della function?
(gli passo il numero di righe e colonne (5,8,8,3) delle due matrici matA e matB, la matrice "risultato" matC e, se ho ben capito, i puntatori alle due matrici, ma come lo scrivo?)

void funzione (...come lo scrivo?...)
{
int i, j; /* i due indici */

double elementomatriceA, elemento matriceB;

[...]
//se devo fare matC[x][y]=matA[i][j]+matB[m][n]
//elemento matA[i][j]
...come lo definisco?
//elemento matB[m][n]
...come lo definisco?



}
Faccio un esempio completo:
Codice:
double matrA[5][8] = { .... };
double matrB[8][3] = { .... };
double matrC[N][M];

/* Metti tu N ed M, io non so quanto deve essere
   per ottenere il prodotto delle matrici,
   non me ne intendo :p  */

void funz (double *matrA, int nrigA, int ncolA, double *matrB, int nrigB, int ncolB, double *matrC, int nrigC, int ncolC)
{
    int iA, jA;
    int iB, jB;
    int iC, jC;
    double elemA, elemB, elemC;

    ....
    elemA = *(matrA + iA * ncolA + jA);
    elemB = *(matrB + iB * ncolB + jB);

    elemC = .... metti il tuo calcolo ....

    *(matrC + iC * ncolC + jC) = elemC;
    ....
}

/* dal main */
funz (&A[0][0], 5, 8, &B[0][0], 8, 3, &C[0][0], N, M);
Quote:
Originariamente inviato da vermaccio
grazie per l'infinita pazienza che stai dimostrando
prego, non c'e problema.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 18:26   #11
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
tu hai scritto:

elem = *(arr + i * ncol + j);

il * più esterno indica indirizzo.
invece quello dentro è un prodotto, giusto?

elem è l'elemento della matrice arr[i][j] che passato alla funzione solo come puntatore *arr.

è così?

quindi dovrebbe essere

void funzione (double *matA, *matB, int nrigA, int ncolA, int nrigB, int ncolB)
{
int i, j, m,n;
// i,j indici di matrice A
//m,n indici di matrice B
double elem;

....
elemento_i_j_matrA= *(matA + i * ncolA + j);
elemento_m_n_matrB= *(matB + m * ncolB + n);
}

è così^?

ma
*(matA + i * ncolA + j);
indica il puntatore a cosa?
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 18:27   #12
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
sei stato più rapido di me

mi serve solo sapere il significato di *(bla bla bla) che metti dentro per trovare un elemento
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 27-03-2006, 20:32   #13
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
L'operatore * oltre ad essere l'operatore aritmetico della moltiplicazione, è anche l'operatore di "dereferenziazione" di un indirizzo. Dato un indirizzo, l'operatore * permette di accedere al valore puntato dall'indirizzo. Il tipo di dato puntato ovviamente deve essere dichiarato!

Esempio:
Codice:
int a = 20;  /* un intero */
int *ptr_a = &a;    /* un puntatore ad intero ... che punta subito ad a */

*ptr_a quindi vale 20
Così ti è più chiaro?

Nota che le parentesi tonde non centrano con la dereferenziazione. Nel mio esempio degli array *(matrA + iA * ncolA + jA) le parentesi servono per raggruppare una espressione. Il risultato di questa espressione (un indirizzo quindi) viene poi dereferenziato.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 28-03-2006, 00:16   #14
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
ok.
ma non ho capito perchè deferenziando
(matrA + iA * ncolA + jA) ,ovvero facendo *(matrA + iA * ncolA + jA), si ottiene elementoA della matrice A.



se abbiamo una matrice A che in realtà è un array di array [i][j], un suo elemento è, ad esempio, l'elemento [i][j]-esimo dell'array.
perchè ha indirizzo *(matrA + iA * ncolA + jA)??

matrA (che era stato passato alla function come indirizzo tramite la "void funz (double *matrA,...") è l'indirizzo del primo elemento dell'array di array quindi è l'indirizzo dell'elemento [0][0] dell'array. Se non ho detto una fesseria ed è vero, allora sommare (iA*ncolA) e JA che effetto ha?

La matrice A è un array di array quindi lo possiamo vedere anche, detto in modo gezzo, come una matrice di cellette cui è associato sia il valore dell'elemento della matrice relativo alla cellatte sia l'indirizzo della celletta nell'array. Un elemento [i][j] che indirizzo ha?





infine:
*ptr_a = &a

*ptr_a deferenzia il puntatore ad a.
ma &a cosa indica? il valore di a?

cioè è come avere una scatola chiamata "a".
l'etichetta è l'indirizzo della scatola (dove sta nello scaffale).
il contenuto è il valore ovvero cosa c'è nella cscatola (quanto vale "a").

&scatola sarebbe il contenuto della scatola "a"
prt_a è l'indirizzo
*ptr_a il contenuto della scatola puntata dal puntatore prt_a ovvero "a"

è esatto?

ma se così è allora quando dichiaro una variabile

a=2

io in realtà sto dicendo &a=2 cioè il contenuto della scatola a è "2"?
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 28-03-2006 alle 00:31.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 28-03-2006, 10:14   #15
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
ok.
ma non ho capito perchè deferenziando
(matrA + iA * ncolA + jA) ,ovvero facendo *(matrA + iA * ncolA + jA), si ottiene elementoA della matrice A.



se abbiamo una matrice A che in realtà è un array di array [i][j], un suo elemento è, ad esempio, l'elemento [i][j]-esimo dell'array.
perchè ha indirizzo *(matrA + iA * ncolA + jA)??

matrA (che era stato passato alla function come indirizzo tramite la "void funz (double *matrA,...") è l'indirizzo del primo elemento dell'array di array quindi è l'indirizzo dell'elemento [0][0] dell'array. Se non ho detto una fesseria ed è vero, allora sommare (iA*ncolA) e JA che effetto ha?

La matrice A è un array di array quindi lo possiamo vedere anche, detto in modo gezzo, come una matrice di cellette cui è associato sia il valore dell'elemento della matrice relativo alla cellatte sia l'indirizzo della celletta nell'array. Un elemento [i][j] che indirizzo ha?





infine:
*ptr_a = &a

*ptr_a deferenzia il puntatore ad a.
ma &a cosa indica? il valore di a?

cioè è come avere una scatola chiamata "a".
l'etichetta è l'indirizzo della scatola (dove sta nello scaffale).
il contenuto è il valore ovvero cosa c'è nella cscatola (quanto vale "a").

&scatola sarebbe il contenuto della scatola "a"
prt_a è l'indirizzo
*ptr_a il contenuto della scatola puntata dal puntatore prt_a ovvero "a"

è esatto?

ma se così è allora quando dichiaro una variabile

a=2

io in realtà sto dicendo &a=2 cioè il contenuto della scatola a è "2"?
No, alt .... facciamo chiarezza!

Nel linguaggio C/C++ ci sono 2 operatori per la gestione degli indirizzi:
- l'operatore & per reperire l'indirizzo di una variabile
- l'operatore * per reperire il valore di una variabile dato il suo indirizzo

Quindi:
int a = 14;
Dire &a significa "indirizzo di a".

int *pa;
pa è un "puntatore ad un intero" (quindi il valore di pa deve essere un indirizzo).

Da queste ne deriva che puoi fare:
int *pa = &a;

A questo punto, dopo queste assegnazioni, che tu dica a oppure *pa, entrambi "valgono" 14.
Un po' più chiaro adesso?

Veniamo al problema dell'array bidimensionale.
Sei d'accordo con me che se dichiari il parametro della funzione come array bidimensionale, sei costretto a dichiarare almeno il numero delle colonne?
Come ho già spiegato, il parametro della funzione può essere dichiarato in uno di questi modi (non so se ce ne sono altri, ma se ci fossero sarebbero alquanto "bizzarri" quasi quanto il terzo modo):
a) double arr[6][3]
b) double arr[][3]
c) double (*arr)[3]

Usando un parametro arr come sopra, dentro la funzione puoi usare senza problemi l'espressione arr[i][j]. Il compilatore sapendo che è un array bidimensionale, implementa lui l'aritmetica dei puntatore per accedere alla cella voluta.

Se il tuo problema è quello di voler passare un array bidimensionale qualsiasi, non puoi più usare il modo sopra ma fare tu e ripeto TU, quello che farebbe il compilatore.
Un array, indipendentemente dal numero di dimensioni, fisicamente è memorizzato (in memoria) come un array lineare di celle.
Quindi tu dichiarando un double *matrA, dichiari un semplice puntatore a un double e devi applicare tu l'aritmetica dei puntatori per accedere alla cella voluta.

Esempio pratico in memoria (nota che i double sono tipicamente lunghi 8 byte).

double A[2][3] = { { 3,5,8 }, { 2,6,4 } };

double *pa = &A[0][0];


Dal punto di vista "logico" hai:
+---+---+---+
| 3 | 5 | 8 |
+---+---+---+
| 2 | 6 | 4 |
+---+---+---+

Supponiamo che A parta dall'indirizzo 1000. Dal punto di vista fisico (in memoria) hai 6 double in sequenza memorizzati così:
Codice:
Indirizzo   valore
1000        3
1008        5
1016        8
1024        2
1032        6
1040        4
(quindi pa vale 1000)

dire A[i][j] è quindi equivalente a dire *(pa + i*3 + j).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 28-03-2006, 12:25   #16
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
Quote:
Originariamente inviato da andbin
Nel linguaggio C/C++ ci sono 2 operatori per la gestione degli indirizzi:
- l'operatore & per reperire l'indirizzo di una variabile
- l'operatore * per reperire il valore di una variabile dato il suo indirizzo

Quindi:
int a = 14;
Dire &a significa "indirizzo di a".
ehm...
ma se <<l'operatore & per reperire l'indirizzo di una variabile>> allora "&a" è l'indirizzo della variabile a.

Se "pa" è l'indirizzo di a, poichè <<l'operatore * per reperire il valore di una variabile dato il suo indirizzo>>
allora "*pa" è la variabile ed infatti tu dichiari la variabile "int *pa" ovvero dichiari la variabile intera "a" che sta all'indirizzo pa

MA (e se chiarisco questo ho capito )
come posso dire
int *pa = &a;
????

il membro a sinistra "int *pa" indica la variabile a tramite la deferenziazione del suo indirizzo pa.

il membro a destra "&a" indica l'indirizzo di a.

che senso ha scrivere l'uguaglianza
int *pa = &a;
se cosa sta a sinistra non è omogeneo con cosa sta a destra?
a sinistra ho una variabile.
a destra un indirizzo.

int *pa = &a;
equivale a dire
int a = &a;

cioè dici che a è uguale al suo indirizzo?????

?
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 28-03-2006, 12:44   #17
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
ehm...
ma se <<l'operatore & per reperire l'indirizzo di una variabile>> allora "&a" è l'indirizzo della variabile a.
Perfetto.

Quote:
Originariamente inviato da vermaccio
Se "pa" è l'indirizzo di a, poichè <<l'operatore * per reperire il valore di una variabile dato il suo indirizzo>>
allora "*pa" è la variabile ed infatti tu dichiari la variabile "int *pa" ovvero dichiari la variabile intera "a" che sta all'indirizzo pa

MA (e se chiarisco questo ho capito )
come posso dire
int *pa = &a;
????

il membro a sinistra "int *pa" indica la variabile a tramite la deferenziazione del suo indirizzo pa.

il membro a destra "&a" indica l'indirizzo di a.

che senso ha scrivere l'uguaglianza
int *pa = &a;
se cosa sta a sinistra non è omogeneo con cosa sta a destra?
a sinistra ho una variabile.
a destra un indirizzo.

int *pa = &a;
equivale a dire
int a = &a;

cioè dici che a è uguale al suo indirizzo?????

?
Precisazione:

Dichiarare:
int *pa;
significa dichiarare una variabile pa che è "un puntatore ad un intero". Nella dichiarazione, il * sta per puntatore.

Una variabile "puntatore" contiene un indirizzo.

Quindi la dichiarazione:
int *pa = &a;
significa "assegnare l'indirizzo di a alla variabile puntatore pa"

Nota che il = non significa uguaglianza ma assegnamento.

Quando fai:
int a = 2;
non vuol dire che a è uguale a 2 ma che hai assegnato 2 ad a!!!
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 28-03-2006, 13:14   #18
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
perfetto!
sei stato illuminante.
tra oggi e domani cerco di scrivere quell'algoritmo e poi ti faccio sapere.

visto il tuo contributo te lo incollo qui se funziona. un algoritmo che serve a moltiplicare due matrici di dimensioni qualsiasi fa sempre comodo.

nota per te:

se hai due matrici
A[a][b]
B[m][n]

per moltiplicare A*B
DEVE essere b=m
e la matrice che si ottiene è
C[a][n]=A*B


logicamente B*A è DIVERSO da A*B

B*A=D[m][b] ma deve essere n=a
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 28-03-2006, 13:28   #19
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Qualcosa sulle matrici l'avevo sicuramente studiato in un passato molto ... remoto. Attualmente in matematica sono moooolto arruginito!!!

Comunque la mitica Wikipedia ancora una volta viene in (mio) aiuto:
http://it.wikipedia.org/wiki/Moltiplicazione_di_matrici
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 28-03-2006, 16:01   #20
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
qualcosa non va, credo:

tu hai detto
<<

double A[2][3] = { { 3,5,8 }, { 2,6,4 } };

double *pa = &A[0][0];


Dal punto di vista "logico" hai:
+---+---+---+
| 3 | 5 | 8 |
+---+---+---+
| 2 | 6 | 4 |
+---+---+---+

Supponiamo che A parta dall'indirizzo 1000. Dal punto di vista fisico (in memoria) hai 6 double in sequenza memorizzati così:
Codice:
Indirizzo   valore
1000        3
1008        5
1016        8
1024        2
1032        6
1040        4
(quindi pa vale 1000)

dire A[i][j] è quindi equivalente a dire *(pa + i*3 + j).
>>

Facciamo un esempio per vedere che esce fuori

elemento in matrice[1][1]=(3) = essendoarray = A[0][0] =*(pa + i*3 + j)=*(1000+0+0)=*(100) : ok.

elemento in matrice[2][3]=(4) = essendoarray = A[1][2] =*(pa + i*3 + j)= *(1000+1*3+2)=*(1005) : NO!

qualcosa non va. dove è che nella "formulina2 c'è il salto di 8 bit in 8 bit?

ogni riga, essendo la matrice di j colonne, occupa 8*j bit
avendo matrice [2X3] cioè j=3
inizio riga1: 1000
fine riga1: 1000+8*3-1=1023
primo elemento riga2: 1000+8*3=1024

quindi se sto in i-esima riga io devo andare "avanti" di i*(8*j) per trovare primo elemento di riga i-esima

+---+---+---+
| X | X | X |
+---+---+---+
| 2 | 6 | 4 |
+---+---+---+

se salto tutta prima riga perchè voglio eelemento in seconda riga

una volta che sono sulla riga i-esima devo spostarmi sull'elemnto che voglio di quella riga e vado a vedere in che colonna j sto: ogni "posto" (colonna) che avanzo io avanzo di 8 bit quindi +8*j

+---+---+---+
| X | X | x |
+---+---+---+
| X | 6 | 4 |
+---+---+---+

se mi fermo al secondo elemento della seconda riga


quindi *(1000+i*(8*j)+8*j)=
*(1000+8*i*j+8*j)

riapplichiamo "*(1000+8*i*j+8*j)" all'esempio che in altro non funzionava per vedere se è corretto:

Supponiamo che A parta dall'indirizzo 1000.
*pa=1000
(quindi pa vale 1000)

elemento in matrice[1][1]=(3) = essendoarray = A[0][0] =*(pa+8*i*j+8*j)=*(1000+8*0*0+8*0)=*(100) : ok.

elemento in matrice[2][3]=(4) = essendoarray = A[1][2] =*(pa+8*1*2+8*2)= *(1000+16+16)=*(1032) : OK!

Codice:
Indirizzo   valore
1000        3
1008        5
1016        8
1024        2
1032<--   6 <--eccolo!
1040        4


confermi?
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 28-03-2006 alle 16:04.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando Due mesi di Battlefield 6: dalla campagna al bat...
Antigravity A1: drone futuristico per riprese a 360° in 8K con qualche lacuna da colmare Antigravity A1: drone futuristico per riprese a ...
Sony Alpha 7 V, anteprima e novità della nuova 30fps, che tende la mano anche ai creator Sony Alpha 7 V, anteprima e novità della ...
realme GT 8 Pro Dream Edition: prestazioni da flagship e anima racing da F1 realme GT 8 Pro Dream Edition: prestazioni da fl...
OVHcloud Summit 2025: le novità del cloud europeo tra sovranità, IA e quantum OVHcloud Summit 2025: le novità del cloud...
Malesia, giro di vite sul mining illegal...
Meta rivede la roadmap: visore ultralegg...
Addio ricariche continue con le elettric...
Maxi sconto sul robot del futuro: roboro...
I 3 super TV OLED e QLED crollati su Ama...
Tre notebook fuori di testa in sconto: M...
Sconti iPhone su Amazon: oggi ci sono i ...
Google rende disponibile Gemini 3 Deep T...
I 3 super robot Dreame Aqua10 Roller tor...
Tornano in sconto le scope elettriche Ti...
IA nei videogiochi: anche SEGA la utiliz...
Apple in piena tempesta: anche il boss d...
Due GeForce GTX 580 in SLI: l'insospetta...
TSMC dà i numeri: dal processo N7...
La ricarica wireless dei Samsung Galaxy ...
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: 13:01.


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