MasterDrive.it   
Vai indietro   MasterDrive.it > Software Development > C/C++



Rispondi
 
Strumenti della discussione Modalità di visualizzazione
Vecchio 17-03-2010, 10:43   #1 (permalink)
Neofita della community

 
68 Messaggi

musiclover85 novizio della comunita' ( + 10 )
Question [C] Visualizzare nome variabile in output

ciao a tutti!
è possibile visualizzare in output (con printf o altri metodi) il nome di una variabile invece del valore?
mi spiego meglio: ho una serie di costanti definite con define, prendo in input un valore, faccio uno switch del valore per confrontarlo con le costanti e per conferma vorrei visualizzare il nome del comando inviato (nome costante).
del tipo:

codice:
......
scanf("%x",&op_scelta);
switch(op_scelta){
    case variabile1: {
          printf("Comando inviato: variabile1\n");
          break;}
    case variabile2: {
          printf("Comando inviato: variabile2\n");
          break;}
    case variabile3: {
          printf("Comando inviato: variabile3\n");
          break;}
}
.........
ovviamente in modo dinamico.

musiclover85 non è in linea   Bookmark and Share Rispondi quotando
Vecchio 17-03-2010, 13:29   #2 (permalink)
Neofita della community

 
130 Messaggi

neobaumuth novizio della comunita' ( + 10 )
Be' se conosci quello che hai inviato, inseriscilo in stringa!
__________________
"Fatti non foste per viver come bruti, ma per seguire virtute e conoscenza."
"Hack to learn, not to steal."
"In un mondo di ciechi, chi ha un occhio solo è un Re"
neobaumuth non è in linea   Bookmark and Share Rispondi quotando
Vecchio 17-03-2010, 15:43   #3 (permalink)
Neofita della community

 
68 Messaggi

musiclover85 novizio della comunita' ( + 10 )
il problema è che ho tantissimi define, vorrei evitare di aggiungere una printf per ogni caso dello switch.
nessuna idea?
musiclover85 non è in linea   Bookmark and Share Rispondi quotando
Vecchio 17-03-2010, 17:38   #4 (permalink)
Moderatore Globale

 L'avatar di M.A.W. 1968

 
371 Messaggi

M.A.W. 1968 e' una persona affidabile ( + 250 )M.A.W. 1968 e' una persona affidabile ( + 250 )M.A.W. 1968 e' una persona affidabile ( + 250 )M.A.W. 1968 e' una persona affidabile ( + 250 )
Dovrai realizzare, come nei programmi "veri", un dizionario di simboli. La cosa è ancora a livello di esercizio in questo caso, avendo semplicemente un elenco di pseudocostanti manifeste rigorosamente definite a compile time; pertanto la struttura dati è realizzabile come un banalissimo array statico di strutture, popolato manualmente in modo da mantenerne l'ordine (per fissare le idee, in ordine crescente di valore del "comando"), potendo così utilizzare una semplice ricerca binaria in fase di estrazione dei dati.

Il che, per inciso, spazza via definitivamente quella bruttura concettuale della switch utilizzata come euristica ad hoc ed appesantita da una printf() per ciascun caso.

EDIT: Esempiuccio di codice, minimamente commentato.
Non conoscendo il tuo livello di preparazione, ho mantenuto la massima semplicità possibile.
E' pressoché inutile aggiungere che, se i valori dei "comandi" non sono discontinui e arbitrari ma sono dei piccoli interi appartenenti ad un singolo intervallo contiguo (es. da uno a dieci...), viene meno la necessità stessa di una struttura e della bsearch() e il tutto si riduce, banalissimamente, all'uso di un array di stringhe contenenti la descrizione di ciascun "comando" associata posizionalmente al valore medesimo.

codice:
#include <stdio.h>
#include <stdlib.h>

#define CMD_LEN 16
#define CMD_NUM 9

/* Valori numerici dei codici comando */
typedef enum {
    CMD1 = 0x10,
    CMD2 = 23,
    CMD3 = 30,
    CMD4 = 0x23,
    CMD5 = 59,
    CMD6 = 61,
    CMD7 = 77,
    CMD8 = 81,
    CMD9 = 90
} cmd_t;

