Encontrar o nome de uma variável em C
-
02-07-2019 - |
Pergunta
Foi-me pedido uma pergunta em C na noite passada e eu não sabia a resposta desde que eu não usei C muito desde a faculdade, então eu pensei que talvez pudesse encontrar a resposta aqui em vez de apenas esquecê-lo.
Se uma pessoa tem uma definição, tais como:
#define count 1
Can essa pessoa encontrar o nome count
variável utilizando o 1, que está dentro dela?
Eu não penso assim desde que eu pensei que a contagem seria apontar para o 1º mas não ver como a 1 poderia apontar de volta para contar.
Solução
A resposta simples é não, eles não podem. # Define como esse são tratados pelo pré-processador, e eles só apontam em uma direção. Claro que o outro problema é que, mesmo que o compilador não saberia - como um "1" pode apontar para qualquer coisa -. Múltiplas variáveis ??podem ter o mesmo valor, ao mesmo tempo
Outras dicas
Com base na resposta de @Cade Roux, se você usar um #define pré-processador para associar um valor com um símbolo, o código não terá qualquer referência ao símbolo uma vez que o pré-processador foi executado:
#define COUNT (1)
...
int myVar = COUNT;
...
Depois que os pré-processamento é executado:
...
int myVar = (1);
...
Assim como os outros, isso basicamente significa "não", pela razão acima.
Can essa pessoa encontrar o nome da variável "contar" com o 1 que está dentro dela?
Não
Como eu tenho certeza que alguém mais eloqüente e versado do que me vai apontar # define'd coisas não são compilados na fonte, o que você tem é uma macro pré-processador que irá percorrer a fonte e alterar todas as instâncias de 'contagem' ele encontra com um '1'.
No entanto, para lançar mais luz sobre a questão lhe foi pedido, porque C é um baixo linguagem compilada para o código de máquina que você nunca vai ter a reflexão e introspecção que você tem com uma linguagem como Java ou C #. Toda a nomeação é perdido após a compilação menos que você tenha uma estrutura construída em torno de sua fonte / compilador para fazer alguma coisa bacana.
Hope este ajuda. (Desculpem o trocadilho)
Infelizmente não é possível.
declarações #define
estão as instruções para o pré-processador, todas as instâncias do count
são substituídos por 1
. Em tempo de execução não existe um local de memória associado com count
, de modo que o esforço é obviamente inútil.
Mesmo se você estiver usando variáveis, após a compilação não haverá restos dos identificadores originais usados ??no programa. Este é geralmente só é possível em linguagens dinâmicas.
Um truque usado em C está usando a sintaxe # em macros para obter o literal string do do parâmetro 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;
}
A saída deve ser algo como o seguinte:
foo: 123
bar: 456.789
thud: this is a string
#define count 1
é uma idéia muito ruim, porque o impede de nomear qualquer variáveis ??ou campos de estrutura count
.
Por exemplo:
void copyString(char* dst, const char* src, size_t count) {
...
}
Seu macro count
fará com que o nome da variável a ser substituído com 1
, impedindo que esta função de compilação:
void copyString(char* dst, const char* src, size_t 1) {
...
}
define C são uma directiva de pré-processador, não uma variável. O pré-processador vai passar por seu arquivo C e substituí onde você escreve a contagem com o que você definiu como, antes de compilar. Olhada as entradas da competição C ofuscados para alguns usos particularmente iluminados desta e de outras directivas pré-processador.
O ponto é que não há 'count' para apontar para um valor '1'. É apenas um simples / encontrar substituir operação que acontece antes o código é mesmo realmente compilado.
Vou deixar isso editável para alguém que realmente sabe realmente o C a correta.
count
não é uma variável. Não tem de armazenamento alocado para ele e nenhuma entrada na tabela de símbolos. É uma macro que será substituído pelo pré-processador antes de passar o código-fonte para o compilador.
Sobre a chance de que você não está pedindo muito a pergunta certa, há uma maneira de obter o nome usando macros:
#define SHOW(sym) (printf(#sym " = %d\n", sym))
#define count 1
SHOW(count); // prints "count = 1"
O operador #
converte um argumento macro a um literal string.
#define
é uma directiva de pré-processador, como tal, não é uma "variável"
O que você tem aí realmente não é uma variável, é um pré-processador diretiva. Quando você compilar o código do pré-processador vai passar e substituir todos os instaces da palavra 'count' nesse arquivo com 1.
Você pode estar perguntando se eu sei 1 eu posso encontrar que os pontos de contagem para ele? Não. Porque a relação entre nomes e valores das variáveis ??não é uma bijeção não há caminho de volta. Considere
int count = 1;
int count2 = 1;
perfeitamente legal, mas o que deve uma resolução para?
Em geral, não.
Em primeiro lugar, um #define não é uma variável, é uma macro compilador pré-processador.
Até o momento a principal fase do compilador começa a trabalhar, o nome foi substituído com o valor eo nome da "contagem" não vai existir em qualquer lugar do código que é compilado.
Para variáveis, não é possível encontrar nomes de variáveis ??em código C em tempo de execução. Essa informação não é mantida. Ao contrário de linguagens como Java ou C #, C não manter muito metadados em tudo, em compila para baixo a linguagem assembly.
Directiva começando com "#" são tratados pelo pré-processador que normalmente faz substituição de texto antes de passar o código para o compilador 'real'. Como tal, não há nenhuma variável chamada contagem, é como se todos "contar" strings em seu código são magicamente substituído com o "1" string.
Então, não, não há maneira de descobrir que "variável".
No caso de uma macro isso é pré-processado e a saída resultante é compilada. Por isso, é absolutamente nenhuma maneira de descobrir esse nome porque após o pré-processador finnishes seu trabalho o arquivo resultante conteria '1' em vez de 'count' em todo o arquivo.
Assim, a resposta é não.
Se eles estão olhando para o código-fonte C (que eles vão estar em um depurador), então eles vão ver algo como
int i = count;
Nesse ponto, eles podem procurar para trás e encontrar a linha
#define count 1
Se, no entanto, todos eles têm é iDontKnowWhat variável, e eles podem ver contans 1, não há maneira de controlar isso de volta para 'contar'.
Por quê? Porque o #define é avaliada em tempo de pré-processador, o que acontece mesmo antes da compilação (embora para quase todos, ele pode ser visto como a primeira fase de compilação). Consequentemente, o código fonte é a única coisa que tem qualquer informação sobre 'contar', como saber que ele nunca existiu. No momento em que o compilador recebe um olhar em, todas as referências a 'contar' foi substituído pelo número '1'.
Não é um ponteiro, é apenas uma string / substituição token. O pré-processador substitui todas as #defines antes de seu código já compila. A maioria dos compiladores incluem um -E ou argumento semelhante ao emitir código pré-compilados, para que possa ver o que os olhares código como depois de todos os #directives são processados.
Mais directamente à sua pergunta, não há nenhuma maneira de dizer que um sinal está sendo substituído no código. Seu código não pode mesmo dizer a diferença entre (contagem == 1) e (1 == 1).
Se você realmente quer fazer isso, pode ser possível usando análise de texto arquivo de origem, digamos, usando uma ferramenta de comparação.
O que você quer dizer com "descoberta"?
A linha
#define count 1
define um símbolo "contagem" que tem valor 1.
O primeiro passo do processo de compilação (chamado pré-processamento) irá substituir cada ocorrência da contagem símbolo com 1 de modo que se você tem:
if (x > count) ...
será substituída por:
if (x > 1) ...
Se você conseguir isso, você pode ver porque "contagem de encontrar" não tem sentido.
A pessoa que faz a pergunta (era uma pergunta da entrevista?) Pode ter sido tentando levá-lo para diferenciar entre o uso de constantes #define contra enums. Por exemplo:
#define ZERO 0
#define ONE 1
#define TWO 2
vs
enum {
ZERO,
ONE,
TWO
};
Dado o código:
x = TWO;
Se você usar enumerações em vez dos #defines, alguns depuradores será capaz de mostrar-lhe a forma simbólica do valor, dois, em vez de apenas o valor numérico de 2.