+ Rispondi al Thread
Visualizzazione dei risultati da 1 a 7 su 7

Discussione: C - Switch con dati di tipo diverso da int

  1. #1
    simonesalerno non è in linea Novello
    Post
    46

    C - Switch con dati di tipo diverso da int

    Salve a tutti, ho appena iniziato a programmare in C e ho trovato questa difficoltà: ho provato a usare lo switch con un array di tipo char e mi da' errore; questa cosa mi coglie abbastanza impreparato perchè in altri linguaggi me lo lasciava fare: come faccio ad aggirare il problema? Posto un esempio di programmino che dovrebbe leggere la sigla di un elemento chimico e restituirne il nome (che non funziona):
    codice:
    #include <stdio.h>
    
    int main (int argc, const char * argv[]) {
    	
    	char el[2];
    	char nome[] = "";
    	int i;
    	
    	printf("Digita sigla elemento:");
    	//acquisisci sigla elemento
    	for (i = 1; i < 3; i++)
    		scanf("&c", el[i-1]);
    	//riconosci sigla
    	switch (el)
    	{
    		case "Fe": 
    			nome = "Ferro"; break;
    		case "Mg": 
    			nome = "Magnesio"; break;
    	}
    	//scrivi nome elemento
    	printf("Elemento: &c \n", nome);
    	
        
    	    return 0;
    }
    Grazie in anticipo per l'aiuto.

  2. #2
    Luogo
    Granducato di Toscana
    Post
    836
    Blogs
    51
    Per definizione, il costrutto switch() richiede una variabile intera, con o senza segno. Un char è un piccolo intero, dunque rientra nella definizione. Un array di char, invece, non è affatto intercambiabile con un char: in particolare, il nome dell'array (utilizzato senza subscritti, ossia privo di indici tra parentesi quadre) coincide sintatticamente con un puntatore immodificabile al primo elemento dell'array stesso, ovvero un puntatore a char. Ergo, nessun compilatore C progettato da individui mentalmente sani può e deve accettare una sintassi come quella proposta. Ecco infatti l'output prodotto dal tentativo di compilazione col solito Borland 5.5.1:

    codice:
    Z:\>compile switch.c
    Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
    switch.c:
    Error E2383 switch.c 14: Switch selection expression must be of 
    integral type in function main
    Error E2313 switch.c 16: Constant expression required in function main
    Error E2277 switch.c 17: Lvalue required in function main
    Error E2313 switch.c 18: Constant expression required in function main
    Error E2172 switch.c 18: Duplicate case in function main
    Error E2188 switch.c 19: Expression syntax in function main
    Warning W8057 switch.c 26: Parameter 'argc' is never used in function main
    Warning W8057 switch.c 26: Parameter 'argv' is never used in function main
    *** 6 errors in Compile ***
    
    Z:\>
    Contrariamente ad altri linguaggi HLL, in C non esistono le stringhe come tipo di base. Un confronto tra due stringhe (array di char con terminatore nullo) richiede obbligatoriamente l'uso di funzioni apposite, come strcmp().

    Inoltre l'uso di scanf() è deprecato per numerosi motivi e va evitato totalmente: nel caso specifico, è altamente consigliato utilizzare fgets().

    Domanda di prammatica: su quale manuale stai studiando il linguaggio C?
    Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo.

    Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo... già che ci siete, leggete questa selezione di parole famose di alcuni tra i più grandi geni.

    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  3. #3
    simonesalerno non è in linea Novello
    Post
    46
    Mi serviva solo sapere l'alternativa allo switch con le stringhe........ sono ancora all'inizio e non conoscevo la funzione strcmp(). Vuol dire che, prima di realizzare anche programmini che ritenevo scemi, andrò avanti con lo studio.... Grazie mille per la risposta.

  4. #4
    Rups non è in linea Scolaretto
    Post
    190
    Quote Originariamente inviato da simonesalerno Visualizza il messaggio
    Mi serviva solo sapere l'alternativa allo switch con le stringhe........ sono ancora all'inizio e non conoscevo la funzione strcmp(). Vuol dire che, prima di realizzare anche programmini che ritenevo scemi, andrò avanti con lo studio.... Grazie mille per la risposta.
    Ciao sinceramente in questo caso proverei a realizzare lo switch solo dato di el e poi eventualmente anniderei o più if o altri switch sul secondo e sul terzo( ununtrio "Uut") , lo so non è una bella cosa ma già deve essere un lavoro da monaco certosino implementare tutti i 118 elementi

    Di seguito un piccolo esempio

    codice:
    #include <stdio.h>
    
    int main (int argc, const char * argv[]) {
    	
    	char el[2];
    	char *nome;
    	int i;
    	
    	printf("Digita sigla elemento:");
    	//acquisisci sigla elemento
    	for (i = 1; i < 3; i++)
    		scanf("%c", &el[i-1]);
    	//riconosci sigla
    	switch (el[0])
    	{
    		case 'F':
    			nome = "Ferro"; break;
    		case 'M': 
    			nome = "Magnesio"; break;
    	}
    	//scrivi nome elemento
    	printf("Elemento: %s \n", nome);
    	
    	    return 0;
    }
    Saluti

  5. #5
    L'avatar di glasgo
    glasgo non è in linea Novello
    Post
    1
    Inoltre l'uso di scanf() è deprecato per numerosi motivi e va evitato totalmente: nel caso specifico, è altamente consigliato utilizzare fgets().

    Domanda di prammatica: su quale manuale stai studiando il linguaggio C?
    scusami m.a.w, anche se non è proprio il tema della discussione vorrei avere dei chiarimenti, su questa cosa. e credo possano essere utili anche ad altre persone.
    i numeri motivi per cui l'uso di scanf() è deprecato e va evitato sono legati alla lettura di stringhe o alla lettura di dati in generale?
    perché nel secondo caso sarebbe una rivelazione shock!

    (sui due libri che sto studiando la scanf viene usata regolarmente. e i libri sono 'linguaggio c III edizione' della mcgraw-hill e il kerninghan)

  6. #6
    Luogo
    Granducato di Toscana
    Post
    836
    Blogs
    51
    Quote Originariamente inviato da glasgo Visualizza il messaggio
    i numeri motivi per cui l'uso di scanf() è deprecato e va evitato sono legati alla lettura di stringhe o alla lettura di dati in generale?
    La scanf(), in generale, va evitata per i medesimi motivi prestazionali della printf(). Si tratta di funzioni lente, complesse, ingombranti, piene di euristiche, poco flessibili nel gestire eccezioni, prone ad indurre errori di difficile tracciabilità - specialmente nel caso di stringhe formato complesse e inusuali.

    Principio guida: laddove possibile, si impieghino sempre le funzioni di I/O inerentemente più semplici (ad esempio sprintf() + puts() in luogo di printf(), fgets() + sscanf() in luogo di scanf() o fscanf()); in linea di principio, si può e si deve usare solamente la loro versione s*() per operare rigorosamente su un buffer intermedio, che a sua volta sarà rispettivamente acquisito in input o emesso in output con le funzioni elementari. Ciò conferisce massimo controllo, migliora la leggibilità, e nella stragrande maggioranza dei casi aumenta misurabilmente anche le prestazioni a livello di throughput.

    Ovviamente il K&R è mondo da qualsivoglia peccato, per definizione dogmatica, trattandosi del Testo Sacro scritto direttamente dagli autori del linguaggio, che si situa eo ipso al di là del Bene e del Male...
    Tuttavia, per quanto fedele oltre ogni dire alle idee ed ai concetti che hanno ispirato la creazione stessa del linguaggio, il K&R rimane solo un viatico iniziale, poiché da lì in poi ben altri sono i testi (e i sorgenti) che insegnano realmente a programmare professionalmente in C in modo efficace ed efficiente in ambienti elaborativi di normale diffusione, usando implementazioni di compilatori commerciali, librerie standard e di runtime con i loro noti pregi e difetti.

    Non stupisce invece che innumerevoli testi postumi, anche di vasta diffusione, contengano pessimi esempi di programmazione, con la parziale giustificazione della generale sbrigatività degli idiomi risultanti dall'uso di funzioni deprecate.

    La fonte di Verità riguardo all'uso più ortodosso del linguaggio C in ambienti produttivi reali sono però i vari testi elencati in questa bibliografia, e in particolare [4], [5], [6] e [8]: testi scritti da autori che - come il sottoscritto - si sono trovati ad implementare compilatori C e relative librerie per le più varie piattaforme, avendo giocoforza studiato le varie implementazioni di libreria esistenti e venendo quindi a contatto con gli orrori e gli scheletri nell'armadio nascosti in certune funzioni che troppi (anche su carta stampata) tendono ad usare in modo superficiale e poco meditato.


    PS: Riguardo al thread, la soluzione più elementare (con gli effetti collaterali di essere generalmente ottima in tempo di esecuzione, e di stimolare ad acquisire la giusta forma mentis informatica) consta nell'uso di una tabella di lookup: in particolare, una matrice costante di 26 righe per 27 colonne, per fissare le idee, alle cui celle corrisponda un indice zero-based all'interno di un secondo array costante di stringhe, contenente il nome dell'elemento.
    Per convenzione la colonna 0 conterrà i puntatori agli elementi con simbolo di una sola lettera, il che richiede banalmente una inizializzazione convenzionale del buffer di input, e in particolare del suo secondo elemento.

    Gli elementi non rilevanti della matrice costante saranno tutti inizializzati con un indice speciale (i.e. nullo) che corrisponde nell'array dei nomi alla stringa di errore "Elemento inesistente" o simili. In questo modo, le celle significative conterranno un indice che può tranquillamente coincidere col numero atomico dell'elemento in questione, per fissare le idee (in questo caso non si ha necessità di far funzionare bidirezionalmente o ortogonalmente il lookup, ad esempio ordinando alfabeticamente l'array dei nomi, ma è sufficientemente ovvio quanto sia banale farlo).

    Tale struttura, se utilizzata in modo minimamente scaltro, consente di indirizzare ogni elemento in O(1) conoscendone la singola lettera o le due lettere del simbolo chimico, con una banale operazione aritmetica, eliminando del tutto il ricorso a qualsiasi struttura di controllo o funzione di libreria. Un guadagno enorme in termini concettuali e di complessità.
    L'unica banale euristica necessaria consiste, in questo caso, nel gestire separatamente la manciata di elementi sintetici transuranici contrassegnati da simbolo di tre lettere.

    Per ottimizzare invece l'occupazione di memoria, si può ricorrere ad un approccio non dissimile, ma leggermente più raffinato, che probabilmente non è neppure il caso di accennare qui.

    Quasi inutile aggiungere che le tabelle di lookup, assieme ai sistemi di hashing, sono un ingrediente essenziale in qualsiasi progetto informatico: dallo sviluppo dei microprocessori ai linguaggi di più alto livello, è pressoché impossibile trovare un progetto di normale complessità che non ne faccia uso.
    Ultima modifica di M.A.W. 1968; 09-06-2011 00:33  Motivo: Fixed typos
    Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo.

    Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo... già che ci siete, leggete questa selezione di parole famose di alcuni tra i più grandi geni.

    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  7. #7
    Luogo
    Granducato di Toscana
    Post
    836
    Blogs
    51
    Aggiorno il thread per segnalare che l'argomento ha avuto l'onore di qualche ulteriore minuto della mia attenzione, da cui è scaturita (al momento) una blog entry...
    Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo.

    Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo... già che ci siete, leggete questa selezione di parole famose di alcuni tra i più grandi geni.

    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

+ Rispondi al Thread

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi