Domanda

ho una funzione come

void printMe (void *i)
{
    printf("%d", i);
}

dove voglio passare un puntatore vuoto e stamparlo sullo schermo. L'esempio sopra va bene se i è intero, float o double ma si arresta in modo anomalo se i è un carattere. Non c'è sovraccarico in C come di solito uso in C ++. Quindi la domanda è questa, possiamo creare una funzione in C che stamperà l'elemento che è il suo parametro, e se sì come è possibile perché mi sfugge totalmente in questo momento.

È stato utile?

Soluzione

Q1: Quindi la domanda è questa, possiamo creare una funzione in C che stamperà l'elemento che è il suo parametro

A: Non nel modo desiderato. Dovrai passare informazioni alla funzione, indicandole il tipo di dati che stai trasmettendo.

Q2: e se sì come è possibile perché mi sfugge totalmente in questo momento.

A: Ti sta sfuggendo perché non può essere fatto. Non ci sono metadati associati a un vuoto * che il compilatore o il runtime possono usare per capire a quale digitazione punta. Devi

  1. passa una struttura che contiene una
    puntatore e informazioni su cosa
    il puntatore punta a (ad es. un enum).
  2. passa un parametro aggiuntivo con informazioni su ciò che il puntatore punti

Dato che il codice esiste, l'unica cosa che puoi stampare qui è l'indirizzo a cui rimando.

Un puntatore vuoto indica dati non elaborati, printf presuppone che tu sappia quale tipo di dati stai stampando, non ha intelligenza e non può " capirlo " per te.

È così semplice.

Quello che puoi fare è passare informazioni sul tipo alla funzione, ma poi finisci con qualcosa di molto simile a printf è auto, in cui passi una stringa di formattazione contenente informazioni di tipo sui dati nei seguenti argomenti.

Spero che questo aiuti.

Inoltre. . . " Non c'è sovraccarico in C come di solito uso in C ++ "

Anche in c ++ il sovraccarico si verifica in fase di compilazione, e qui non c'è modo per il compilatore di sapere quali dati verranno passati a quella funzione, quindi anche se sei abituato al sovraccarico, non funzionerebbe mai in questo modo (ad es. prova questa stessa cosa usando printf, ma compilala con un compilatore C ++, otterrai esattamente gli stessi risultati). Prova effettivamente

cout << i;

nella funzione sopra, e ti darà l'indirizzo a cui punta, non il " valore " di me. Dovresti lanciare io e deriverlo prima di poterne ottenere il valore

cout << *(int*)i;

Quindi, per far funzionare quanto sopra in C ++ dovresti avere molte funzioni sovraccaricate (o una funzione template, che è davvero la stessa cosa, tranne che il compilatore esegue il rollback delle funzioni per te) ad es. funzioni sovraccariche

printMe(int i){...}
printMe(double d){...}
printMe(char c){...}
printMe(char* string){...}

In c devi solo dare a quelle funzioni nomi specifici

printInt(int i){...}
printDouble(double d){...}
printChar(char c){...}
printString(char* string){...}

Altri suggerimenti

Per cominciare, stai stampando il puntatore, non quello a cui punta. Per stampare il contenuto effettivo, è necessario passare da *i a printf, non i.

Se vuoi davvero farlo, una soluzione è:

void printMe (void *p, int typ) {
    switch(typ) {
        case TYP_INT: printf("%d", *((int*)p)); break;
        case TYP_CHR: printf("%c", *((char*)p)); break;
        /* and so on ... */
    }
}
  

Quindi la domanda è questa, possiamo creare una funzione in C che stamperà l'elemento che è il suo parametro

Sì, possiamo. Tale funzione fa già parte della libreria standard - si chiama printf;)

Poiché non esiste un sovraccarico della funzione di compilazione in C, in qualche modo è necessario fornire il tipo di argomenti in fase di esecuzione. La stringa di formato <=> può essere utilizzata per fare ciò, quindi non c'è davvero alcun motivo per creare la propria funzione wrapper quando esiste già una soluzione funzionante.

Se si sta tentando di stampare il valore del puntatore, l'utilizzo corretto è printf("%p", i);. L'identificatore 'd' è per numeri interi e 'p' è per puntatori. È tua responsabilità ottenere queste cose corrette e possono accadere cose brutte se le mescoli.

Non so perché questo fallirebbe per un carattere * e non per un int *, ed è possibile che tu abbia altri problemi a causare questo. Se continua a fallire con% p, qualcos'altro è stato incasinato. Vedi se riesci a installare una sorta di software di monitoraggio della memoria per verificare la presenza di puntatori penzolanti o double free () s, perché a quel punto i soldi intelligenti hanno danneggiato la memoria da qualche parte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top