Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Il primo Sony con retroilluminazione True RGB alla prova del banco di misura e dei contenuti: luminanza enorme, colori accurati in HDR e un antiriflesso molto efficace. I limiti sono due sole HDMI 2.1 e il blooming fuori asse
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 14-10-2005, 19:48   #1
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
[C] Puntatori tripli e array di matrici

Ciao boys.

Oggi per divertimento ho iniziato a scrivere un po' di roba riguardante le matrici.

Per motivi logistici che non sto a spiegarvi mi risulterebbe molto utile riuscire a passare a una funzione del tipo
Codice:
float **funz(float ***);
un array di matrici del tipo

Codice:
float Matrici[2][5][5]
Il problema è che il passaggio semplice (come si fa con i puntatori ed array unidimensionali) :

Codice:
funz(Matrici)
Non funziona.

Ora mi trovo veramente in difficoltà , perchè ho sempre pensato agli array come "costanti di tipo puntatore" , e perciò con la stessa aritmetica e modus operandi dei normali puntatori.

Infatti il tutto funziona perfettamente con gli array unidimensionali, ma già quando si passa a quelli bidimensionali (matrici) scattano i problemi.

Vi faccio un esempio di un programmino che ho scritto apposta per esplicare il problema :

Codice:
#include <stdio.h>
#include <stdlib.h>

int a[5], *p;

int main(int argc, char **argv)

{
  p = a;

  printf("0x%X\n", p);
  printf("0x%X\n", a);
  printf("0x%X\n", *p);
  printf("0x%X\n", *a);
   
  return 0;

}
Come vedete nel programma viene fatta una cosa semplicissima. Viene dichiarato un array "a" e poi un puntatore "p" entrambi di tipo int.
Successivamente viene assegnato al puntatore "p" il valore di "a", ossia l'indirizzo del primo elemento di "a". Successivamente con le "printf()" scrivo a schermo una serie di valori in esadecimale. In particolare scrivo l'indirizzo contenuto in "p", quello contenuto in "a" e i valori puntati rispettivamente. L'output del programma è:

Codice:
melchior@melchior:~$ ./prova3
0x8049660
0x8049660
0x0
0x0
L'output è proprio quello che mi aspettavo. Gli indirizzi contenuti in "a" e in "p" sono identici e il valore puntato da quell' indirizzo è anch'esso identico (in questo caso = a "0" perchè l'array è stato inizializzato automaticamente dal compilatore a "0").

Ora ho provato a trasformare l'array in una matrice e il puntatore in un doppio puntatore in questo modo :

Codice:
#include <stdio.h>
#include <stdlib.h>

int a[5][5], **p;

int main(int argc, char **argv)

{
  p = a;

  printf("0x%X\n", p);
  printf("0x%X\n", a);
  printf("0x%X\n", *p);
  printf("0x%X\n", *a);
   
  return 0;

}
A questo punto mi aspettavo un output simile al precedente, solo che al posto del valore "0" nelle ultime 2 printf mi sarei ritrovato l'indirizzo del primo elemento del primo array della matrice "a" che ovviamente è uguale per entrambe le chiamate di printf , ma invece :

