Torna indietro   Hardware Upgrade Forum > Software > Programmazione

HONOR Magic 8 Pro: ecco il primo TOP del 2026! La recensione
HONOR Magic 8 Pro: ecco il primo TOP del 2026! La recensione
HONOR ha finalmente lanciato il suo nuovo flagship: Magic 8 Pro. Lo abbiamo provato a fondo in queste settimane e ve lo raccontiamo nella nostra recensione completa. HONOR rimane fedele alle linee della versione precedente, aggiungendo però un nuovo tasto dedicato all'AI. Ma è al suo interno che c'è la vera rivoluzione grazie al nuovo Snapdragon 8 Elite Gen 5 e alla nuova MagicOS 10
Insta360 Link 2 Pro e 2C Pro: le webcam 4K che ti seguono, anche con gimbal integrata
Insta360 Link 2 Pro e 2C Pro: le webcam 4K che ti seguono, anche con gimbal integrata
Le webcam Insta360 Link 2 Pro e Link 2C Pro sono una proposta di fascia alta per chi cerca qualità 4K e tracciamento automatico del soggetto senza ricorrere a configurazioni complesse. Entrambi i modelli condividono sensore, ottiche e funzionalità audio avanzate, differenziandosi per il sistema di tracciamento: gimbal a due assi sul modello Link 2 Pro, soluzione digitale sul 2C Pro
Motorola edge 70: lo smartphone ultrasottile che non rinuncia a batteria e concretezza
Motorola edge 70: lo smartphone ultrasottile che non rinuncia a batteria e concretezza
Motorola edge 70 porta il concetto di smartphone ultrasottile su un terreno più concreto e accessibile: abbina uno spessore sotto i 6 mm a una batteria di capacità relativamente elevata, un display pOLED da 6,7 pollici e un comparto fotografico triplo da 50 MP. Non punta ai record di potenza, ma si configura come alternativa più pragmatica rispetto ai modelli sottili più costosi di Samsung e Apple
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


HONOR Magic 8 Pro: ecco il primo TOP del 2026! La recensione HONOR Magic 8 Pro: ecco il primo TOP del 2026! L...
Insta360 Link 2 Pro e 2C Pro: le webcam 4K che ti seguono, anche con gimbal integrata Insta360 Link 2 Pro e 2C Pro: le webcam 4K che t...
Motorola edge 70: lo smartphone ultrasottile che non rinuncia a batteria e concretezza Motorola edge 70: lo smartphone ultrasottile che...
Display, mini PC, periferiche e networking: le novità ASUS al CES 2026 Display, mini PC, periferiche e networking: le n...
Le novità ASUS per il 2026 nel settore dei PC desktop Le novità ASUS per il 2026 nel settore de...
Il MacBook Pro è sempre più...
Il prezzo della Switch 2 potrebbe divent...
TikTok chiarisce il funzionamento della ...
Samsung Galaxy A07 5G: il nuovo entry le...
Realme 16 in arrivo: un mix tra iPhone A...
Domenica di follia su Amazon: iPhone 17 ...
Questo portatile HP OMEN con Core Ultra ...
Robot aspirapolvere al prezzo giusto: le...
Il nuovo M5 Max potrebbe avere una GPU p...
Pulizie automatiche al top (e a prezzo B...
Casa più calda, spese più leggere: Tado ...
Mini PC mostruoso in offerta nascosta su...
Netflix promette 45 giorni di esclusivit...
Gigabyte: un handheld? Sì, ma sol...
Samsung conferma l'arrivo di tre variant...
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: 05:46.


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