Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
vivo X300 Pro rappresenta un'evoluzione misurata della serie fotografica del produttore cinese, con un sistema di fotocamere migliorato, chipset Dimensity 9500 di ultima generazione e l'arrivo dell'interfaccia OriginOS 6 anche sui modelli internazionali. La scelta di limitare la batteria a 5.440mAh nel mercato europeo, rispetto ai 6.510mAh disponibili altrove, fa storcere un po' il naso
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2 è la nuova handheld PC gaming con processore AMD Ryzen Z2 Extreme (8 core Zen 5/5c, GPU RDNA 3.5 16 CU) e schermo OLED 8,8" 1920x1200 144Hz. È dotata anche di controller rimovibili TrueStrike con joystick Hall effect e una batteria da 74Wh. Rispetto al dispositivo che l'ha preceduta, migliora ergonomia e prestazioni a basse risoluzioni, ma pesa 920g e costa 1.299€ nella configurazione con 32GB RAM/1TB SSD e Z2 Extreme
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
A re:Invent 2025, AWS mostra un’evoluzione profonda della propria strategia: l’IA diventa una piattaforma di servizi sempre più pronta all’uso, con agenti e modelli preconfigurati che accelerano lo sviluppo, mentre il cloud resta la base imprescindibile per governare dati, complessità e lock-in in uno scenario sempre più orientato all’hybrid cloud
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 14-10-2005, 20: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, 21: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, 21: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, 21: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, 22: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, 22: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, 02: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, 02: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 02:24.
AnonimoVeneziano è offline   Rispondi citando il messaggio o parte di esso
Old 15-10-2005, 10: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, 10: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, 14:41   #11
bancodeipugni
Senior Member
 
L'Avatar di bancodeipugni
 
Iscritto dal: Nov 2013
Città: Nel cuore dell'8 Mile di Detroit
Messaggi: 3942
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, 10: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


Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria Recensione vivo X300 Pro: è ancora lui il...
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'...
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti AWS re:Invent 2025: inizia l'era dell'AI-as-a-Se...
Cos'è la bolla dell'IA e perché se ne parla Cos'è la bolla dell'IA e perché se...
BOOX Palma 2 Pro in prova: l'e-reader diventa a colori, e davvero tascabile BOOX Palma 2 Pro in prova: l'e-reader diventa a ...
Factorial, azienda di batterie allo stat...
Le specifiche fuori di testa della Yangw...
I numeri incredibili di Xiaomi: nel 2025...
In Cina è pronto il parco fotovol...
Neuralink accelera: produzione di massa ...
Starlink abbassa l'orbita di migliaia di...
Dal MIT una nuova batteria per auto elet...
Adam Mosseri parla di IA su Instagram: l...
Suonerie personalizzate e Tone Store: il...
LG UltraGear evo: svelati i monitor gami...
Nelle offerte Amazon del nuovo anno ci s...
Meta Quest 3 da 512 GB torna a 469€ con ...
Steam a inizio 2026: i giochi più vendut...
Auto sempre al top: compressore Xiaomi, ...
In Francia si ragiona sul ban dei social...
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: 17:00.


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