Newsgroup: it.comp.lang.c
Titolo: funzioni e indirizzi di memoria

Salve, ho riassunto il subject per motivi di spazio e vado al dunque.
ho questo programmino, ho ripreso il c per studi, in particolare
*devo* capire il lato *memoria*:
-----------
#include <stdio.h>
char FunzA(char grande) {
    if ((grande >= 65) && (grande < 90)) {
	grande = ('A' + 32);
	printf("%p\n", grande);
    }
 
    return grande;
}
char *FunzB(char *grandeB) {
    if ((*grandeB >= 65) && (*grandeB < 90)) {
	*grandeB = ('A' + 32);
	printf("%p\n", grandeB);
    }
 
    return *grandeB; /* qua' mi da il warning */
}
int main(void) {
    char carattere = 'A';
    char *Ptr;
    Ptr = &carattere;
    system("clear");
    printf("%p\n", carattere);
    printf("------------------------------\n");
    printf("%c\n", FunzA(carattere));
    printf("%c\n", carattere);
    printf("------------------------------\n");
    printf("%c\n", FunzB(Ptr));
    printf("%c\n", carattere);
 
    return (0);
}
######################
Con il seguente output:
######################
0x41
------------------------------
0x61
a
A
------------------------------
0xbf82dff3
a
a
Innanzitutto ricevo un warning, il famoso "return makes pointer
from integer without a cast.
Mi chiedo alcune cose:
1) perche' l'indirizzo di memoria non e' lo stesso ? 
Ptr, carattere e grandeB non dovrebbero avere lo stesso indirizzo ?
--  
Postato da Virgilio Newsgroup: scopri i nuovi gruppi 
Eros, foto e video a 
http://newsgroup.eros.virgilio.it

 Ptr, carattere e grandeB non dovrebbero avere lo stesso indirizzo ?
L'indirizzo di memoria è lo stesso, non capisco la domanda.
Ptr == FunzB(Ptr) == &carattere
Ciao

 Stai attento.
[...]
Va bene dai, grazie mille, e' inutile che chiedo ancora, non ho
capito; devo rivedermi i puntatori e le funzioni.
Grazie ancora, siete comunque preziosissimi, mi sfuggono i
concetti fondamentali, forse e' il caso mi deprimo un po' !!!


 concetti fondamentali, forse e' il caso mi deprimo un po' !!!
Non ti deprimere, dai. Posso dirti come feci io a suo tempo? Potrà 
sembrare banale ma da allora non l'ho mai scordato.
Pensa sempre a come è organizzata la RAM (per semplicità assumi che gli 
indirizzi siano a 16 bit):
0000  xxxx xxxx
0001  xxxx xxxx
....  .... ....
0204  0100 0001  <-- 'A'
0205  0000 0000
....  .... ....
FFFE  xxxx xxxx
FFFF  xxxx xxxx
Adesso supponi supponi che eseguendo questo pezzo di codice:
....
char *c;
printf("c punta a 0x%04x\n",c);
....
ottieni:
c punta a 0x0204
Pensando a come è organizzata la RAM si capisce subito cos'e' un 
puntatore: è un indirizzo di memoria.
Cos'e', invece, "*c". La risposta è: "il contenuto dell'indirizzo a a 
cui punta c".
Ora prendiamo la tua funzione. La riga:
char *FunzB(char *grandeB) {
si legge: "FunzB prende un puntatore a carattere e restituisce un 
puntatore a carattere".
mentre la riga
     return *grandeB; /* qua' mi da il warning */
si legge "restituisci il contenuto della cella puntata da grandeB (cioe' 
un carattere)".
In altre parole, avevi promesso che FunzB avrebbe restituito un 
indirizzo di memoria (e.g. 0x0204) ed invece ora gli fai resituire il 
contenuto della cella di memoria ('A').
Se l'esempio ti sembra semplice, prova a complicarlo.
Immagina a come è fatta una struttura in termini di allocazione di 
memoria e chiediti come mai su alcune architetture la struttura
struct {
   char  a;
   short b;
}
occupa 4 byte e non 3.
Oppure prova a chiederti se è vero che se c è un puntatore a carattere 
124[c] è un carattere.
O, ancora perche' ha senso considerare un punatore a funzione.
E cosi' via.
Hope it helps ....
Remo D.

Grazie *Remo D.*, l'esempio mi ha aperto la mente.
Ciao
