Newsgroup: it.comp.lang.c
Titolo: Puntatori di array

Sono nuovo dell'ng e del c, provengo dal pascal e vi presento il primo
problema.
Sugli AppuntiLinux il bravo Daniele Giacomini ha scritto:"Per prima
cosa, bisogna rammentare che la stringa, anche se espressa in forma
letterale, è un array di caratteri, e come tale restituisce
semplicemente il puntatore del primo di questi caratteri."
Ma allora come individuo un singolo carattere della serie puntata?
Ho provato *array[n] per individuare l'n-simo da mandare ad una
printf, ma ho notato che l'indice n scorre avanti e indietro tra tutte
le stringhe puntate dall'array, e non sui singoli caratteri della
serie puntata.
ByeZ.
Rimuovi 'nospam.' dall'indirizzo per rispondermi.

 serie puntata.
?
Prova questo:
#include <stdio.h>
char stringa[81];
void main(){
int ciclo;
for (ciclo=0; ciclo<80; ciclo++)
    stringa[ciclo] = 'a' + ciclo;    /* Qui lo uso come array */
stringa[80] = 0;
printf("\nLa stringa è:\n%s", stringa);
printf ("\nPremi INVIO per vedere un elenco delle sottostringhe ottenute
togliendo un carattere a sinistra alla volta");
getchar();
for (ciclo=0; ciclo<80; ciclo++)
    printf (\n%s", (stringa + ciclo)); /* Qui uso l'aritmetica dei puntatori
*/
}
Otterrai forse un po' di warning, ma dovrebbe andare.
Per estrarre un solo carattere, alla posizione x, puoi usare:
char a; (scritto in un luogo opportuno)
...
a = stringa[x]; (vettore)
oppure
a = *(stringa+x); (puntatore)
oppure (più corretto con i puntatori)
a= *(&stringa[1] + x); (indirizzo del primo carattere + x)
Chiaro?
--
Alessandro Monti

 Ma allora come individuo un singolo carattere della serie puntata?
char c = stringa[ n ];
dove n è la posizione del carattere cercato (le posizioni iniziano da
0).
EMG

Ricorda che un array di stringhe non è altro che un vettore bi-dimensionale,
quindi lavora con le righe (le stringhe) e le colonne (i caratteri
all'interno di una stringa).
 
Quindi per visualizzare dei semplici caratteri devi creare un doppio ciclo:
 
char aszArray[10][20];
int iCntColonne;
int iCntRighe;
 
for(iCntRighe = 0;iCntRighe < 10;iCntRighe ++)
{
  for(iCntColonne = 0;iCntColonne < 20;iCntColonne ++)
    print("Carattere: %c\n",aszArray[iCntRighe][iCntColonne]);
}
 
se non conosci la dimensione di un singola stringa puoi sempre usare la
strlen()
Es.  for(iCntColonne = 0;iCntColonne < strlen(aszArray
[iCntRighe]);iCntColonne ++)
in questo modo eviti di visualizzare dei caratteri nulli ('\0')
 
questo sistema è valido anche per un array di puntatori a stringa:
 
char * apsArray[10];
int iCntColonne;
int iCntRighe;
 
for(iCntRighe = 0;iCntRighe < 10;iCntRighe ++)
{
  for(iCntColonne = 0;iCntColonne < strlen(apsArray [iCntRighe]);iCntColonne
++)
    print("Carattere: %c\n",apsArray[iCntRighe][iCntColonne]);
}
 
naturalmente i puntatori devono 'puntare' a delle aree di memoria ben
definite, o che hai precedentemente allocato.
 
spero di essere stato chiaro
 
Bye Treehenge
   -**** Posted from RemarQ, 
http://www.remarq.com/?a
 ****-
 Search and Read Usenet Discussions in your Browser - FREE -

 a= *(&stringa[1] + x); (indirizzo del primo carattere + x)
Dato che sono (mi sembra) tutte e tre altrettanto corrette allora la
prima è senz'altro preferibile per la sua estrema chiarezza.
EMG

serie puntata.
Se array è dichiarato come
char array[20];    // Stringa di 20 caratteri
allora array[n] ti ritorna l'ennesimo carattere della stringa altrimenti, se
array è dichiarato come
char array[10][20];    // Un array di 10 stringhe di 20 caratteri ciascuna
o
char *array[10];    // Un array di 10 stringhe la cui memoria deve essere
allocata (malloc)
array[n] ti ritorna l'ennesima stringa (il puntatore all'ennesima stringa) e
*array[n] ti ritorna il primo carattere dell'ennesima stringa.
In quest'ultimo caso per prelevare l'ennesimo carattere della stringa
"emmesima" devi usare la notazione array[m][n];
Ciao, Giuseppe
---------------------------------------------------------------------------
_Guybrush su IRCNet canale #programmazione
ICQ: 42227764
---------------------------------------------------------------------------

 wrote:
[ snip ]
AM>char a; (scritto in un luogo opportuno)
AM>...
AM>a = stringa[x]; (vettore)
AM>oppure
AM>a = *(stringa+x); (puntatore)
AM>oppure (più corretto con i puntatori)
AM>a= *(&stringa[1] + x); (indirizzo del primo carattere + x)
        ^^^^^^^^^^^
Qui va '&stringa[0]'.
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

you wrote :
#Sugli AppuntiLinux il bravo Daniele Giacomini ha scritto:"Per prima
#cosa, bisogna rammentare che la stringa, anche se espressa in forma
#letterale, è un array di caratteri, e come tale restituisce
#semplicemente il puntatore del primo di questi caratteri."
Io l'avrei scritta cosi' :
"Per prima cosa, bisogna rammentare che la stringa e' comunque un
vettore di caratteri, a cui ci si puo' riferire mediante la notazione
di vettore o quella di puntatore a carattere.
Nel primo caso, con tre eccezioni specifiche, il nome del vettore
decade nel puntatore al primo di questi caratteri.
Le tre eccezioni si verificano quando il nome del vettore e' argomento
di sizeof, dell'operatore address-of (&) e durante le inizializzazioni
con valori costanti literal".
#Ma allora come individuo un singolo carattere della serie puntata?
#Ho provato *array[n] per individuare l'n-simo da mandare ad una
#printf, ma ho notato che l'indice n scorre avanti e indietro tra tutte
#le stringhe puntate dall'array, e non sui singoli caratteri della
#serie puntata.
Se hai 
char mio_array[10] ;
accedi al quarto elemento tramite le notazioni alternative tra loro :
 1) mio_array[3]
 2) *(mio_array + 3)