/* Struttura core del dizionario */
typedef struct
{
    cmd_t cmd;
    char desc[CMD_LEN];
} Cmd_dict_t;

/* Il dizionario vero e proprio, implementato tramite un array statico */
Cmd_dict_t SysCommands[CMD_NUM] = {
    { CMD1, "Comando1" },
    { CMD2, "Comando2" },
    { CMD3, "Comando3" },
    { CMD4, "Comando4" },
    { CMD5, "Comando5" },
    { CMD6, "Comando6" },
    { CMD7, "Comando7" },
    { CMD8, "Comando8" },
    { CMD9, "Comando9" }};

/* Semplifica la dichiarazione della UDF per la ricerca binaria */
typedef int (*fptr)(const void*, const void*);

/* La UDF di confronto usata dalla bsearch() */
int dict_cmp(const cmd_t *p1, const Cmd_dict_t *p2)
{
    return ((int) * p1 - p2->cmd);
}

/* Funzione che restituisce la posizione di un comando nel dizionario (o -1) */
int CmdLookup(cmd_t c)
{
    Cmd_dict_t *iptr;

    iptr = (Cmd_dict_t *)bsearch(&c, SysCommands, CMD_NUM, sizeof(Cmd_dict_t), (fptr)dict_cmp);

    return (NULL != iptr ? (iptr - SysCommands) : -1);
}

int main(void)
{
    cmd_t TestVec[CMD_NUM] = {CMD8, CMD6, CMD4, CMD2, CMD1, CMD3, CMD5, CMD7, CMD9};

    int i, pos;

    for( i = 0; i < CMD_NUM; i++ )
    {
        pos = CmdLookup(TestVec[i]);

        if (-1 != pos)
        {
            printf("Invio comando %02d: %s\n", SysCommands[pos].cmd, SysCommands[pos].desc);
        }
    }

    return (EXIT_SUCCESS);
}
__________________
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...

• "Die ganzen Zahlen hat der liebe Gott gemacht, alles andere ist Menschenwerk." (Leopold Kronecker)
• "A Mathematician is a machine for turning coffee into theorems." (Pal Erdös)
• Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

Ultima modifica di M.A.W. 1968 : 17-03-2010 a 18:29.
M.A.W. 1968 non è in linea   Bookmark and Share Rispondi quotando
Vecchio 17-03-2010, 21:17   #5 (permalink)
Neofita della community

 
68 Messaggi

musiclover85 novizio della comunita' ( + 10 )
ottima spiegazione..grazie..appena posso la testo..
quello che volevo evitare è proprio lo switch..
in realtà sono più esperto di visual basic..ma sono costretto ad usare il c per questo progetto.
dato che ho trovato un vero esperto magari potrei avere buoni consigli..visto che sono ancora nella fase iniziale..
questo è in breve il progetto:
nella mia azienda di progettazioni e costruzioni elettroniche abbiamo deciso di integrare nei nostri prodotti un lettore di impronte digitali. ciò che vogliamo ottenere è un'interfaccia tra il lettore e il pc, collegati tramite porta seriale. per ora sto studiando il dispositivo cercando di inviare comandi (un array di byte) e visualizzare la risposta (formattata in modo specifico).
nel datasheet mi sono stati forniti i valori in byte dei comandi, dei responsi, degli errori e dei log. essendo un'enormità di costanti, quando formatto e visualizzo la risposta a video mi farebbe comodo visualizzare il nome della costante, più che il relativo valore.
la tua soluzione mi è comunque utilissima in ogni caso!
ora, per ogni comando devo chiamare una funzione: nella struct che hai proposto si può inserire il nome di una funzione da richiamare?
mi spiego meglio: in javascript c'è la possibilità di passare come parametro il nome di una funzione in formato stringa a un'altra funzione e farla eseguire.
in questo contesto si può?
musiclover85 non è in linea   Bookmark and Share Rispondi quotando
Vecchio 18-03-2010, 01:03   #6 (permalink)
Moderatore Globale

 L'avatar di M.A.W. 1968

 
371 Messaggi

