Pergunta

Como pode um ofício, uma boa explicação de por que o seguinte código não está correto, em que o autor está a tentar escrever código C++ de forma declarativa, ao invés de incluir processualmente?

const double NEWTONS_PER_POUND = 4.448;

int main()
{
   double pounds, newtons;
   pounds = newtons/NEWTONS_PER_POUND; /* pounds equals 'unassigned variable'/4.448 */
   newtons = 10.0;
   cout << pounds << endl;             /* a big number, not 10.0/4.448 */
   return 0;
}

O autor esperava cout para exibir um cálculo apropriado, mas, em vez disso, recebe um "número louco."

Gostaria de explicar isso como "C++ é processual, e, portanto, ao tempo da declaração

pounds = newtons/NEWTONS_PER_POUND;

newtons não foi atribuído um valor.

Alguma sugestão melhor?Ou uma explicação por que C++ não é "inteligente" o suficiente para realizar o comportamento do usuário por engano esperado?

Foi útil?

Solução

Diga ao autor que

pounds = newtons/NEWTONS_PER_POUND;

comanda a CPU para

  • Pegue o valor no endereço referido como "Newtons"
  • Pegue o valor no endereço referido como "newtons_per_pound"
  • Divida -os
  • Armazene o resultado no endereço chamado de "libras"

O que ele está procurando é provavelmente uma função em termos imperativos:

double newtons_to_pounds(double newtons) {
  return newtons/NEWTONS_PER_POUND;
}

...

newtons = 10.0;
cout << newtons_to_pounds(newtons) << endl;    /* a big number, not 10.0/4.448 */
return 0;

Outras dicas

O C++ é uma linguagem imperativa, não uma equação do solver.

C++ executa instruções na ordem em que você as escreve.C++ não inicializa variáveis, a menos que seja instruído para tal.C++ permite que você use uma variável cujo valor não foi inicializada, mas quando você fizer isso, o resultado é não especificado.Não especificado significa que qualquer coisa pode acontecer, inclusive as coisas ruins como a produção de "louco números".

Aqui está a explicação detalhada:

double pounds, newtons;
pounds = newtons/NEWTONS_PER_POUND;
newtons = 10.0;

A primeira instrução declara duas variáveis sem inicializá-los.Neste ponto, seus valores não especificados.

A segunda instrução lê o valor de newtons (que poderia ser qualquer coisa) e divide-lo por NEWTONS_PER_POUND.O resultado (que pode ser qualquer coisa) é atribuído a pounds.

A terceira instrução inicializa newtons, mas é tarde demais para afetar o cálculo de nós realizada.

Bem, isso não deve ser muito difícil de explicar, independentemente dos antecedentes dos alunos: apenas os que C ++ avaliam programas uma etapa de cada vez, declaração após declaração (apesar dos artefatos do compilador como reordenar…).

Não há absolutamente nada de especial para o C ++ '' de lidar com isso, nem é limitado à programação de computadores - é uma maneira cotidiana de lidar com uma lista ordenada de instruções.

Não é preguiçoso avaliar Newtons

Como tal, o cálculo é realizado no momento da declaração, não no momento da solicitação. Ele está após o código funcional, não o que o C ++ fará.

Se a pessoa não for excessivamente técnica, você pode tentar:

"As declarações deste programa C ++ são como as etapas necessárias para fazer um bolo. Você deve executar as etapas uma a uma e elas devem ser executadas em uma certa ordem para que seja um sucesso".

Explique que as libras recebem um valor na linha com o operador de atribuição:

pounds = newtons/NEWTONS_PER_POUND;

Se não fosse esse o caso, mas que a libra foi avaliada quando foi usada (como na instrução Cout), se o valor de Newtons mudou, o valor dos libras também mudaria. Como libras não é nenhum tipo de ponteiro, mas é um número inteiro simples, isso não é possível.

Que tal passar pelo código em um depurador?

IME não há nada assim para entender a execução de um programa escrito em um idioma processual (ou seja, modelado sobre como a CPU realmente executa o código).

Você está tentando fazer com que o ouvinte sofra uma mudança de paradigma - para alterar toda a sua abordagem para compreender esse código.

"libras" é apenas um número. Não tem nenhum conceito de como é criado. Você diz a "libras" como é criado, não se lembra. Ele apenas se lembrará do que é, não como é criado.

Pode parecer um pouco estranho para antropomorfizar um bloco de memória. :-)

Tome um exemplo um pouco mais complexo, onde uma variável como newtons é reutilizado e atribuído valores mais de uma vez. Por exemplo:

double pounds, newtons;

newtons = 10.0;
pounds = newtons/NEWTONS_PER_POUND;
cout << pounds << endl;

newtons = 15.0;
pounds = newtons/NEWTONS_PER_POUND;
cout << pounds << endl;

return 0;

Mostre a ele o código e a saída. Em seguida, peça a ele para explicar como e por que o programa produz um número diferente para cada linha. Eu acho que isso deveria ajudar a empurrá -lo na direção de ver o programa como um procedimento que corre de cima para baixo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top