--------------------------------------------------------
* Andrea Laforgia        (
andrea_...@bigfoot.com
) *
--------------------------------------------------------

allora array[n] ti ritorna l'ennesimo carattere della stringa
Ritorna il carattere (n+1)esimo, poichè il primo elemento ha indice 0.
_____________________________________________________
Francesco Trotta
http://space.tin.it/computer/ftrotta
elimina "x_" dal mio indirizzo per le risposte

 Qui va '&stringa[0]'.
Ops! Ecco cosa succede ad usare altri linguaggi.
E pensare che avevo invece controllato i cicli per evitare di indirizzare
oltre l'ultimo carattere, ma mi è sfuggito il primo :)
--
Alessandro Monti

 all'interno di una stringa).
Però parlava di stringhe=array di caratteri, non di array di stringhe.
Era un'altro thread che si preoccupava di ciò. Rischiamo di fare confusione.
--
Alessandro Monti

Ritorna il carattere (n+1)esimo, poichè il primo elemento ha indice 0.
Naturalmente, mi sono scordato di farlo notare. Grazie per l'appunto :-)


allocata (malloc)
La dichiarazione che ho usato è proprio di questo tipo:
char *options[10] = {"Nuovo", "Carica", "Salva", "Aggiungi",
"Modifica", "Elimina", "Esci"}
Avendo inserito già in fase di dichiarazione le stringhe, la malloc
diventa per me non necessaria?
Leggendo a pag. 138 di Linguaggio C Sec. Ed., tale dichiarazione
significherebbe che ho creato un vettore di nome 'options', i cui 10
elementi sono puntatori a carattere, e vista la dichiarazione a
stringhe [un vettore di puntatatori sostanzialmente, giusto??, e
quindi il subject andava girato? (in effetti vedo adesso che il titolo
del capitolo è 'vettori di puntatori e puntatori a puntatori'].
La soluzione di Davide Stanziano mi ha dato lo spunto giusto, infatti
io usavo erroneamente *options[s] per individuare l'[s-1] carattere
della stringa, mentre usando options[0][s] funziona correttamente. Il
[0] in pratica lo punta a se stesso, e options lo incremento di 1 a
fine ciclo (++options).
Cmq, e' forse più indicata la soluzione dell'array bidimensionale?? Il
vantaggio che vedo io attraverso l'uso dei puntatori in questo caso è
il risparmio di una variabile che fungerebbe da indice. Ce ne sono
altri?
Upcase, chr, ord in pascal: traduzione in c?


 chr, ord in pascal: traduzione in c?
Non servono a causa delle conversioni automatiche del C (weakly type
checking vs. strong type checking).
EMG

Upcase, chr, ord in pascal: traduzione in c?
Upcase = toupper, ma non so quanto questa sia standard. Per gli altri non
c'è bisogno di una funzione perchè in C ogni variabile carattere rappresenta
il proprio codice ASCII. Per esempio l' uguaglianza 'A'==65 risulta essere
vera e se scrivessi una cosa del tipo:
char c = '3';
printf("%d", c);
ti stamperebbe a video il numero 51, codice ASCII della lettera '3'.


vera e se scrivessi una cosa del tipo:
Poichè lo scostamento nel codice ASCII tra una lettera e la sua
maiuscola, si può facilmente implementare una fuzione personalizzata
void upperacase(char *string)
{
	for(; *(string++);) *string = ((*string>96) &&
(*string<123))?*string-=32:*string;


 Upcase = toupper, ma non so quanto questa sia standard.
E' standard.
EMG

}
Errata corrige
void upperacase(char *string)
{
	for(; *string; string++) *string = ((*string>96) &&


 convertito in un puntatore al primo elemento.
Dalle FAQ:
6.3:    So what is meant by the "equivalence of pointers and arrays" in
        C?
A:      Much of the confusion surrounding arrays and pointers in C can
        be traced to a misunderstanding of this statement.  Saying that
        arrays and pointers are "equivalent" means neither that they are
        identical nor even interchangeable.  What it means is that array
        and pointer arithmetic is defined such that a pointer can be
        conveniently used to access an array or to simulate an array.
        Specifically, the cornerstone of the equivalence is this key
        definition:
                An lvalue of type array-of-T which appears in an
                expression decays (with three exceptions) into a
                pointer to its first element; the type of the
                resultant pointer is pointer-to-T.
        That is, whenever an array appears in an expression,
        the compiler implicitly generates a pointer to the array's
        first element, just as if the programmer had written &a[0].
        (The exceptions are when the array is the operand of a sizeof or
        & operator, or is a string literal initializer for a character
        array.)
        As a consequence of this definition, the compiler doesn't apply
        the array subscripting operator [] that differently to arrays
        and pointers, after all.  In an expression of the form a[i], the
        array decays into a pointer, following the rule above, and is
        then subscripted just as would be a pointer variable in the
        expression p[i] (although the eventual memory accesses will be
        different, as explained in question 6.2).  If you were to assign
        the array's address to the pointer:
                p = a;
        then p[3] and a[3] would access the same element.
        See also questions 6.8 and 6.14.
        References: K&R1 Sec. 5.3 pp. 93-6; K&R2 Sec. 5.3 p. 99; ISO
        Sec. 6.2.2.1, Sec. 6.3.2.1, Sec. 6.3.6; H&S Sec. 5.4.1 p. 124.
EMG

Lo so cosa dice la faq; mi sono espresso male: quello che volevo evidenziare
 e' che il risultato di sizeof  viene calcolato durante la compilazione, non in esecuzione.

 e' che il risultato di sizeof  viene calcolato durante la compilazione, non in esecuzione.
Il seguente programmino ti illustra il fatto che array != puntatore al
suo primo elemento:
#include <stdio.h>
void pippo( char a[] )
{
    printf( "%ld\n", sizeof a );
}
int main()
{
    char a[ 10 ];
    printf( "%ld\n", sizeof a );
    pippo( a );
    return 0;
}
La dimensione stampata per prima è quella dell'array mentre quella
stampata per seconda è del puntatore al suo primo elemento. Come vedi
sono diverse.
EMG

E' evidene che continuo a esprimermi male; lo so benissimo che un array e' diverso
da un puntatore. E' pur vero pero' che il compilatore tratta i vettori in termini di puntatori
al primo elemento del vettore, tranne nei due casi citati dalla faq.


}
Ottima, promosso con 10 e lode! :-)


Thanks!


 al primo elemento del vettore, tranne nei due casi citati dalla faq.
I casi sono tre. Comunque il tuo mi sembra un punto di vista non esatto,
anche se può sembrare che in pratica si adatti a quello che succede. Il
modello corretto invece è di considerare array e puntatori come oggetti
diversi e tener conto che il nome dell'array viene convertito
implicitamente nel puntatore al suo primo elemento quando compare in
un'espressione, a parte le tre eccezioni già citate.
Scusa se insisto ma questo è un punto che sembra difficile da capire per
molti programmatori.
EMG

un'espressione, a parte le tre eccezioni già citate.
Non mi sembra di avere affermato nulla di diverso

you wrote :
#Francesco Trotta ha scritto nel messaggio ...
#>void upperacase(char *string)
#>{
#> for(; *string; string++) *string = ((*string>96) &&
#>(*string<123))?*string-=32:*string;
#>}
#Ottima, promosso con 10 e lode! :-)
Niente affatto, non e' portabile.
toupper() e' standard e portabile.


you wrote :
#> Non mi sembra che l'osservazione sia pertinente; sizeof agisce
#> solo in fase di compilazione.  In runtime, ogni vettore viene
#> convertito in un puntatore al primo elemento.
#
#Dalle FAQ:
Ehm... ma perche' non utilizzate gli spezzoni in italiano ? ;)


toupper() e' standard e portabile.
La funzione che ha scritto Francesco Trotta non usa alcuna funzione non
standard (anzi, non usa alcuna funzione) e poi toupper converte solo un
char.


options.......
I motivi sono:
1)  risparmio una variabile
2) l'utilità di options è valida solo all'interno della funzione,
perciò non mi interessa più alla fine della funzione stessa.
Forse la pecca di questa soluzione è la sua scarsa adattabilità ad
aggiornamenti, che potrebbero richiedere un altro utilizzo di options
all'interno della fuinzione (di cui in effetti avrò probabilmente
bisogno).
Credo allora che *consumerò* una variabile per l'indice.
Grazie ancora a tutti.


 char.