M.A.W. 1968 e' una persona affidabile ( + 250 )M.A.W. 1968 e' una persona affidabile ( + 250 )M.A.W. 1968 e' una persona affidabile ( + 250 )M.A.W. 1968 e' una persona affidabile ( + 250 )
Quando si programma in linguaggio C proveniendo da altri linguaggi e ambienti di alto livello, il primo presupposto da apprendere è che in C si può fare praticamente qualunque cosa consentita dal calcolatore, poiché tale linguaggio è in pratica solo un macroassembler molto evoluto, e rappresenta di fatto il più low level tra i linguaggi di alto livello.

Si tratta, di norma, solo di individuare la sintassi corretta (il che spesso non è banale).

In questo caso, richiamare funzioni arbitrarie scritte dall'utente è un'operazione implementata tramite puntatori a funzione, che hai già visto all'opera nell'esempio precedente, entro la chiamata a bsearch(): la chiamata (fptr)dict_cmp sfrutta infatti un puntatore a funzione, sebbene reso meno evidente dal cast (fptr).

Tali puntatori a funzione possono tranquillamente essere memorizzati in array, strutture, e più in generale possono essere sottoposti a tutte le operazioni valide per qualsiasi altro puntatore, ivi inclusa l'aritmetica dei puntatori.

Naturalmente tutta questa potenza ha un prezzo: tramite un puntatore a funzione, imbizzarrito o artatamente modificato, si può letteralmente mandare in esecuzione qualsiasi sequenza binaria entro lo spazio di indirizzamento logico dell'applicazione...

Per gestire tabelle di puntatori a funzioni, inoltre, occorre progettare in modo omogeneo e coerente il passaggio di parametri e la restituzione di valori, per evitare di perdersi in contorsioni sintattiche e cast che diventano rapidamente illeggibili, come d'altro canto suggerisce anche la #define (fptr) sopra indicata per la UDF di ricerca, e come ancor meglio esplicita questo famosissimo esempio del K&R (la "bibbia" del linguaggio C):
codice:
char (*(*x())[])()
/* 
** x è una funzione che restituisce un puntatore ad un vettore 
** di puntatori a funzioni che restituiscono un char... 
*/
In questo post, in particolare, ho suggerito alcune delle idee più solide e radicate del software engineering in C per l'uso di pool di puntatori a funzioni.


Occupandomi a livello hardware, firmware e software di sistemi di misura e controllo embedded da oltre un quarto di secolo, aggiungo inoltre che lavorare con device seriali, di qualsivoglia natura (ivi incluse molte "moderne" periferiche USB) di norma richiede l'uso di un monitor seriale: applicazione di alto costo se implementata con un normale strumento, ma di fatto si tratta di uno dei primissimi software che hanno promosso e consentito impieghi dei calcolatori in laboratorio, fin dagli esordi dei PET.

Esistono molte ottime soluzioni, ecco qui alcuni esempi in ordine alfabetico:

- Adontec SuperMonitor
- Agg Advanced Serial Port Monitor & Data Logger
- Docklight Scripting
- Frontline Serial Monitor
- HHD Serial Monitor
- fCoder LookRS232
- PTronix SimpleTerm Gold
- Realtime Control ComLite32 (dead link)

L'uso di una di queste applicazioni, specialmente quelle che supportano lo scripting e il riconoscimento di protocolli/sequenze con plugin e DLL utente, renderà sicure e veloci tutte le fasi di implementazione del device esterno, integrandosi al meglo con l'applicazione C in corso di sviluppo.
__________________
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...

• "Die ganzen Zahlen hat der liebe Gott gemacht, alles andere ist Menschenwerk." (Leopold Kronecker)
• "A Mathematician is a machine for turning coffee into theorems." (Pal Erdös)
• Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

Ultima modifica di M.A.W. 1968 : 18-03-2010 a 02:30. Motivo: Individuato e rimosso dead link
M.A.W. 1968 non è in linea   Bookmark and Share Rispondi quotando
Vecchio 18-03-2010, 09:18   #7 (permalink)
Neofita della community

 
130 Messaggi

