Newsgroup: it.comp.lang.c++
Titolo: typedef su array

Salve a tutti,
ho un paio di questioni sul codice seguente
---------------------------------------------------------------------
typedef char char3[3];
void func(char3 arg){
	int sz2=sizeof(arg);
	arg[0]=0;
}
int main(){
	char3 x={1, 2, 3};
	int sz1=sizeof(x);
	func(x);
	return 0;
}
---------------------------------------------------------------------
Come mai sz1==3 (come atteso) mentre sz2==4?
Perché dopo la chiamata a func(x) si ha x[0]==0? Ma x non è passato
per valore?
In effetti Visual C mi dice che il tipo di x è char[3] mentre arg è di
tipo char*, ma scrivere
	void func(char3 arg);
non vuol dire che arg nel corpo di func sarà di tipo char3 cioè
char[3]?
Saluti,
Enzo

 char[3]?
No, il tipo sarà "char*", come hai potuto verificare.
Due programmi qua sotto, una modifica del tuo e un esempio di come usare 
agevolmente uno std::vector per fare tutto quello che ti serve.
Nota pure come, nel secondo programma, il vettore viene passato per 
riferimento alla funzione "assegna_valori" (ossia come "vector<int>&") 
perché la funzione deve essere in grado di modificare il vettore, mentre 
la funzione "stampa_valori" non ha bisogno di modificarlo, quindi posso 
(e faccio meglio a) passarlo per riferimento costante, ossia come "const 
vector<int>&".
Come ho scritto nell'altro messaggio, avere a disposizione un buon libro 
di testo e leggere la FAQ che ti ho segnalato ti aiuteranno a studiare 
il C++ "a livello del C++" - dalle domande che poni, sembra tu ti stia 
concentrando su degli aspetti di basso livello ereditati dal C, e 
potresti tranquillamente farne a meno per il momento, utilizzando invece 
le funzionalità della libreria standard come ad esempio std::vector, che 
sono estremamente più comode e sicure da usare.
programma I
//-------
#include <iostream>
#include <typeinfo> // per usare typeid
using namespace std;
typedef char char3[3];
void func(char3 arg) {
     int sz2 = sizeof(arg);
     cout << "sz2 == " << sz2 << endl;
     if (typeid(arg) == typeid(char3)) {
         cout << "arg e' di tipo char3" << endl;
     } else {
         cout << "arg NON e' di tipo char3" << endl;
     }
     arg[0] = 0;
}
void foo(char* pc) {
     pc[0] = 42;
}
int main() {
     char3 x = {1, 2, 3};
     cout << "x[0] == " << int(x[0]) << endl;
     func(x);
     cout << "x[0] == " << int(x[0]) << endl;
     foo(x);
     cout << "x[0] == " << int(x[0]) << endl;
     return 0;
}
//-------
programma II
//-------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void assegna_valori(vector<int>& v){
     for(int i = 0; i < v.size(); ++i) {
         v[i] = i * 3;
     }
}
void stampa_valori(const vector<int>& v) {
     cout << "valori contenuti nel vettore:" << endl;
     for(int i = 0; i < v.size(); ++i) {
         cout << "v[" << i << "] == " << v[i] << endl;
     }
}
int main(){
     cout << "creo un vettore di 10 int" << endl;
     vector<int> v(10);
     stampa_valori(v);
     cout << "assegno dei valori al vettore" << endl;
     assegna_valori(v);
     stampa_valori(v);
     cout << "inverto l'ordine degli elementi" << endl;
     reverse(v.begin(), v.end());
     stampa_valori(v);
     return 0;
}
//-------
-- 
  FSC - 
http://userscripts.org/scripts/show/59948
 
http://fscode.altervista.org
 - 
http://sardinias.com

> per valore?
Mi sono dimenticato di rispondere a questo in particolare.
Il "valore" al quale ti riferisci è l'indirizzo contenuto dal puntatore, 
quindi sì, il puntatore viene passato per valore. Ma il valore che stai 
passando è un indirizzo, e punta proprio all'array che avevi allocato, 
quindi, tramite un puntatore, stai passando "per riferimento" anche l'array.
Quel "per riferimento" non è proprio esatto: il passaggio per 
riferimento vero e proprio, in C++, si ottiene con l'operatore "&", non 
con i puntatori.
Passando un array stai solo passando l'indirizzo del primo elemento, 
quindi stai perdendo l'informazione sul numero di elementi (ossia stai 
perdendo l'informazione sulla dimensione dell'array). Ecco perché, di 
nuovo, è meglio lavorare con std::vector.


La risposta l'ho trovata nel sempre valido "Thinking in C++"
The fact that naming an array produces its starting address turns out
to be quite important when you want to pass an array to a function. If
you declare an array as a function argument, what you’re really
declaring is a pointer.
quindi
void func(char3 arg){ ....
equivale a
void func(char arg[3]){...
cioé
void func(char* arg){...