Non e' portabile perche' presuppone una rappresentazione ASCII dei
caratteri.
Incidentalmente, toupper non "converte solo char"; il comportamento e'
non definito se l'argomento non e' rappresentabile come UNSIGNED char
(o EOF).  Cfr. ANSI/ISO 7.3: "... the argument is an int, the value of
which shall be representable as an unsigned char or shall equal the
value of the macro EOF.  If the argument has any other value, the
behavior is undefined."
Spiegato al volgo, se il tuo compilatore usa caratteri signed ti serve
un cast a unsigned char per evitare situazioni spiacevoli; questo e'
il motivo per cui gcc da' un warning (ma solo in alcuni ambienti) se
richiami toupper con un argomento di tipo char.
-- 
Maurizio Loreti                      
http://wwwcdf.pd.infn.it/~loreti/mlo.html
Un. of Padova, Dept. of Physics - Padova, Italy          
lor...@padova.infn.it

 Ciao, Giuseppe
toupper esiste proprio per evitare di scrivere codice dipendente
dall' alfabeto. Il documento ANSI del C non cita alcun alfabeto,
ansi, e' aperto a tutti. L' ASCII, anche se molto diffuso, non e' l'
unico.
Probabilmente toupper() il ogni piattaforma e' realizzata nel modo
piu' efficiente possibile, ma se tu ti dovessi scrivere una tua
toupper portabile dovresti mappare ogni carattere:
if (c=='a') return 'A'
else
...
con perdita di efficienza.
ciao.