neobaumuth novizio della comunita' ( + 10 )
Tempo fa mi cimentai anch'io (in collaborazione con un mio amico più esperto di me) nella realizzazione di una serratura per cassaforte che utilizzasse le impronte digitali come combinazione. Io non ho sorgenti, perchè il progetto è stato momentaneamente sospeso per mancanza di tempo e fondi, ma ricordo che assieme al lettore di impronte vero e proprio ci era stata fornita dalla ditta costruttrice una libreria C molto vasta e ricca di funzioni adatte ad ogni scopo, in modo da evitare uno studio troppo approfondito di un hardware che ti veniva fornito con un suo micro e firmware di interfaccia. Lavoìravamo su schede di nostra produzione con ATMega128, ma questo comporta solo una differenza nel compilatore, quindi può essere che esistano librerie per il lettore che utilizzi tu. Prova a dare un occhio sul sito del produttore.

PS: Tra MAW e Bottomap, di più esperti e disponibili non ne puoi trovare.
__________________
"Fatti non foste per viver come bruti, ma per seguire virtute e conoscenza."
"Hack to learn, not to steal."
"In un mondo di ciechi, chi ha un occhio solo è un Re"
neobaumuth non è in linea   Bookmark and Share Rispondi quotando
Vecchio 18-03-2010, 13:33   #8 (permalink)
Neofita della community

 
68 Messaggi

musiclover85 novizio della comunita' ( + 10 )
di MAW me ne sono reso conto
di Bottomap non ho avuto ancora occasione..essendo da poco frequentante del forum..
abbiamo ordinato dal produttore un evaluation kit e ci hanno mandato tutto il materiale possibile, per cui evidentemente non hanno librerie già pronte in c, ci hanno dato solo un datasheet con il formato dei dati e altre info, il resto spetta a noi.

@MAW sto provando il tuo codice..ottimo!
sto cercando di integrare anche i puntatori a funzione proprio ora, però mi sorge una domanda (non badare alla semplicità..sto solo testando ):

per fare qualche prova ho modificato la struct in

codice:
typedef struct
{
    cmd_t cmd;
    char desc[CMD_LEN];
    void (*fptr1);
    int (*fptr2);
} Cmd_dict_t;
per se richiamo le funzioni puntate:

codice:
....
int j=0;

void ciao(){
    j++;
}

int ciao2(){
    return j;
}
....
Cmd_dict_t SysCommands[CMD_NUM] = {
    { CMD1, "Comando1", ciao },
    { CMD2, "Comando2", ciao2 },
.......
void main(){
...
SysCommands[pos].fptr1;
printf("%d",j);
printf("%d",SysCommands[pos].fptr2);
...
}
non riesco a cambiare il valore di j..sbaglio qualcosa?

Ultima modifica di musiclover85 : 18-03-2010 a 14:39.
musiclover85 non è in linea   Bookmark and Share Rispondi quotando
Vecchio 18-03-2010, 15:34   #9 (permalink)
Neofita della community

 
68 Messaggi

musiclover85 novizio della comunita' ( + 10 )
come non detto..un errore di distrazione..avevo omesso le parentesi quando richiamavo la funzione tramite puntatore..
più o meno sto entrando nella mentalità dei puntatori a funzione..
grazie!!
musiclover85 non è in linea   Bookmark and Share Rispondi quotando
Rispondi

Strumenti della discussione
Modalità di visualizzazione

Regole d'invio
Non puoi inserire discussioni
Non puoi inserire repliche
Non puoi inserire allegati
Non puoi modificare i tuoi messaggi

BB code è attivo
Le smilies sono attive
Il codice IMG è attivo
il codice HTML è disattivato
Trackbacks are attivo
Pingbacks are attivo
Refbacks are disattivato

Salto del forum


Tutti gli orari sono GMT +2. Attualmente sono le 09:46.


Powered by vBulletin versione 3.8.0
Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.2.0

Valid XHTML 1.0 Transitional  Creative Commons License

Eccetto dove diversamente specificato, i contenuti pubblicati in questa comunità sono rilasciati sotto Licenza
Creative Commons Attribuzione-Non commerciale-Condividi allo stesso modo 2.5 Italia License.
La comunita' di MasterDrive.it non e' responsabile di eventuali imprecisioni presenti nelle pagine.