Página 1 de 1

Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 09 Fev 2020 11:30
por MOR_AL
Olá pessoal.

Para quem não quiser ler a história, vá direto para a linha azul....



Em meus projetos com Microcontrolador (MC) pic16F628A, aprendi a usar a linguagem Assembly e costumo obter uma grande redução da memória de programa se comparado a linguagens de mais alto nível. Com 2k de memória de programa se consegue fazer muita coisa com este MC.

Começo com um fluxograma que usa pseudo código, com blocos que contém uma proximidade com a linguagem Assembly. À partir do fluxograma consigo chegar ao programa sem problemas.

Mas a evolução para programas maiores está sendo mais complicada, justamente pelo fato de sempre partir de um fluxograma. 

Explico melhor.

Estou estudando um programa em C de uma apostila, mas o problema não está na linguagem, pois ocorreria em outra linguagem como o Basic do Bascavr.

Basicamente, discordo do programa da apostila.

Passei o programa da apostila para um fluxograma e tentei fazer um programa baseado neste fluxograma (vide figura)

O programa da apostila não seguiu a lógica. No bloco "D" do fluxograma, o programa da apostila continua para o bloco "C". Mas a lógica do PROBLEMA indica que não há necessidade de ir para o bloco "E" e sim retornar ao bloco "B", como no meu fluxograma.

Aí é que vem o MEU problema.

Escuto que não se deve usar a instrução GOTO, porque ela cria confusão no entendimento do programa. Eu concordo, mas se houver um fluxograma disponível, fica bem mais inteligível.

Minha dúvida é a seguinte (demorou, né?).



Como não usar a instrução GOTO, seguindo o fluxograma apresentado?

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 09 Fev 2020 11:56
por Red Neck Guy
X deve fazer uma chamada a função que tem o loop:

Código: Selecionar todos

unsigned char loop_do_Mor_al(void*args){


}

// lá no local em que você gostaria de chamar o código
...

while(!loop_do_Mor_al());
...