toupper() e' standard e portabile.
void uppercase(char *string)
{
for(; *string; string++) *string = ((*string>='a') &&
(*string<'z'))?*string-=('a' - 'A'):*string;
}
Forse cosě č meglio?


con perdita di efficienza.
A me è proprio l'efficenza che interessa particolarmente. Addirittura, se
l'avessi dovuta usare in una applicazione che fa largo uso delle stringhe,
quella funzione l'avrei scritta in assembler.


caratteri.
Caspita è vero: sono troppo assuefatto dalle architetture DOS\Win e penso
sempre in termini di codici ANSI :-( .


Credo allora che *consumerò* una variabile per l'indice.
Questo grande spreco....  :-)


 Forse così è meglio?
No, perché fa affidamento su relazioni che potrebbero non esistere. Non
è detto, ad esempio, che il codice della 'a' sia inferiore al codice
della 'z' o che i codici dei caratteri alfabetici siano tutti contigui.
EMG

 


quella funzione l'avrei scritta in assembler.
...perdendo però in portabilità.


you wrote :
#No, perché fa affidamento su relazioni che potrebbero non esistere. Non
#è detto, ad esempio, che il codice della 'a' sia inferiore al codice
#della 'z' o che i codici dei caratteri alfabetici siano tutti contigui.
Cosa che accade, per esempio, per l'EBCDIC.


