Apesar de focarmos em um dos tópicos básicos, este artigo foi escrito para profissionais experientes. O objetivo é mostrar quais conceitos errôneos os iniciantes têm na programação. Para os desenvolvedores praticantes, esses problemas já foram resolvidos, esquecidos ou nem notados. Um artigo pode ser útil se você, de repente, precisar ajudar alguém com esse tópico. O artigo traça paralelos com o material de vários livros sobre programação de Shildt, Straustrup, Okulov.
O tópico dos ciclos foi escolhido porque muitas pessoas o abandonam ao dominar a programação.
Essa técnica é projetada para alunos fracos. Como regra, aqueles que são fortes nesse tópico não ficam presos e não precisam inventar técnicas especiais para eles. O objetivo secundário do artigo é transferir essa metodologia da turma "funciona para todos os alunos, mas apenas para um professor" para a turma "funciona para todos os alunos, todos os professores". Não finjo ser absolutamente original. Se você já está aplicando uma técnica semelhante para ensinar este tópico, escreva como sua versão difere. Se você decidir se inscrever, conte-nos pelos resultados como tudo correu. Se uma técnica semelhante for descrita em um livro, escreva o nome.
Eu pratiquei essa técnica por 4 anos, estudando individualmente com alunos de diferentes níveis de treinamento. Apenas cerca de cinquenta alunos e duas mil horas de aulas. Inicialmente, os alunos continuaram e deixaram para sempre esse assunto. Após cada aluno, a metodologia e os materiais foram ajustados. No ano passado, os alunos não estão mais presos a esse tópico, então decidi compartilhar minhas melhores práticas.
Por que tantas cartas? Os ciclos são elementares!
Como escrevi acima, para praticantes desenvolvedores e estudantes fortes, a complexidade do conceito de ciclos pode ser subestimada. Por exemplo, você pode organizar uma longa palestra, ver cabeças balançando a cabeça e olhos inteligentes. Mas quando você tenta resolver um problema, um estupor e problemas inexplicáveis começam. Após a palestra, os alunos provavelmente desenvolveram apenas um entendimento parcial. A situação é agravada pelo fato de que os próprios alunos não podem expressar qual é exatamente o seu erro.
Uma vez eu percebi que os alunos percebem meus exemplos como hieróglifos. Ou seja, como pedaços de texto indivisíveis nos quais você precisa adicionar algum tipo de letra "mágica" e ela funcionará.
Às vezes notei que os alunos pensam que, para resolver um problema específico, é necessária
alguma outra construção, o que eu ainda não contei. Embora a solução exigisse apenas uma pequena modificação do exemplo.
Portanto, tive a ideia de que o foco principal não deveria estar na sintaxe das expressões, mas na idéia de refatorar o código repetitivo usando loops. Assim que os alunos dominam essa idéia, qualquer sintaxe é reforçada com um pouco de exercício.
Para quem e por que eu ensino
Como não há exames de admissão, na sala de aula pode haver alunos fortes e muito fracos. Mais detalhes sobre meus alunos podem ser encontrados no artigo
Retrato de alunos de cursos noturnos.Eu tentei garantir que todos que quisessem dominassem a programação.
Minhas aulas são realizadas individualmente e o aluno paga seu dinheiro por cada uma. Parece que os alunos otimizarão os custos e exigirão um mínimo. No entanto, as pessoas não participam de aulas em período integral com um professor ao vivo pelo conhecimento em si, mas pela confiança que aprenderam, pelo senso de progresso e pela aprovação de um especialista (professor). Se os alunos não sentirem progresso em seus estudos, eles partirão. Em geral, as aulas podem ser projetadas para que os alunos sintam progresso no aumento do número de projetos familiares. Ou seja, primeiro estudamos em detalhes em detalhes, depois estudamos, depois estudamos e agora temos um curso de mil e uma noites, no qual estudamos ciclos apenas por dois meses e, no final, um aluno que escreveu uma biblioteca padrão ditou. No entanto, para solucionar problemas práticos, é necessário não apenas o conhecimento do material, mas também independência em sua aplicação e na busca de novas informações. Portanto, para os cursos em período integral, acho que o princípio está correto - ensinar um mínimo e incentivar o estudo independente de nuances e tópicos relacionados. No tópico de loops, considero a construção while um mínimo. Nele você pode entender o princípio. Conhecendo o princípio, você pode dominar tanto a si próprio quanto a fazer enquanto faz.
Não é suficiente descrever a sintaxe para obter o domínio do material por alunos fracos. Você precisa dar tarefas mais simples, mas diversas, e pintar exemplos com mais detalhes. Por fim, a velocidade do desenvolvimento é limitada pela capacidade do aluno de transformar expressões e procurar padrões. Para alunos inteligentes, a maioria das tarefas será chata. Ao praticar com eles, você não pode insistir em resolver 100% das tarefas. Meu material pode ser visto no
meu github . É verdade que o repositório é mais como um grimório de bruxo - ninguém, exceto eu, entenderá onde está
, e se você falhar na verificação, poderá ficar loucoPrática prática orientada
A teoria é explicada pelo exemplo de solução de um problema. Nas aulas sobre os conceitos básicos de programação, onde estuda ramificação e loop, você não poderá dar uma palestra útil sobre um tópico por uma hora. 15-20 minutos são suficientes para explicar o conceito. As principais dificuldades aparecem ao executar tarefas práticas.
Professores iniciantes podem despejar instruções, ramificações, loops e matrizes em uma aula. Aqui estão apenas os alunos que encontrarão o problema de assimilação dessa informação.
Você precisa não apenas contar o material, mas também garantir que o público entenda.
O fato de dominar o tópico é determinado pela maneira como o aluno lida com o trabalho independente.
Se um aluno conseguiu resolver um problema em um tópico sem a ajuda de um professor, o tópico foi aprendido. Para fornecer auto-verificação, cada tarefa é descrita em uma tabela com scripts de teste. As tarefas têm uma ordem pronunciada. Ignorar tarefas não é recomendado. Se a tarefa atual for muito complicada, a continuação para a próxima será inútil. Ela é ainda mais difícil. Para que o aluno possa dominar a tarefa difícil atual, são explicados vários truques no exemplo da primeira tarefa. Na verdade, todo o conteúdo do tópico é reduzido a métodos de superação de dificuldades. Ciclos são mais provavelmente um efeito colateral.
A primeira tarefa é sempre um exemplo. O segundo difere um pouco e é realizado “independentemente” imediatamente após o primeiro, sob a supervisão de um professor. Todas as tarefas subseqüentes têm como objetivo chamar a atenção para várias pequenas coisas que podem causar confusão.
A explicação do exemplo é um diálogo no qual o aluno precisa retornar a propagação e a validação cruzada para garantir que ele assimila uma parte do material.
Serei banal e declararei que o primeiro exemplo sobre o assunto é muito importante. Se houver material para extenso trabalho independente, as omissões do primeiro exemplo podem ser corrigidas. Se, além do exemplo, não houver mais nada, é provável que o aluno não domine o tópico.
Enquanto ou para?
Uma das questões controversas é a escolha do construto para um exemplo: enquanto ou para. Uma vez, um amigo meu, um desenvolvedor praticante sem experiência de ensino, me convenceu por uma hora que o loop for era o mais fácil de entender. Os argumentos se resumiram a "tudo está claro e exposto em alguns lugares". No entanto, a causa raiz das dificuldades dos verdadeiros iniciantes na própria idéia do ciclo, e não na sua escrita. Se uma pessoa não entender essa idéia, ela terá dificuldades com a sintaxe. Assim que a idéia é realizada, os problemas de design de código desaparecem.
Nos meus materiais, o tema dos ciclos segue o tema da ramificação. A semelhança externa de if e while nos permite traçar uma analogia direta: "quando a condição no cabeçalho for verdadeira, o corpo ficará satisfeito". A peculiaridade do ciclo é que o corpo é realizado muitas vezes.
Meu segundo argumento é que enquanto requer menos decoração do que para. Menos estilo - menos erros estúpidos com vírgulas e colchetes ausentes. Os iniciantes ainda não são tão atenciosos e meticulosos que evitam automaticamente erros de sintaxe.
O terceiro argumento é que muitos livros bons são explicados primeiro.
Se um aluno consegue transformar expressões facilmente, você pode falar sobre isso de passagem. O aluno escolherá o que mais gosta. Se as transformações causarem dificuldades, é melhor não despertar a atenção. Deixe o aluno resolver tudo com a ajuda de um tempo. Depois de dominar o tópico dos loops, você pode reescrever soluções para calcular a conversão de enquanto para.
Os ciclos pós-condicionamento são um animal raro. Eu não gasto tempo com isso. Se um aluno dominar as idéias de revelar padrões e transformar expressões, poderá descobrir isso sem a minha ajuda.
Ao demonstrar o primeiro exemplo para alunos fortes, chamo a atenção para o fato de que no primeiro exemplo é importante corrigir não apenas a solução, mas também toda a cadeia de ações que levaram ao resultado. Os estudantes preguiçosos podem negligenciar os escritos e transferir apenas o algoritmo finito para si mesmos. Eles precisam estar convencidos de que um dia encontrarão uma tarefa difícil. Para resolvê-lo, você precisará seguir as etapas como neste exemplo. É por isso que é importante corrigir todas as etapas. Nas tarefas a seguir, será possível deixar apenas a solução final.
A principal idéia da automação é que instruímos o computador a realizar trabalhos de rotina por pessoa. Um dos truques básicos é escrever ciclos. É usado quando várias ações repetitivas idênticas são gravadas em um programa em uma linha.
Explícito é melhor que implícito
Pode parecer uma boa ideia na primeira tarefa dos ciclos exibir uma frase idêntica várias vezes. Por exemplo:
Viva, funciona!
Viva, funciona!
Viva, funciona!
Viva, funciona!
Viva, funciona!
Viva, funciona!
Viva, funciona!
Viva, funciona!
Esta opção está incorreta porque a saída não mostra o valor do contador. Este é um problema para iniciantes. Não o subestime. No início, essa tarefa era a primeira, e a tarefa de gerar uma série de números em ordem crescente foi a segunda. Eu tive que introduzir termos adicionais "ciclo N vezes" e "ciclo de A a B", que são essencialmente os mesmos. Para não produzir entidades desnecessárias, decidi mostrar apenas um exemplo com uma série de números. Poucos conseguem aprender como manter um contador na cabeça e simular o comportamento de um programa na cabeça sem preparação. Pela primeira vez, alguns alunos são confrontados com a modelagem “na mente” sobre o tema dos ciclos.
Após alguma prática, dou a tarefa de repetir o mesmo texto para uma solução independente. Se você der primeiro um contador visível e depois invisível, os alunos terão menos problemas. Às vezes, os avisos "não escreva o contador na tela" são suficientes.
Como os outros explicam isso?
Na maioria dos materiais educacionais na Internet, a sintaxe do loop é apresentada como parte de uma "palestra". Por exemplo, no developer.mozilla.org (atualmente), várias outras construções são descritas junto com o loop while. Nesse caso, apenas as construções em si são fornecidas na forma de modelos. O resultado do seu lançamento é descrito em palavras, mas a ilustração está ausente. Na minha opinião, essa apresentação do tópico multiplica a utilidade de tais materiais por zero. O aluno pode reescrever o código e executá-lo, mas o benchmark para comparação ainda é necessário. Como entender que o exemplo é reescrito corretamente se não há nada para comparar o resultado?
Quando apenas um modelo é fornecido, sem um exemplo, isso se torna ainda mais difícil para um aluno. Como entender que fragmentos de código são colocados no modelo corretamente? Você pode tentar escrever de
alguma forma e depois executar. Mas se não houver um padrão para comparar o resultado, o lançamento também não ajudará.
No curso C ++ sobre intuição, a sintaxe do loop está oculta na terceira página da Palestra 4, sobre o tópico "operadores". Ao explicar a sintaxe dos loops, é dada ênfase especial ao termo "operador". O termo é apresentado como um conjunto de fatos como “símbolo; este é um operador "," {} este é um operador composto "," o corpo do loop deve ser um operador ". Não gosto dessa abordagem porque parece ocultar relacionamentos importantes em um único termo. A análise do código-fonte do programa em termos desse nível é necessária para que os desenvolvedores do compilador implementem a especificação de idioma, mas não para os alunos na primeira aproximação. Os iniciantes em programação raramente têm a meticulosidade de estar tão atentos aos termos. Uma pessoa rara lembra e entende novas palavras pela primeira vez. Virtualmente ninguém pode aplicar corretamente o termo que eles acabaram de aprender. Portanto, os alunos têm vários erros como "escreveu enquanto (a <7); {, mas o programa não funciona".
Na minha opinião, no início é melhor fornecer a sintaxe da construção imediatamente com colchetes. A opção sem colchetes é explicada apenas se o aluno tiver uma pergunta específica “por que funciona sem colchetes”.
No livro de Okulov, "Fundamentos da programação", em 2012, o conhecimento dos ciclos começa com o modelo for, depois são dadas recomendações para seu uso e, em seguida, a seção experimental da lição segue imediatamente. Entendo que o livro foi escrito para a minoria de estudantes muito capazes que raramente frequentam minhas aulas.
Nos livros populares, o resultado de fragmentos de código é sempre escrito. Por exemplo, edição “2015 do Java 8. Complete Guide” de Schildt. Primeiro, é fornecido um modelo, depois um programa de exemplo e imediatamente após o resultado da execução.
Como exemplo, considere um loop while no qual o inverso
a contagem regressiva, começando em 10, e exatamente 10 linhas de "medidas" são exibidas:
Após o início deste programa, são exibidas dez "medidas", como a seguir:
10
9
8
7
6
5
4
3
2
1
A abordagem com a descrição do modelo, programa de amostra e o resultado desse programa também é usada no livro “Javascript para crianças” e no curso js em w3schools.com. O formato da página da web ainda permite que você interaja com este exemplo.
No livro de 2016 da Straustrup, Principles and Practices Using C ++, o autor foi ainda mais longe. O primeiro passo explica qual deve ser o resultado e, depois disso - mostre o texto do programa. Além disso, como exemplo, eles tomam não apenas um programa aleatório, mas fazem uma excursão pela história. Ajuda a chamar a atenção: “Veja, este não é apenas um texto inútil. Você vê algo significativo.
Como um exemplo de iteração, considere o primeiro programa executado em uma máquina com um programa armazenado (EDSAC). Foi escrito por David Wheeler no laboratório de informática da Universidade de Cambridge, Inglaterra, em 6 de maio de 1949. Este programa calcula e imprime uma lista simples de quadrados.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801
Aqui, cada linha contém um número seguido por uma guia ('\ t') e o quadrado desse número. A versão C ++ deste programa tem a seguinte aparência:
Curiosamente, o modelo de sintaxe não é descrito neste livro. Stroustrup no manual do instrutor (
tradução ) enfatiza que ele respeita a inteligência de seus alunos. Talvez a capacidade de identificar o padrão em vários exemplos seja considerada uma manifestação dessa inteligência.
Como eu me explico
A abordagem de Straustrup: uma descrição do resultado, depois uma solução para o problema e, em seguida, uma análise independente pelo aluno - parece a mais ponderada. Por isso, decidi tomá-lo como base, mas conte-o em um exemplo menos histórico - a tarefa de derivar um "índice". Forma uma âncora reconhecível, de modo que mais tarde diga "lembre-se da tarefa do sumário" e para que os alunos se lembrem dela. No meu exemplo, tentei alertar mais dois dos equívocos mais comuns. Em seguida, escreverei mais sobre eles.
Nesta tarefa, nos familiarizamos com os métodos de solução de problemas complexos. A decisão inicial deve ser tomada de forma primitiva e simples. Bem, então você pode pensar em como melhorar essa solução.
1
2
3
4
5
6
7
De acordo com minhas observações, a abordagem "modelo-exemplo-resultado" em diferentes combinações ainda leva os alunos a perceber o ciclo como um hieróglifo. Isso se manifestou no fato de que eles não entenderam por que deveriam escrever uma condição, como escolher entre i ++ e i - e outras coisas aparentemente óbvias. Para evitar esses conceitos errôneos, a abordagem da história sobre os ciclos deve enfatizar o significado da repetição das mesmas ações e somente então - projetá-las usando o design. Portanto, antes de fornecer a sintaxe do loop, você precisa resolver o problema "testa". Uma solução primitiva para o problema do sumário é assim:
Console.WriteLine(""); Console.WriteLine(" 1"); Console.WriteLine(" 2"); Console.WriteLine(" 3"); Console.WriteLine(" 4"); Console.WriteLine(" 5"); Console.WriteLine(" 6"); Console.WriteLine(" 7"); Console.WriteLine("");
Como pode ser melhorado?
Substitua ações repetitivas por um loop.
Quais ações são repetidas em uma linha sem alterações?
Não há neste fragmento. No entanto, o comando para gerar a palavra "Capítulo" com o número é muito semelhante um ao outro.
Portanto, o próximo passo é a busca pela diferença entre os fragmentos. É somente nessa tarefa que tudo é óbvio, então não serão repetidos comandos únicos, mas blocos de código de 5 linhas ou mais. Você terá que pesquisar não apenas na lista de comandos, mas em construções de ramificação ou loop.
No exemplo, a diferença entre as equipes no número após a palavra "Capítulo".
Uma vez que a diferença é encontrada, você precisa entender o padrão de mudança. Um fragmento diferente é esse número? Está constantemente aumentando ou diminuindo? Como o valor de um número muda entre duas equipes lado a lado?
No exemplo, o número após a palavra “Capítulo” aumenta com a etapa 1. A diferença é encontrada, o padrão é revelado. Agora você pode substituir o fragmento diferente por uma variável.
Essa variável deve ser declarada antes do primeiro dos fragmentos repetidos. Essa variável é geralmente chamada I ou j ou, de alguma forma, mais expandida. Seu valor inicial deve ser igual ao primeiro valor exibido na tela. No exemplo, o primeiro valor é 1.
Qual valor inicial deve ser tomado para gerar uma série de números "100, 101, 102, 103, 104, 105"?
Nesta linha, o primeiro número é 100.
Após cada comando de saída, você precisa aumentar o valor dessa variável em 1. Esta unidade é uma etapa de alteração.
Qual passo será na série de números "100, 102, 104, 106"?
Nesta linha, etapa 2.
Depois de substituir o fragmento diferente por uma variável, o código ficará assim:
Console.WriteLine(""); int i; i = 0; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(" " + i); i = i + 1; Console.WriteLine("");
Depois de aplicar a técnica "expressar a lei da variável", o código gera vários grupos de ações idênticas que se seguem. Agora, ações repetidas podem ser substituídas por um loop.
A sequência de solução do problema em que você precisa usar ciclos consiste nas etapas:
- Resolva a “testa” com muitas equipes separadas
- Encontre um padrão
- Expressar a regularidade de uma variável
- Design como um loop
Em seguida, novos termos são introduzidos para que o aluno não se encontre na situação "eu entendo tudo, mas não posso dizer":
- um contador é sempre uma variável necessária para rastrear o número de etapas em um ciclo. Geralmente um número inteiro que é comparado a uma restrição.
- counter step - uma descrição do padrão de alteração no contador.
- restrição - um número ou uma variável com a qual o contador é comparado, para que o algoritmo seja finito. O valor do contador muda para se aproximar do limite.
- corpo do ciclo - um conjunto de comandos que serão repetidos. Quando diz "o comando está escrito dentro do ciclo", significa o corpo.
- iteração de loop - uma única execução do corpo do loop.
- uma condição de loop é uma expressão lógica que determina se outra iteração será executada. (Pode haver confusão com os desenhos das filiais)
Você precisa estar preparado para o fato de que, a princípio, os alunos usarão os termos para outros fins. Isso se aplica a fortes e fracos. Construir uma linguagem comum é uma arte completa. Escreverei brevemente agora: você precisa definir a tarefa "selecionar um fragmento de código com <term>" e usar esses termos em uma conversa corretamente.
Após a conversão com um loop, um fragmento é obtido:
Console.WriteLine(""); int i = 0; while (i < 7) { Console.WriteLine(" " + i); i = i + 1; } Console.WriteLine("");
Equívoco principal
Um equívoco popular dos estudantes é que eles colocam dentro da estrutura do loop ações que precisam ser realizadas apenas uma vez. Por exemplo, assim:
; int i = 0; while (i < 7) { Console.WriteLine("") Console.WriteLine(" " + i); i = i + 1; Console.WriteLine(""); }
Os alunos constantemente se deparam com esse problema, tanto no começo quanto em tarefas mais complexas.
Dica da coroa neste caso:
Quantas vezes você precisa repetir o comando: uma ou várias?
Os comandos de saída para as palavras "Introdução" e "Conclusão", bem como a declaração e inicialização da variável i, não são como outras ações repetitivas. Eles são executados apenas uma vez, o que significa que precisam ser gravados fora do corpo do ciclo.
Todos os três estágios da solução devem permanecer no código, para consultá-los em caso de dificuldade. As duas primeiras opções são suficientes para comentar, para que não interfiram.
A atenção do aluno deve ser dada aos seguintes fatos:
- Em uma condição de loop, o contador e o limite são geralmente comparados. O contador pode mudar no corpo do loop, mas o limite não é. Para quebrar essa regra, você precisa formular boas razões.
- Os comandos para exibir as palavras "Introdução" e "Conclusão" estão fora do corpo do ciclo. Precisamos executá-los uma vez. "Introdução" - antes de repetir ações, "Conclusão" - depois.
No processo de corrigir esse tópico, dominando o seguinte, bem como os procedimentos com dificuldades, é útil até mesmo estudantes fortes fazerem a pergunta: “Mas quantas vezes essa ação precisa ser executada? Um ou muitos?
Desenvolvimento de habilidades adicionais
No processo de estudar ciclos, os alunos ainda têm a habilidade de diagnosticar e resolver problemas. Para realizar o diagnóstico, o aluno precisa apresentar o resultado desejado e compará-lo com o resultado real. As ações para correção dependem da diferença entre elas.
Como os alunos nessa etapa ainda têm uma péssima idéia do resultado "desejado", eles podem se concentrar nos dados do teste. Como regra, ninguém nesta fase ainda entende o que pode dar errado e como lidar com isso. Portanto, dou uma descrição dos problemas típicos e várias maneiras de resolvê-los em uma entrada em um caderno. A escolha dos mais adequados deles é tarefa do próprio aluno.
O registro é necessário para perguntar: “O que aconteceu era esperado?”, “Qual dessas situações aconteceu agora?”, “A solução ajudou?”.
- O número de ações é 1 menor ou mais que o esperado. Maneiras de resolver:
- aumente o valor inicial do contador em 1.
- substitua o operador de comparação estrita (<ou>) por um operador não estrito (<= ou> =).
- altere o valor da restrição para 1. - As ações no loop são executadas sem parar, sem parar. Maneiras de resolver:
- adicione um comando de troca de contador se estiver ausente.
- corrija o comando de troca de contador para que seu valor se aproxime do limite.
- remova o comando para alterar a restrição, se estiver no corpo do ciclo. - O número de ações no loop é mais que 1 menos ou mais que o esperado. A ação no loop nunca foi executada. Primeiro, você precisa descobrir os valores reais das variáveis imediatamente antes do início do ciclo. Maneiras de resolver:
- altera o valor inicial da restrição
- alterar o valor inicial do contador
Geralmente, o problema 3 está relacionado ao uso da variável incorreta ou ao não zerar o contador.
Após esta explicação, o aluno ainda pode ter vários conceitos errados sobre a operação dos ciclos.
Para dissipar o mais comum, eu dou tarefas:
- Na qual a restrição, o valor inicial do contador ou a etapa do contador é inserido pelo usuário.
- No qual o valor do contador deve ser usado em alguma expressão aritmética. É aconselhável com o contador na expressão radical ou no denominador, para que a diferença seja não linear.
- No qual o valor do contador não é exibido durante o ciclo. Por exemplo, a saída do número necessário de fragmentos de texto idênticos ou desenhe uma figura com gráficos de tartaruga.
- Na qual você precisa executar primeiro algumas ações repetidas e depois outras.
- Em que você precisa executar outras ações antes e depois de repetir
Para cada tarefa, você precisa fornecer dados de teste e o resultado esperado.
Para entender a rapidez com que você pode se mover, você precisa ler as condições dessas tarefas e perguntar: “como elas diferem do exemplo?”, “O que precisa ser alterado no exemplo para resolvê-las?”. Se o aluno responder de maneira significativa, deixe-o decidir pelo menos um da lição e o restante - em casa por conta própria. Se a solução for bem-sucedida, você poderá começar a explicar as condições dentro dos loops.
Se você tiver uma solução independente para as dificuldades, precisará resolver tudo da lição. Para que a solução do problema não se assemelhe a desenhar uma coruja, recomendo que você primeiro resolva o problema de maneira não universal. Ou seja, para que a solução passe no primeiro teste e não use a construção de loop. Bem, aplique as transformações para alcançar a universalidade da solução.
Loops e Ramos
Na minha opinião, é útil fornecer o tópico "loops inside branches" separadamente. Para que mais tarde você possa ver a diferença entre uma verificação de várias condições e uma única.
As tarefas para correção serão sobre a saída de números de A a B, que são inseridos pelo usuário:
- sempre ascendente.
- ascendente ou descendente, dependendo dos valores de A e B.
O tópico "ramificação dentro de ciclos" deve ser passado somente depois que o aluno dominar os truques: "substituindo padrões por uma variável" e "substituindo ações repetidas por um loop".
O principal motivo para usar ramificações dentro de loops é anomalias nos padrões. No meio, ele está quebrado, dependendo dos dados de origem.
Para os alunos que são capazes de procurar uma solução combinando técnicas simples, basta dizer que "a ramificação pode ser escrita dentro de loops" e atribuir a tarefa "por exemplo" completamente a uma solução independente.
Tarefa por exemplo:
O usuário digita o número X. Mostre nos números da coluna de 0 a 9 e coloque o sinal '+' oposto ao número igual a X.
Se 0 foi inserido0+
1
2
3
4
5
6
7
8
9
Se 6 foi inserido0 0
1
2
3
4
5
6+
7
8
9
Se 9 foi inserido0 0
1
2
3
4
5
6
7
8
9+
Se 777 foi inserido0 0
1
2
3
4
5
6
7
8
9
Se uma breve explicação não for suficiente para escrever com um loop, você precisará obter uma solução universal para o mesmo problema sem um loop.
Você receberá uma das duas opções:
Desejado string temp; temp = Console.ReadLine(); int x; x = int.Parse(temp); if (x==0) { Console.WriteLine(0 + "+"); } else { Console.WriteLine(0); } if (x==1) { Console.WriteLine(1 + "+"); } else { Console.WriteLine(1); } if (x==2) { Console.WriteLine(2 + "+"); } else { Console.WriteLine(2); } if (x==3) { Console.WriteLine(3 + "+"); } else { Console.WriteLine(3); } if (x==4) { Console.WriteLine(4 + "+"); } else { Console.WriteLine(4); } if (x==5) { Console.WriteLine(5 + "+"); } else { Console.WriteLine(5); } if (x==6) { Console.WriteLine(6 + "+"); } else { Console.WriteLine(6); } if (x==7) { Console.WriteLine(7 + "+"); } else { Console.WriteLine(7); } if (x==8) { Console.WriteLine(8 + "+"); } else { Console.WriteLine(8); } if (x==9) { Console.WriteLine(9 + "+"); } else { Console.WriteLine(9); }
Possível string temp; temp = Console.ReadLine(); int x; x = int.Parse(temp); if (x==0) { Console.WriteLine("0+\n1\n2\n3\n4\n5\n6\n7\n8\n9"); } if (x==1) { Console.WriteLine("0\n1+\n2\n3\n4\n5\n6\n7\n8\n9"); } if (x==2) { Console.WriteLine("0\n1\n2+\n3\n4\n5\n6\n7\n8\n9"); } if (x==3) { Console.WriteLine("0\n1\n2\n3+\n4\n5\n6\n7\n8\n9"); } if (x==4) { Console.WriteLine("0\n1\n2\n3\n4+\n5\n6\n7\n8\n9"); } if (x==5) { Console.WriteLine("0\n1\n2\n3\n4\n5+\n6\n7\n8\n9"); } if (x==6) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6+\n7\n8\n9"); } if (x==7) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6\n7+\n8\n9"); } if (x==8) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6\n7\n8+\n9"); } if (x==9) { Console.WriteLine("0\n1\n2\n3\n4\n5\n6\n7\n8\n9+"); }
Eu dou um problema semelhante antecipadamente, enquanto estudava o tópico de ramificação.
Se o aluno tiver uma opção "possível", será necessário informar que pode haver muitas soluções para o mesmo problema. No entanto, eles diferem em sua resistência às mudanças nos requisitos. Faça a pergunta: "Quantos lugares no código precisarão ser corrigidos se você precisar adicionar outro número?" Na versão "possível", você precisará adicionar outra ramificação e adicionar um novo número em 10 outros lugares. No "desejado", basta adicionar apenas um ramo.
Defina a tarefa para reproduzir a opção "desejada", encontre um padrão no código, execute uma substituição de variável e escreva um loop.
Se você tem uma idéia de como resolver esse problema sem um loop de outra maneira, escreva nos comentários.
Loops dentro de loops
Nesta discussão, você precisa prestar atenção ao fato de que:
- Os contadores para o loop interno e externo devem ser variáveis diferentes.
- o contador do loop interno precisa ser redefinido várias vezes (ou seja, no corpo do loop externo).
- nas tarefas de saída de texto, não é possível primeiro escrever uma letra em várias linhas e depois a segunda. Primeiro você precisa imprimir todas as letras da primeira linha, depois todas as letras da segunda e assim por diante.
É melhor começar uma explicação do tópico sobre loops dentro de loops, explicando a importância de redefinir o contador.
Tarefa por exemplo:
O usuário digita dois números: R e T. Imprima duas linhas de caracteres "#". A primeira linha deve conter caracteres R. A segunda linha são T pedaços. Se qualquer número for negativo, exiba uma mensagem de erro.
R = 5, T = 11#####
############
R = 20, T = 3######################
###
R = -1, T = 6O valor de R deve ser não negativo
R = 6, T = -2O valor de T deve ser não negativo
Obviamente, esse problema também tem pelo menos duas soluções.
Desejado string temp; int R; int T; temp = Console.ReadLine(); R = int.Parse(temp); temp = Console.ReadLine(); T = int.Parse(temp); int i = 0; while (i < R) { Console.Write("#"); i = i + 1; } Console.WriteLine(); i = 0; while (i < T) { Console.Write("#"); i = i + 1; }
Possível No. 1 string temp; int R; int T; temp = Console.ReadLine(); R = int.Parse(temp); temp = Console.ReadLine(); T = int.Parse(temp); int i = 0; while (i < R) { Console.Write("#"); i = i + 1; } Console.WriteLine(); int j = 0; j = 0; while (j < T) { Console.Write("#"); j = j + 1; }
A diferença é que, na solução "possível", a segunda variável foi usada para exibir a segunda linha. Você precisa insistir em usar a mesma variável para os dois ciclos. Pode-se argumentar por essa limitação, pois uma solução com um contador por dois ciclos será uma ilustração do termo “zeramento do contador”. É necessário entender este termo ao resolver os seguintes problemas. Como compromisso, você pode salvar as duas soluções para o problema.
Um problema típico com o uso de uma única variável de contador por dois ciclos aparece da seguinte maneira:
O número de caracteres na segunda linha não corresponde ao valor de T. Se for necessária ajuda com esse problema, será necessário "enfiar o nariz" na sinopse sobre os problemas típicos dos loops. Este é o sintoma número 3. É diagnosticado se você adicionar a saída do valor do contador imediatamente antes do segundo ciclo. Corrigido por zerar. Mas é melhor não contar imediatamente. O aluno deve tentar formular pelo menos uma hipótese.
Obviamente, ainda existe essa solução. Mas eu nunca o vi entre os estudantes. Na fase de estudar os ciclos, a história sobre ele dispersará a atenção. Você pode retornar mais tarde ao estudar as funções de trabalhar com strings.
Número possível 2 string temp; int R; int T; temp = Console.ReadLine(); R = int.Parse(temp); temp = Console.ReadLine(); T = int.Parse(temp); Console.WriteLine(new String('#', R)); Console.WriteLine(new String('#', T));
A próxima tarefa necessária:
Exiba os números de 0 a 9. Cada dígito deve estar em sua própria linha. O número de dígitos por linha (W) é inserido no teclado.
W = 100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
Se um aluno dominar a técnica de substituir uma variável, ele lidará rapidamente. Um possível problema estará novamente em zerar a variável. Se você não consegue lidar com a conversão, está com pressa e precisa resolver problemas mais simples.
Obrigado pela atenção.
Como, assine o canal.PS Se você encontrar erros de digitação ou erros no texto, entre em contato.
Isso pode ser feito destacando parte do texto e pressionando “⌘ + Enter” no Mac e nos teclados clássicos “Ctrl / Enter” ou através de mensagens privadas. Se essas opções não estiverem disponíveis, escreva sobre erros nos comentários. Obrigada