Newsgroup: it.comp.lang.c
Titolo: Matrici

Salve, come mai se dichiaro un matrice in questo modo:
char mat[3][3];
mi dà problemi quando vado ad accedere agli elementi, mentre se faccio così:
char *mat[3];
for (i=0;i<=3;i++) mat=(char *)malloc(3*sizeof(char));
funziona?
Con la prima dichiarazione l'allocazione non dovrebbe essere automatica?
Grazie.

Grazie.
Si... solo che gli indici partono da zero e si fermano a n-1.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 Con la prima dichiarazione l'allocazione non dovrebbe essere automatica?
Esatto. Ma tieni presente che in una matrice 3 x 3 gli indici degli
elementi vanno da 0 a 2. E comunque nella seconda hai fatto un errore:
il ciclo for deve contare da 0 a 2, non da 0 a 3 come fa attualmente.
Inoltre puoi anche togliere il cast alla malloc().
EMG

 confesso che e' un vizio che ho anche io).
Il mio DJGPP mi da warning e siccome sono allergico ai warnings faccio il
cast!

cast!
Il tuo DJGPP ti da' un warning, perche' non includi "stdlib.h".
Ignorare i messaggi di errore equivale a non imparare il linguaggio.

 cast!
Può darsi che tu stia compilando in modalità C++? A me non dà alcun
warning.
EMG

 confesso che e' un vizio che ho anche io).
come mai e' sconsigliato?
ho verificato che anche togliendo il casting gcc non da nessun warning,
pero' e' una cosa (il casting) che ho visto in molti sorgenti e su
alcune guide!
ciao
Kronos
-- 
Home: 
http://kronoz.tsx.org
"Chi parla in tono cortese,
 ma continua a prepararsi,
 potra' andare avanti;
 chi parla in tono bellicoso
 e avanza rapidamente
 dovra' ritirarsi" Sun Tzu -- L'arte della guerra


Non mi quadra il fatto che sia sconsigliato
Malloc ritorna un void *, ossia un generico puntatore che deve essere
castato al tipo corretto.
Io normalmente il cast ce lo metto sempre, anche se dal punto di vista
pratico non fa nulla, per lo meno se ci si limita ad un semplice
assegnamento.
se abbiamo:
char *Ptr;
Ptr = malloc( 10 * sizeof( char ));
char *Ptr;
Ptr = ( char *) malloc( 10 * sizeof( char )) ;
il compilatore farà la stessa cosa: scrivere nella locazione denominata Ptr
l'indirizzo ritornato da malloc.
Però col cast sicuramente la leggibilità ci guadagna, e il compilatore non
si lamenta.
Ciao
Ricky

 EMG

No malloc restituisce un (void *) e il cast è necessario.
Il cast NON E' affatto necessario in C, perche' in C ogni puntatore
tipizzato e' convertibile in puntatore NON tipizzato.

alcune guide!
Quelle guide sbagliano a consigliarlo come "obbligatorio", se e'
questo che fanno.
Il cast e' necessario in C++, NON in C.

si lamenta.
Non vedo in che modo ci possa guadagnare la leggibilita' del codice.
Il cast in C e' da evitare la maggior parte delle volte in cui si puo'
fare, perche' riduce i controlli sulla correttezza dei tipi, gia' per
altro deboli in questo linguaggio. Ribadisco che in C, a differenza
del C++, ogni puntatore tipizzato puo' essere convertito in puntatore
non tipizzato, senza alcun problema di sorta.

 No malloc restituisce un (void *) e il cast è necessario.
No, non è necessario in quanto in C la conversione da void * a qualunque
tipo puntatore è automatica.
EMG

 tipizzato e' convertibile in puntatore NON tipizzato.
Se malloc restituisce (Void *) dove è la tipizzazione.
(Controlla prototipi  funzioni di un compilatore a staNDARD ansi).
cIAO.

cIAO.
Se leggi il K&R vedi che ti dice di castare sempre il risultato di
Calloc e Malloc... se ti leggi lo standard ISO credo dall'C89 in poi
vedi che il cast non e' piu' necessario, ma e' implicito.
Paolo

(Controlla prototipi  funzioni di un compilatore a staNDARD ansi).
Mi sono espresso male : ogni puntatore NON tipizzato viene
tranquillamente convertito in puntatore tipizzato, quindi NON C'E'
AFFATTO BISOGNO del cast. Controlla un buon manuale del linguaggio.

non tipizzato, senza alcun problema di sorta.
Ovviamente ho invertito i termini ;), nel senso che ogni puntatore NON
tipizzato viene convertito implicitamente in puntatore tipizzato.

 un compilatore a staNDARD ansi).
p.s.: lo standard e' ormai ISO.

 di sorta.
  C'e` da aggiungere che il cuore del problema e` dato dal fatto che il