Codice:
melchior@melchior:~$ ./prova3
0x80496A0
0x80496A0
0x0
0x80496A0
Come vedete l'indirizzo contenuto in"a" e in "p" è sempre lo stesso, solo che se faccio il dereferimento di "p" ottengo inspiegabilmente "0", mentre facendo quello di "a" ottengo l'indirizzo contenuto in "a" stesso (che dovrebbe anche essere l'indirizzo del primo array di "a").

Chiaramente se faccio un doppio dereferimento di "p" con "**p" ottengo un "Segmentation Fault".

GCC mi da anche un warning alla compilazione del secondo programmino che nel caso del primo non appare :

Codice:
melchior@melchior:~$ gcc provaschif.c -o prova3
provaschif.c: In function 'main':
provaschif.c:9: warning: assignment from incompatible pointer type
Sinceramente però non riesco a capire cosa sbaglio

Grazie a tutti quelli che mi aiuteranno

Ciao

PS= Scusate per la lunghezza.
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 14-10-2005, 20:20   #2
Qu@ker
Member
 
Iscritto dal: Apr 2004
Messaggi: 130
Codice:
#include <stdio.h>

int a[5][5], (*p)[5];

int main()
{
  p = a;

  printf("%p\n", p);
  printf("%p\n", a);
  printf("%p\n", *p);
  printf("%p\n", *a);
   
  return 0;
}
Qu@ker è offline   Rispondi citando il messaggio o parte di esso
Old 14-10-2005, 20:28   #3
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da Qu@ker
Codice:
#include <stdio.h>

int a[5][5], (*p)[5];

int main()
{
  p = a;

  printf("%p\n", p);
  printf("%p\n", a);
  printf("%p\n", *p);
  printf("%p\n", *a);
   
  return 0;
}
Interessante, il problema è che non mi posso permettere una cosa del genere, dato che all' inizio non conosco neanche una delle dimensioni dell' array (e quindi non potrei scrivere quel [5]) .

Come potrei fare in questo caso senza sapere neanche una delle dimensioni dell'array?

Grazie

Ciao
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 14-10-2005, 20:33   #4
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da AnonimoVeneziano
Interessante, il problema è che non mi posso permettere una cosa del genere, dato che all' inizio non conosco neanche una delle dimensioni dell' array (e quindi non potrei scrivere quel [5]) .

Come potrei fare in questo caso senza sapere neanche una delle dimensioni dell'array?

Grazie

Ciao

Ho provato a fare :
Codice:
#include <stdio.h>

int a[5][5], (*p)[];

int main()
{
  p = a;

  printf("%p\n", p);
  printf("%p\n", a);
  printf("%p\n", *p);
  printf("%p\n", *a);
   
  return 0;
}
Sintassi a me sempre stata sconosciuta e funziona, il problema è che trasformando la cosa per un puntatore triplo non funziona, ne :

(*p)[ ][ ] :

melchior@melchior:~$ gcc provaschif.c -o prova3
provaschif.c:4: error: array type has incomplete element type

e nemmeno

(**p)[ ] (viene lo stesso problema che ho all' inizio)

Come fare?

Grazie

Ciao
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 14-10-2005, 21:21   #5
sirus
Senior Member
 
Iscritto dal: Mar 2004
Messaggi: 16053
io quando ho fatto un programmino che lavorava sulle matrici bidimensionali con allocazione dinamica et simila sono arrivato ai Puntatori a Puntatori e il passaggio di parametri era banalmente una cosa simile

Codice:
typedef riga float*;
typedef matrice riga*;

matrice funzione(matrice) {
...
}
non dovrebbe essere diverso...comunque ora sono sul PC2 e non ho a disposizione il programma domani ti posto il procedimento corretto e provi a vedere se riesci a fare funzionare il programma
sirus è offline   Rispondi citando il messaggio o parte di esso
Old 14-10-2005, 21:39   #6
Qu@ker
Member
 
Iscritto dal: Apr 2004
Messaggi: 130
Non sono sicuro di capire: se non hai le dimensioni come pensi di gestirlo, il puntatore?
Comunque, la sintassi (*p)[] dovrebbe essere un'estensione del GCC, anche se qualcosa di simile e' prevista anche nel C99. In ogni caso, l'array flessibile deve essere l'ultimo elemento, per cui con tre indici diventerebbe, ad es., (*p)[5][].
Tutto sommato, perche' non passi l'indirizzo come void *?
Qu@ker è offline   Rispondi citando il messaggio o parte di esso
Old 15-10-2005, 01:17   #7
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da sirus
io quando ho fatto un programmino che lavorava sulle matrici bidimensionali con allocazione dinamica et simila sono arrivato ai Puntatori a Puntatori e il passaggio di parametri era banalmente una cosa simile

Codice:
typedef riga float*;
typedef matrice riga*;

matrice funzione(matrice) {
...
}
non dovrebbe essere diverso...comunque ora sono sul PC2 e non ho a disposizione il programma domani ti posto il procedimento corretto e provi a vedere se riesci a fare funzionare il programma

Niente da fare , non funziona. Inoltre nel typedef "riga" e "float*" e "matrice" e "riga*" dovrebbero essere invertiti

Ciao
__________________
GPU Compiler Engineer
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 15-10-2005, 01:22   #8
AnonimoVeneziano
Senior Member
 
L'Avatar di AnonimoVeneziano
 
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
Quote:
Originariamente inviato da Qu@ker
Non sono sicuro di capire: se non hai le dimensioni come pensi di gestirlo, il puntatore?
Comunque, la sintassi (*p)[] dovrebbe essere un'estensione del GCC, anche se qualcosa di simile e' prevista anche nel C99. In ogni caso, l'array flessibile deve essere l'ultimo elemento, per cui con tre indici diventerebbe, ad es., (*p)[5][].
Tutto sommato, perche' non passi l'indirizzo come void *?

Metti che ho una roba del genere :

int arrayMatr[2][5][5];

funz(arrayMatr);

La mia funzione non può sapere a priori che che nella seconda parentesi ci sarà il valore 5, perchè , volendo , io potrei scrivere qualsiasi valore, quindi non posso dichiarare "funz()" come :

funz(int (*aMatr)[5][ ])

, ma dovrei dichiararla in modo generico come :

funz(int ***aMatr)

Questo però non me lo fa fare in modo corretto
__________________
GPU Compiler Engineer

Ultima modifica di AnonimoVeneziano : 15-10-2005 alle 01:24.
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 15-10-2005, 09:00   #9
sirus
Senior Member
 
Iscritto dal: Mar 2004
Messaggi: 16053
ecco come ho fatto io:
Codice:
/* definizione di un tipo di dato di nome Matrice di tipo **float */
typedef float *Riga;
typedef Riga *Matrice;

...

Matrice initMatrice(Matrice FMatrice, unsigned int FRows, unsigned int FColumns) {
	FMatrice = new float*[FRows]; // allocazione di un array di *float
	for(unsigned int j = 0; j < FRows; j++) {
		FMatrice[j] = new float[FColumns]; // allocazione di un array di float
	}
	/* per ogni array di puntatori a float viene definito un array di float
		al suo interno, questo array permetterà di immagazzinare i dati */
	return FMatrice;
}

...
ho messo la funzione più semplice che ho scritto (mi faceva allocare la matrice dinamicamente) comunque il passaggio di parametri (funzionante) l'ho fatto come sopra

non credo che aggiungendo un * in più...ossia creando un puntatore a puntatore a puntatore le cose cambino

spero di essere stato più chiaro e spero di aver capito il problema che avevi altrimenti
sirus è offline   Rispondi citando il messaggio o parte di esso
Old 19-01-2014, 09:40   #10
DomusP45
Senior Member
 
L'Avatar di DomusP45
 
Iscritto dal: Apr 2010
Città: Whiterun
Messaggi: 580
Invece io ho un problema leggermente diverso, ma simile.

Ho una serie di matrici 4x4 double. Sono tutti array "double [4][4]".

Sono 9 array di questo tipo. Io vorrei legarli ad un indice o altro array, da passare poi ad una funzione, così con l'indice, accedere a quella matrice.

Tipo, int elencomatrici[9] = non so come assegnargli le 9 matrici

funzione_prova (int elenco){

...

elenco[1] <--deve restituirmi la 2° matrice

}


come si fa questa cosa?
__________________
Come la chiami la chiami, la cocozza sempre cocozza è.
DomusP45 è offline   Rispondi citando il messaggio o parte di esso
Old 19-01-2014, 13:41   #11
bancodeipugni
Senior Member
 
L'Avatar di bancodeipugni
 
Iscritto dal: Nov 2013
Città: Nel cuore dell'8 Mile di Detroit
Messaggi: 3984
uhm...quasi 9 anni fa

vediamo se qualcuno ancora riceve le notifiche
bancodeipugni è offline   Rispondi citando il messaggio o parte di esso
Old 22-01-2014, 09:50   #12
Daniels118
Senior Member
 
L'Avatar di Daniels118
 
Iscritto dal: Jan 2014
Messaggi: 852
Codice:
#include <stdio.h>

#define N 2
#define W 5
#define H 5

typedef struct TMatrici {
  float matrici[N][W][H];
} TMatrici;

float media(TMatrici m) {
  int i, j, k;
  float avg = 0;
  for (i = 0; i < N; i++) {
    for (j = 0; j < W; j++) {
      for (k = 0; k < H; k++) {
        avg += m.matrici[i][j][k];
      }
    }
  }
  return avg / (N * W * H);
}

int main(int argc, char *argv[]) {
  int i, j, k;
  float avg;
  float l = 0;
  TMatrici m;
  for (i = 0; i < N; i++) {
    for (j = 0; j < W; j++) {
      for (k = 0; k < H; k++) {
        m.matrici[i][j][k] = l;
        l++;
      }
    }
  }
  avg = media(m);
  printf("%f\n", avg);
  system("PAUSE");	
  return 0;
}
Daniels118 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
La prima missione orbitale del razzo spa...
Servizi in streaming sempre più c...
Anteprima della Leapmotor B03X: inizia l...
Anthropic accusa la Cina: Claude utilizz...
I satelliti Rassvet (Starlink russo) di ...
Un agente IA ha risolto un problema su W...
Cina: la CMSA potrebbe cambiare parte de...
68 mensilità di bonus per i dipen...
Rocket Lab ha fatto ricorso contro la de...
Nutanix rende disponibile Azure Virtual ...
Il padrino del deep learning avverte: gl...
Il finto avviso "iPhone Storage is Full"...
Dietrofront in Cina, addio touchscreen p...
Un piccolo accessorio trasforma lo smart...
Dopo 370 anni il Cyphral Distich non è p...
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: 20:53.


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