Domanda

Mi è stata posta una domanda in C ieri sera e non conoscevo la risposta poiché non ho usato C molto dal college, quindi ho pensato che forse avrei potuto trovare la risposta qui invece di dimenticarmene.

Se una persona ha una definizione come:

#define count 1

Può quella persona trovare il nome della variabile count usando l'1 che è al suo interno?

Non la pensavo così poiché pensavo che il conteggio avrebbe puntato su 1 ma non vedo come l'1 potesse tornare indietro per contare.

È stato utile?

Soluzione

La semplice risposta è no, non possono. #Definizioni del genere sono trattate dal preprocessore e puntano solo in una direzione. Ovviamente l'altro problema è che nemmeno il compilatore lo saprebbe - come un "1" potrebbe indicare qualsiasi cosa: più variabili possono avere lo stesso valore contemporaneamente.

Altri suggerimenti

Basandosi sulla risposta di @Cade Roux, se si utilizza un preprocessore #define per associare un valore a un simbolo, il codice non avrà alcun riferimento al simbolo una volta eseguito il preprocessore:

#define COUNT (1)
...
int myVar = COUNT;
...

Dopo l'esecuzione del preprocessore:

...
int myVar = (1);
...

Quindi, come altri hanno notato, questo significa fondamentalmente "no", per la ragione sopra.

  
    

Può quella persona trovare il nome della variabile " count " usando l'1 che è al suo interno?

  

No

Poiché sono sicuro che qualcuno più eloquente e esperto di me indicherà # le cose definite non sono compilate nella fonte, quello che hai è una macro pre-processore che passerà attraverso la fonte e cambierà tutte le istanze di "count" trova con un "1".

Tuttavia, per far luce sulla domanda che ti è stata posta, poiché C è un linguaggio compilato fino al codice macchina non avrai mai la riflessione e l'introspezione che hai con un linguaggio come Java o C #. Tutta la denominazione viene persa dopo la compilazione, a meno che tu non abbia un framework costruito attorno al tuo sorgente / compilatore per fare qualcosa di elegante.

Spero che questo aiuti. (scusa il gioco di parole)

Purtroppo questo non è possibile.

Le istruzioni

?? #define sono istruzioni per il preprocessore, tutte le istanze di count sono sostituite con 1 . In fase di esecuzione non esiste una posizione di memoria associata a count , quindi lo sforzo è ovviamente inutile.

Anche se stai usando le variabili, dopo la compilazione non ci saranno resti degli identificativi originali utilizzati nel programma. Questo è generalmente possibile solo nelle lingue dinamiche.

Un trucco usato in C sta usando la sintassi # nelle macro per ottenere la stringa letterale del parametro macro.

#define displayInt(val) printf("%s: %d\n",#val,val)
#define displayFloat(val) printf("%s: %d\n",#val,val)
#define displayString(val) printf("%s: %s\n",#val,val)

int main(){
  int foo=123;
  float bar=456.789;
  char thud[]="this is a string";

  displayInt(foo);
  displayFloat(bar);
  displayString(thud);

  return 0;
}

L'output dovrebbe essere simile al seguente:

foo: 123
bar: 456.789
thud: this is a string

#define count 1 è una pessima idea, perché ti impedisce di nominare variabili o campi della struttura count .

Ad esempio:

void copyString(char* dst, const char* src, size_t count) {
   ...
}

La macro count farà sì che il nome della variabile venga sostituito con 1 , impedendo la compilazione di questa funzione:

void copyString(char* dst, const char* src, size_t 1) {
   ...
}

Le definizioni C sono una direttiva pre-processore, non una variabile. Il pre-processore passerà attraverso il tuo file C e sostituirà il punto in cui scrivi conta con quello che hai definito, prima della compilazione. Guarda le voci offuscate del concorso C per alcuni usi particolarmente illuminati di questa e altre direttive pre-processore.

Il punto è che non esiste un "conteggio" per indicare un valore "1". È solo una semplice operazione di ricerca / sostituzione che si verifica prima che il codice sia addirittura compilato.

Lascerò questo modificabile per qualcuno che in realtà conosce davvero C per correggere.

count non è una variabile. Non ha spazio di archiviazione assegnato e nessuna voce nella tabella dei simboli. È una macro che viene sostituita dal preprocessore prima di passare il codice sorgente al compilatore.