...perdendo però in portabilità.
Non credo alla portabilità. Non è possibile scrivere codice portabile che
serva realmente a qualcosa o che sia efficiente. E' per questo che me ne
infischio dello standard.


 infischio dello standard.
Per me la portabilità è un concetto molto importante da prendersi però
in senso esteso. Mi spiego: sono d'accordo con te che un programma
scritto con il C standard serva a poco e comunque solo in determinati
tipi di lavori. Però abituandosi a sviluppare soluzioni il più possibile
svincolate dal particolare sistema/piattaforma/ambiente/compilatore su
cui si opera si ottengono molti vantaggi in termini di riuso di ciò che
si sta facendo. In fin dei conti è un po' la filosofia che sta alla base
dei design patterns. Quindi parliamo della portabilità di idee e
soluzioni che non di quella del mero codice che, tutto sommato, non è
poi così essenziale e perde, secondo me, sempre più importanza.
EMG

 sia efficiente. E' per questo che me ne infischio dello standard.
  Posto che per fare il /porting/ di un'applicazione scritta seguendo
questa filosofia richiede almeno un tempo decuplo rispetto a quello
necessario per un'applicazione il piu` possibile attinente allo
standard, non posso che ringraziarti a nome di tutta la categoria degli
sviluppatori /free-lance/, la quale indubbiamente prospera su scelte di
questo tipo. ;)
	Alla prossima,
		Marco

questo tipo. ;)
Mi fa piacere dare lavoro a te e ai tuoi colleghi :-)


fare solo perché scrivo con in mente la portabilità.
Il problema è che partiamo con una filosofia di sviluppo totalmente diversa:
tu magari sei disposto a perdere qualcosa in prestazioni pur di mantenerti
più vicino allo standard mentre io non ci penso due volte a utilizzare le
librerie che mi fanno più comodo o anche a riscrivermi in assembler le
funzioni standard (le meno performanti) solo per velocizzare un pò il tutto.


 Mi fa piacere dare lavoro a te e ai tuoi colleghi :-)
  Non faccio piu` l'"applicativo" da quando ho dovuto migrare
un'interfaccia grafica da Windows a Motif... sono esperienze che
segnano. :)))
	Alla prossima,
		Marco

 funzioni standard (le meno performanti) solo per velocizzare un pò il tutto.
Si, ma la tua filosofia è criticabile per due motivi principali:
1. Rende i programmi strettamente dipendenti dal
sistema/piattaforma/linguaggio/compilatore e rende quindi complessa
un'eventuale (molto probabile) migrazione anche solo su una nuova
versione di quest'ultimo.
2. L'ottimizzazione "bruta" ottenuta riscrivendo in Assembly le funzioni
può dare benefici immediati ma alla lunga non potrà mai essere efficace
come la scelta di un algoritmo migliore.
EMG

segnano. :)))
Non fai più l'applicativo? Che significa?
Un'altra info: Motif cosè? Un OS? una UI?


 versione di quest'ultimo.
Ma di solito si mantiene una certa compatibilitā all'indietro.
Del resto girano ancora i programmi DOS scritti quasi 20 anni fa.
Per il resto sono d'accordissimo, almeno bisognerebbe separare e
"incapsulare" il pių possibile le parti non standard, cosa che non costa
niente, se ben documentata.
Al limite basta un:
/* Funzione NON portabile */
int funzione (int)...
--
Alessandro Monti

come la scelta di un algoritmo migliore.
Ma io cerco (nel limite delle mie conoscenze) di usare sempre l'algoritmo
migliore. Poi le eventuali ottimizzazioni (che preciso, io attuo solo sulle
funzioni a basso livello o time-critical, mica su tutto il listato) vengono
sempre dopo.
Non ho mai cercato di velocizzare con l'assembler una funzione scritta da me
solo perchè svolgeva il suo compito in modo non ottimale.


> Un'altra info: Motif cosč? Un OS? una UI?
In pratica, le MFC sotto unix (meglio: sotto X window).
--
Alessandro Monti

 Un'altra info: Motif cosè? Un OS? una UI?
  Motif e` un'insieme di librerie per sviluppare interfacce grafiche