C assume che ogni funzione o variabile non dichiarata sia di tipo /int/.
Se non si prototipizza correttamente la malloc(), ovvero se non si
include il file stdlib.h, il C presuppone che essa ritorni un intero, il
che puo` confliggere con il fatto che non sempre /int/ e /void */ hanno
la stessa dimensione.
	Alla prossima,
		Marco


K&R II ed pag 182
Il problema della dichiarazione di tipo per una funzione come *malloc* affligge
tutti i linguaggi che prendono in seria considerazione il controllo sui tipi. In C, 
la *soluzione corretta* consiste nel dichiarare che l'oggetto ritornato da *malloc*
č un puntatore a *void*, e forzare poi esplicitamente questo puntatore a puntare al tipo desiderato,
usando l'operatore *cast*. 
K&R II ed pag 183
*	return (struct tnode *)malloc(sizeof(struct tnode));
*	char *p;
	p = (char *)malloc(strlen(s)+1);
###############################################
H. Schildt La Guida Completa C++ II ed pag 137
In C un puntatore  void * viene automaticamente convertito nel tipo di puntatore che si trova sul lato
sinistro dell'assegnamento. Questa conversione automatica non avviene invece in C++.
In particolare,in C++, per assegnare un puntatore void * a un altro tipo di puntatore č necessario specificare
una conversione di tipo esplicita.
come esempio per il C riporta	:  char *p;
				   p = malloc(1000);
mentre per il C++            	:  p = (char *)malloc(1000);
Continua dicendo: 
come regola generale, quando in C++ si deve assegnare (o convertire) un tipo di puntatore in un
altro si deve sempre impiegare una conversione cast. Questa č una dele differenze
piů importanti tra il C e il C++.
 
-- 
================================================================================
TO REPLY
CHANGE 
NOS...@technologist.com
 IN ingv at 
technologist.com
"...Unix, MS-DOS, and Windows NT (also known as the 
    Good, the Bad, and the Ugly)."                     (by Matt Welsh)

H. Schildt La Guida Completa C++ II ed pag 137
Lascia perdere, Schildt lo conosciamo bene...
(
http://www.lysator.liu.se/c/schildt.html
)
H.S. e' riconosciuto come uno dei peggiori interpreti dello standard
del linguaggio e i suoi testi sono noti perche' pieni di scorrettezze.
Spero di avervi convinto ;)
--
Andrea Laforgia (ICQ 87230455)

 No malloc restituisce un (void *) e il cast è necessario.
Dalle FAQ internazionali:
7.7:    Why does some code carefully cast the values returned by malloc
        to the pointer type being allocated?
A:      Before ANSI/ISO Standard C introduced the void * generic pointer
        type, these casts were typically required to silence warnings
        (and perhaps induce conversions) when assigning between
        incompatible pointer types.
        Under ANSI/ISO Standard C, these casts are no longer necessary,
        and in fact modern practice discourages them, since they can
        camouflage important warnings which would otherwise be generated
        if malloc() happened not to be declared correctly; see question
        7.6 above.  (However, the casts are typically seen in C code
        which for one reason or another is intended to be compatible
        with C++, where explicit casts from void * are required.)
        References: H&S Sec. 16.1 pp. 386-7.
EMG

 
http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html
Bel colpo, Andrea! :-)
EMG


E dsove sono i compilatori 100% aderenti allo standard ?.
THA
gfb

E dsove sono i compilatori 100% aderenti allo standard ?.
I compilatori recenti e piu' conosciuti sono TUTTI 100% aderenti allo
standard ISO C. Sono le implementazioni C++ che soffrono la mancanza
di un'aderenza precisa.


 E dsove sono i compilatori 100% aderenti allo standard ?.
Che io sappia tutti i compilatori C moderni sono aderenti al 100% allo
standard C ISO.
EMG

standard C ISO.
E comunque non ha importanza l'aderenza o meno allo standard di una
particolare implementazione. Secondo lo standard il valore di ritorno
di malloc() non necessita d'essere "castato". 
Il programmatore che sfrutta una implementazione fuori standard sara'
una potenziale vittima degli effetti di un "cast" forzato. 
E' il prezzo da pagare per essere fuori standard.


 Inoltre puoi anche togliere il cast alla malloc().
Hai ragione, ma mi pare di aver provato a fare char *mat[4][4] e mi dava lo
stesso problema:
for (i=0;i<=3;i++){
    for (j=0;j<=3;j++) mat[i][j]=' ';
}
il primo ciclo non si chiudeva mai...come se scrivendo in mat[i][j] andassi
a modificare anche i...
Comunque, grazie per le risposte, se riuscite a spiegarmi questo problema,
poi...meglio ancora!
Il cast lo metto per comodità, così mi ricordo sempre che tipo di dato sto
considerando :-)

 stesso problema:
Chiaramente volevo dire char mat[4][4]
Ciao

 a modificare anche i...
Non so se è solo un errore di trascrizione, ma devi scrivere
char mat[4][4];
non
char *mat[4][4];
EMG

Difatti e' un errore del Kernighan & Ritchie (II edizione).
IMHO l'uso fuori standard della malloc è un problema legato non all'aderenza allo standard ma 
all'interpretazione dello standard che l'autore fà.
Con le inevitabili conseguenze che ne derivano. 
Ti porto come esempio un testo che sto consultando in questi giorni:
Beginning Linux Programming  IIed. 1999  di Stones, Matthew 
 
a pag 232 dice :
<<Notice that since malloc return a void * pointer, we cast the result to the char * we need.
The malloc function is guaranteed to return memory that is aligned so that it can be cast to 
a pointer of any type.>>


si lamenta.
Io ho detto "si dovrebbe evitare" perche' in "C"
effettivamente non aggiunge nulla se non pericoli.
Io programmo anche in C++ (dove il cast e' obbligatorio)
e comunque, anche in C, ho il vizio di mettere il
cast nonostante mi renda conto delle ragioni degli
oppositori di questa usanza.
Dopo qualche anno sono cose che "ti entrano nelle dita"
e le scrivi senza neanche rendertene conto :)
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

a pointer of any type.>>
Non e' necessario. malloc non ha bisogno di ALCUN cast.
--
Andrea Laforgia (ICQ 87230455)
"programmatori si nasce, non si diventa".

....tuttavia come mai a volte sei cosě caustico nelle risposte?
Perche' la soluzione a gran parte delle risposte, spessissimo, e' nei
manuali che andrebbero letti.
-- 
Andrea Laforgia (ICQ# 87230455) ---------------------------
Non scrivetemi in privato, se non richiesto espressamente.
No replies in private e-mail, unless explicitly requested.
----------------------------------------------------------