Se non stai facendo la domanda giusta, c'è un modo per ottenere il nome usando le macro:

#define SHOW(sym) (printf(#sym " = %d\n", sym))
#define count 1

SHOW(count); // prints "count = 1"

L'operatore # converte un argomento macro in una stringa letterale.

#define è una direttiva pre-processore, in quanto tale non è una "variabile" "

Quello che hai in realtà non è una variabile, è una direttiva preprocessore. Quando compili il codice, il preprocessore passerà e sostituirà tutte le istanze della parola "count" in quel file con 1.

Potresti chiedermi se so che posso trovare quel conteggio dei punti? No. Poiché la relazione tra nomi e valori delle variabili non è una biiezione, non è possibile tornare indietro. Considerare

int count = 1;
int count2 = 1;

perfettamente legale, ma cosa dovrei risolvere?

In generale, no.

Innanzitutto, #define non è una variabile, è una macro del preprocessore del compilatore.

Quando la fase principale del compilatore inizia a funzionare, il nome è stato sostituito con il valore e il nome "conta". non esisterà da nessuna parte nel codice che viene compilato.

Per le variabili, non è possibile trovare i nomi delle variabili nel codice C in fase di esecuzione. Quelle informazioni non sono conservate. A differenza di linguaggi come Java o C #, C non mantiene affatto molti metadati, nelle compilazioni fino al linguaggio assembly.

Direttiva che inizia con " # " sono gestiti dal pre-processore che di solito fa la sostituzione del testo prima di passare il codice al compilatore "reale". Pertanto, non esiste una variabile chiamata count, è come se tutto " count " le stringhe nel tuo codice vengono magicamente sostituite con "1" " stringa.

Quindi, no, non c'è modo di trovare quella "variabile".

Nel caso di una macro questa è preelaborata e l'output risultante viene compilato. Quindi non è assolutamente possibile scoprire quel nome perché dopo che il preprocessore termina il suo lavoro il file risultante conterrebbe '1' invece di 'count' ovunque nel file.

Quindi la risposta è no.

Se stanno guardando il codice sorgente C (che saranno in un debugger), vedranno qualcosa come

int i = count;

a quel punto, possono cercare indietro e trovare la linea

#define count 1

Se, tuttavia, tutto ciò che hanno è la variabile iDontKnowWhat, e possono vederlo in contans 1, non c'è modo di rintracciarlo su 'count'.

Perché? Perché #define viene valutato al momento del preprocessore, cosa che accade anche prima della compilazione (anche se per quasi tutti, può essere visto come il primo stadio della compilazione). Di conseguenza, il codice sorgente è l'unica cosa che ha informazioni su "count", come sapere che è mai esistito. Quando il compilatore dà un'occhiata, ogni riferimento a "count" è stato sostituito dal numero "1".

Non è un puntatore, è solo una sostituzione stringa / token. Il preprocessore sostituisce tutte le #define prima che il codice venga mai compilato. La maggior parte dei compilatori include un argomento -E o simile per emettere codice precompilato, quindi puoi vedere come appare il codice dopo che tutti i #direttivi sono stati elaborati.

Più direttamente alla tua domanda, non c'è modo di dire che un token viene sostituito nel codice. Il tuo codice non può nemmeno distinguere tra (count == 1) e (1 == 1).

Se vuoi davvero farlo, potrebbe essere possibile utilizzare l'analisi del testo del file sorgente, ad esempio utilizzando uno strumento diff.

Che cosa intendi per "trovare " ;?

La linea

#define count 1

definisce un simbolo " count " che ha valore 1.

Il primo passaggio del processo di compilazione (chiamato preelaborazione) sostituirà ogni occorrenza del conteggio dei simboli con 1 in modo che se si dispone di:

if (x > count) ...

sarà sostituito da:

if (x > 1) ...

Se ottieni questo, potresti capire perché " trovare il conteggio " non ha senso.

La persona che ha posto la domanda (era una domanda di intervista?) potrebbe aver cercato di farti distinguere tra l'uso di costanti #define e enumerazioni. Ad esempio:

#define ZERO 0
#define ONE 1
#define TWO 2

vs

enum {
  ZERO,
  ONE,
  TWO
};

Dato il codice:

x = TWO;

Se usi le enumerazioni invece delle #define, alcuni debugger saranno in grado di mostrarti la forma simbolica del valore, DUE, anziché solo il valore numerico di 2.

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