sopra l'X Toolkit. probabilmente, se hai mai visto X su una UNIX box
diversa da Linux, hai visto anche Motif. ;)
	Alla prossima,
		Marco


In pratica, le MFC sotto unix (meglio: sotto X window).
Grazie per l'informazione.


diversa da Linux, hai visto anche Motif. ;)
Purtroppo fino ad oggi ho avuto il piacere di vedere solo l'X del Linux.
Comunque ho capito cosa č Motif. Grazie per l'info.


you wrote :
#Dobbiamo capire su cosa stiamo dibattendo. Se parliamo di idee, di
#algoritmi, di soluzioni o di patterns anche io penso che debbano essere
#portabili, senza riferimento a piattaforma alcuna. Ma se parliamo di codice
#allora dico che è IMPOSSIBILE scrivere qualcosa di portabile tra le varie
#piattaforme.
Questo e' un altro discorso e comunque non e' generalmente vero.
#include <stdio.h>
int main()
{
   int c ;
   while ( (c = getchar()) != EOF ) 
         putchar(c) ;
 
   return 0 ;
}
Un semplice filtro di input su output, portabile al 100% ;)


you wrote :
#Non credo alla portabilità. Non è possibile scrivere codice portabile che
#serva realmente a qualcosa o che sia efficiente. E' per questo che me ne
#infischio dello standard.
Non e' vero.
Pensi questo perche' evidentemente non hai mai scritto software che
necessitasse di essere trasportato da una piattaforma all'altra o
sottoposto a piu' compilatori.
La portabilita' dei programmi ha una grossa importanza ed il fatto che
si usino per la maggior parte le estensioni del proprio compilatore
(cosa che si *deve* fare per sviluppare qualcosa che sfrutti al meglio
la propria piattaforma) non significa che si possa ignorare lo
standard del linguaggio.
La buona programmazione vuole che si mantenga la maggior parte del
codice il piu' portabile possibile, relegando le funzioni particolari
del compilatore a quella parte del codice imprescindibile dalla
piattaforma di destinazione.
E questo non solo perche' un giorno il tuo programma potra' girare con
*poche* modifiche su altre piattaforme, ma anche perche' potrebbe
essere piu' digeribile per un eventuale compilatore che ti piacesse
piu' di quello che utilizzi gia'.
Non e' raro, tra l'altro, specialmente adesso che c'e' internet, che
si trovi del codice scritto da altre persone che si voglia
adattare/ricompilare col proprio compilatore.
Quello che non si comprende e' che la portabilita' influenza lo
sviluppo del *cuore* del codice e non della sua, per cosi' dire,
*periferia*.


 del Linux.
  Mmhmm... Hai visto "Jurassik Park"? Oppure uno dei tanti servizi del
telegiornale sulla crisi della Telecom? Tutte quelle belle macchinine
con schermi da 21" sono SGI o Sun (nei casi piu` disperati HP), con
Motif sopra. :)
	Alla prossima,
		Marco