Supondo que a condição de retorno para voltar a X é a unica condição de continuar no loop, então retornaria um valor diferente de zero....
Se não for isso, iteramos mais uma vez aqui pra tentar te ajudar.

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 09 Fev 2020 12:35
por MOR_AL
O problema é o seguinte:
Uma bomba d'água que alimenta uma caixa d'água. Nessa caixa tem duas boias em níveis diferentes. A água não deve ultrapassar a boia superior e nem ficar abaixo da boia inferior.
Tem uma chave que ao fechar vai a zero. Quando esta chave estiver fechada (0) é que ativa o processo. Quando estiver aberta (1) o programa mantém a bomba desligada.
Os blocos:
A = Desliga a bomba.
B = Chave acionada? (0) para Sim e 1 para não.
C = Boia superior com água?
D = Desliga a bomba.
E = Boia inferior sem água?
F = Desliga a bomba
Note que o programa da apostila pergunta se a boia inferior está sem água (item E) ... depois de saber que a boia superior está com água (o programa da apostila liga a saída "D" na entrada "E".

Tirei uma foto do exercício. Meu fluxograma não testa a bomba inferior, sabendo que a superior está com água. Daí é que fiz o meu fluxograma e apareceu o GOTO. O programa fica perguntando se a chave está fechada o tempo todo. Pelo que entendi de sua sugestão, o loop externo cessa. É isso?

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 09 Fev 2020 12:54
por MOR_AL
Basicamente.
Entendi que sua opção sai do loop e para, mas o loop tem que ficar rodando continuamente.
Como não usar o GOTO?
MOR_AL

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 09 Fev 2020 13:07
por cfreund
Não tenha medo do Goto. Esse povo que "torce o nariz" para uma ferramenta, nem deveria ser chamado de programador. Tanto que uma vez compilado, dificilmente um programa não terá um "goto". É uma ferramenta extremamente útil e ajuda bastante na otimização do código.

Enfim, neste caso eu faria da seguinte forma:
Código: Selecionar todos
for (;;)
{
   while (chave_fechada && sensor_superior_ativado)   // Quando chave acionada, espera o sensor superior indicar nível baixo
   {
      if (sensor_inferior_ativado) // Espera nível chegar no sensor inferior
         ligar_bomba();
   }

   desligar_bomba(); // Desliga a bomba quando o nível atingir sensor superior ou abrir a chave
}

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 09 Fev 2020 16:39
por MOR_AL
cfreund escreveu:Não tenha medo do Goto. Esse povo que "torce o nariz" para uma ferramenta, nem deveria ser chamado de programador. Tanto que uma vez compilado, dificilmente um programa não terá um "goto". É uma ferramenta extremamente útil e ajuda bastante na otimização do código.

Enfim, neste caso eu faria da seguinte forma:
Código: Selecionar todos
for (;;)
{
   while (chave_fechada && sensor_superior_ativado)   // Quando chave acionada, espera o sensor superior indicar nível baixo
   {
      if (sensor_inferior_ativado) // Espera nível chegar no sensor inferior
         ligar_bomba();
   }

   desligar_bomba(); // Desliga a bomba quando o nível atingir sensor superior ou abrir a chave
}


Valeu cfreud. Acho que você fez uma tabela verdade e resolveu o problema da bomba.
Mas a instrução não seria ...
while (chave_fechada && sensor_superior_DESativado) // Só liga a bomba com o sensor superior indicar nível baixo.
Parabéns. O exercício fica resolvido. Bastaria ter feito a tabela verdade para simplificar o problema.
Grato a você e ao Aquino.
[]'s
MOR_AL

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 10 Fev 2020 11:31
por xultz
Uma vez eu peguei o código fonte do kernel linux e fiz um grep -R goto * e fiquei impressionado a quantidade de vezes que o goto é utilizado.
Em situações apertadas, onde se precisa de velocidade, código enxuto ou ambos, o goto pode ser a melhor solução. Se o Linus Torvalds não xingou a pessoa e aceitou o código usando goto, então usar goto talvez não seja pecado.

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 10 Fev 2020 19:10
por Red Neck Guy
xultz escreveu:Uma vez eu peguei o código fonte do kernel linux e fiz um grep -R goto * e fiquei impressionado a quantidade de vezes que o goto é utilizado.
Em situações apertadas, onde se precisa de velocidade, código enxuto ou ambos, o goto pode ser a melhor solução. Se o Linus Torvalds não xingou a pessoa e aceitou o código usando goto, então usar goto talvez não seja pecado.


No código-fonte do Linux o goto é muito utilizado como uma espécie de "exception". São situações em que é necessário desfazer algo, geralmente assim: FAZ A,B,C... depois no "exception", os labels são incrementais e desfaz C,B,A...

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 11 Fev 2020 13:36
por dede
Na próxima vez pensa em maquina de estados.
Sua vida vai ficar mais fácil com esses fluxogramas.

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 13 Fev 2020 19:13
por MOR_AL
Bom.
Conclusões:
1 - Fazer o fluxograma em pseudo código.
2 - Fazer a tabela verdade.
3 - Fazer a máquina de estados, já que a sequência é necessária.
4 - Partir para um programa tentando evitar o GOTO. Caso fique trabalhoso, azar. E lá vai GOTO. Com o fluxograma do item 1, o programa fica bem claro de se entender.
Pessoal, valeu pelas dicas.
[]'s.
MOR_AL

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 14 Fev 2020 22:16
por cfreund
5 - Remover o while do código proposto.

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 15 Fev 2020 15:27
por MOR_AL
cfreund escreveu:5 - Remover o while do código proposto.


Porquê?
Alguém informou que prefere o For(;;) ao While(1), saberia dizer porquê?
MOR_AL

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 17 Fev 2020 11:48
por mastk
Não gosto de GOTO, só uso quando realmente é preciso, o problema do goto é quebrar a estrutura do programa, deixando menos legível. Discordo dos amigos de verem o fonte do Linux como exemplo, nenhum de nos está trabalhando em um sistema operacional.

While(1) e for(;;) são equivalentes, até aonde eu sei, o que muda é menos texto, até aonde eu sei, lembro do conceito de código como risco, quanto menos, melhor.

Moral, tabela de verdade teria de vir antes do pseudo código, eu penso assim:

-Texto com o objetivo do código.
-Rascunho de lógica e estruturas. (Tabela de verdade, desenhos, propostas e conceitos).
-Pseudo código.
-Código.

Máquina de estados é uma técnica que pode ser trabalhosa, tem que ver se vale a pena no seu problema.

Re: Do Fluxograma ao Programa (outra vez...)

MensagemEnviado: 17 Fev 2020 17:28
por MOR_AL
mastk escreveu:Não gosto de GOTO.....
While(1) e for(;;) são equivalentes, até aonde eu sei, o que muda é menos texto, até aonde eu sei, lembro do conceito de código como risco, quanto menos, melhor.
OK!
Moral, tabela de verdade teria de vir antes do pseudo código, eu penso assim:

Normalmente eu costumo usar um fluxograma. Parto de blocos genéricos com rotinas em um bloco, que abrangeriam muitas linhas de código. Para mim é mais fácil começar assim. É um modo de ver quase que o programa todo em apenas uma página. Aos poucos vou detalhando cada bloco em tantos quantos forem necessários. Tudo em pseudo código, porém direcionado para a linguagem que eu decidi usar. Com o tempo, se eu observar que o fluxograma fica muito complexo. Então eu tento observar as variáveis, tentando fazer a tabela verdade, junto com um diagrama de estados. Dá um pouco de trabalho, mas no fim fica bem mais fácil.
Como exemplo vai em anexo o causador desse tópico. No final fiz uma tabela verdade, que usava 6 sensores em 3 caixas d'águas e 2 bombas controlando o nível das caixas. Foram 64 linhas de tabela verdade.
Se fosse seguir apenas a tabela verdade, eu já teria uma substancial redução do fluxograma e, consequentemente, do programa. Ocorre, que observando a tabela verdade, notei que algumas linhas eram redundantes e outras eram impossíveis de existirem. Algo como o sensor superior da caixa d'água informar que a água chegou nele e o sensor inferior informando que não havia água nele. Fiz apenas dois mapas de Karnaugh (2x2)e tudo se simplificou.
Conclusão só seria necessário testar 4 situações, para ligar ou desligar cada uma das duas bombas.


-Texto com o objetivo do código.
-Rascunho de lógica e estruturas. (Tabela de verdade, desenhos, propostas e conceitos).
-Pseudo código.
-Código.

Máquina de estados é uma técnica que pode ser trabalhosa, tem que ver se vale a pena no seu problema.


Segue o trabalho. os blocos Rot1, 2, 3 e 4 são apenas rotinas que retiram o bouncing da marola da água nos sensores.