*periferia*.
Ma io non posso separare le parti di codice portabili da quelle non
portabili!!!!!! Come faccio???


Motif sopra. :)
Beeeeeellooooooooo :-)


Un semplice filtro di input su output, portabile al 100% ;)
Allora preciso la mia affermazione: ".....Ma se parliamo di codice allora
dico che è IMPOSSIBILE scrivere qualcosa di portabile tra le varie
piattaforme _che faccia qualcosa di realmente utile._"
Il tuo programma sarà portabile al 200%, ma nella vita reale (fatta di
interface grafiche) non posso presentare un programma testuale dicendo "Ma
io volevo scrivere del codice portabile....". La cosa più bella che potrebbe
capitarmi è ricevere uno sputo in faccia........


capitarmi è ricevere uno sputo in faccia........
... oppure un ringraziamento perchè il tuo programma è estremamente
leggero e non ha bisogno di un hardware molto recente. Ho cominciato a
usare Linux e a smacchinare tra i file di configurazione (con vi o
vim, che sono editor testuali), ed è molto più gratificante che i
pulsantini tuttofare (o nullafare, questione di punti di vista) di
win, che a lungo andare rincretiniscono.
Credo che per molte cose, tipo un mail-reader o un news-reader. la
grafica sia superflua, perchè devi solo leggere testi. Per altre cose
può essere utile.


 caso di porting, apportare modifiche sostanziali al codice....
Se i programmatori di sistema si preoccupassero degli standard (loro sì,
dovrebbero), ti basterebbe qualche #ifdef qua e là nel codice.
Poichè invece contano di più le fidelizzazioni, ti dò (parzialmente)
ragione.
Da notare che un framework come MFC dovrebbe avere come uno dei compiti
principali proprio quello di aumentare la standardizzazione tra i sistemi,
dato che comunque, a livello di risultati pratici, non differisce molto dai
vari Motif et similia.
Usare la stessa struttura di base e le stesse funzioni sarebbe costato poco.
Se il problema erano le royalties, MS avrebbe potuto aquisire i proprietari
o fare un accordo di qualche tipo, come ha fatto per tante altre cose
(sistema multitasking compreso). A mio parere c'era proprio la volontà
opposta.
Separare la parte "businness" dall'interfaccia utente per quanto possibile,
comunque, era già consigliabile con le interfacce basate sul testo, a costo
di passare qualche variabile in più alle funzioni.
Ciò non vuole dire diventare matti per aumentare la portabilità, ma almeno
tenerla in mente, e semmai rifiutarla se prorpio si ritiene troppo
complicato per il progetto in corso.
P.S.
A furia di indentare le risposte alle risposte, ecc. questo thread sta
superando la capacità del mio schermo.
--
Alessandro Monti

 superando la capacità del mio schermo.
[...]
Non dirlo a me che ho un 640x480 :-(
-- 
 Ciao, Luca.
 Reply to 
luca....@tiscalinet.it
 UIN : 43385135

può essere utile.
Qui non sono d'accordo. Secondo me un SO multitasking DEVE possedere
un'interfaccia grafica, sennò come fa a permette l'output contemporaneo
delle varie applicazioni?
Linux si salva perchè dà la possibilità di utilizzare dei terminali virtuali
multipli (ALT + Fx), altrimenti....


superando la capacità del mio schermo.
A me è già uscito dallo schermo da un pezzo :-).


you wrote :
#Il tuo programma sarà portabile al 200%, ma nella vita reale (fatta di
#interface grafiche) 
La vita reale non e' fatta di interfacce grafiche ma di algoritmi che
risolvano problemi.
Ti ricordo che gran parte dei filtri di supporto in ambiente Unix sono
scritti adoperando lo stesso principio del programmino di esempio.


 scritti adoperando lo stesso principio del programmino di esempio.
Gią, ma ti immagini un'impiegato che adopera un "filtro di Unix" al
posto di Word? Io no...
EMG

scritti adoperando lo stesso principio del programmino di esempio.
Nessuno ha detto che lo standard non sia potente abbastanza per gestire
anche i filtri di supporto sotto Unix. E' che scarseggia nell'output (sia a
video che in altre forme)...


Dura realtà!
E che ne diresti di separare (in fase di design e nel codice) la parte
che risolve il problema da quella che presenta i risultati?
La prima e' sicuramente piu' facile da realizzare secondo lo standard
e renderla portabile.
In questo modo dovrai riscrivere solo la parte di interfaccia in caso
di porting.
Andrea Polci
apo...@geocities.com

 e renderla portabile.
Non sempre. Se voglio qualcosa di performante devo ricorrere ai servizi del
sistema operativo, non posso adattarmi con le funzioni standard.


 sistema operativo, non posso adattarmi con le funzioni standard.
Uhm... nella mia esperianza ho visto che normalmente i servizi del
sistema operativo sono tutt'altro che performanti...
EMG

portabili!!!!!! Come faccio???
Hai sostenuto (correggimi se sbaglio) che la parte non portabile di un
programma è principalmente l'interfaccia. Posso essere daccordo con te
(anche se utilizzando opportune librerie... ma tu non vuoi rinunciare
alle prestazioni).
Allora e' una buona norma (e non per la portabilita') separare
l'interfaccia dal resto del programma.
Se non fai questo, significa che realizzi solo applicativi di
complessita' molto bassa che ti permettono di mantenere il controllo
di cio' che stai facendo.
Anche se ci sono altre parti di un applicativo che possono non essere
rese portabili, dovrebbe essere comunque possibile separarle dal resto
senza grandi perdite di prestazioni (salvo casi particolari), al costo
di un aumento del tempo da dedicare alla fase di design.
Naturalmente questo e' solo IMHO.
Andrea Polci
apo...@geocities.com

 sistema operativo sono tutt'altro che performanti...
Ma, proprio perchè non sono performanti, una cosa è chiamare un solo
servizio e un'altra cosa è chiamare una funzione standard che per svolgere
il suo compito deve chiamare svariate API......


 di un aumento del tempo da dedicare alla fase di design.
Fosse solo quello......


eccome, e inoltre diminuisce di molto la leggibilità.
Ho dei dubbi che in un programma fatto bene le prestazioni diminuirebbero in 
modo significativo, invece sono certo che la leggibilita' ne guadagnerebbe 
alquanto. In ogni caso se lo scopo e' quello di aumentare la portabilita' del 
programma o di parte di esso (non solo tra varie piattaforme ma anche tra 
diversi progetti) magari qualche concessione bisogna farla, eh!

 diversi progetti) magari qualche concessione bisogna farla, eh!
E' questo che io non riesco a fare (non ho la forza di farlo): perdere
prestazioni per far posto alla portabilità.


prestazioni per far posto alla portabilità.
Ho tagliato la parte precedente che rischiava di diventare troppo off-topic... 
Ma sei SICURO che la perdita di prestazioni sia significativa? Magari potresti 
realizzare qualche piccolo prototipo e sperimentare delle soluzioni 
alternative. In ogni caso prendi la decisione che ritieni migliore e procedi 
di conseguenza: che sia giusta o sbagliata avrai comunque fatto esperienza ed 
imparato qualcosa. A volte si perde piu' tempo ad iper-analizzare il problema 
di quanto ce ne vorrebbe ad implementare entrambe le possibilita' (e chissa' 
che non ci sia una via di mezzo?).
Ciao

 che non ci sia una via di mezzo?).
Purtroppo solo a volte. Con progetti di grosse dimensioni ciò che tu proponi
non è per nulla applicabile.


 non č per nulla applicabile.
A me sembra che proprio nei progetti di grosse dimensioni queste
tecniche diventino indispensabili, pena il loro inevitabile collasso.
EMG

 tecniche diventino indispensabili, pena il loro inevitabile collasso.
Implementere tutto il progetto in modi diversi piuttosto che analizzare un
pò meglio i problema è una tecnica indispensabile?


 pò meglio i problema è una tecnica indispensabile?
Non ti seguo. Cosa intendi dire?
EMG

 Non ti seguo. Cosa intendi dire?
Voglio dire che secondo me è preferibile analizzare un pò meglio il problema
che si sta affrontando e decidere a priori che codice scrivere (che
algoritmo utilizzare magari) che scrivere più versioni dello stesso codice
per valutare dopo dei test sulle performance quale utilizzare.
