Baderous Posted May 13, 2008 at 02:23 PM Report Share #184826 Posted May 13, 2008 at 02:23 PM O título pode não ser muito esclarecedor mas passo a explicar. Tenho um professor que exige que utilizemos determinadas regras a programar: - Ciclos for são usados para iterar sobre todos os elementos de um conjunto/colecção/array/wtv. - Ciclos while e do while são usados com uma condição booleana de paragem e são usados para iterar sobre 0 ou mais elementos de um conjunto/colecção/array/wtv (os que verifiquem a condição). - Não se deve usar break dentro de for, na tentativa de implementar um while. Passo a citar: Note-se que sendo a condição_de_iteração testada antes da primeira execução do corpo, pode acontecerque, sendo a primeira imediatamente falsa, este não seja executado. Assim, a principal característica determinante na utilização de uma estrutura repetitiva do tipo while é que a mesma conduz a 0 ou mais iterações do corpo de instruções a iterar. O número de iterações que serão efectivamente realizadas não pode nestes casos ser expresso apenas em função dos sucessivos valores tomados por uma variável de controlo. Quando o número de iterações pode de facto ser expresso de tal forma, a estrutura aconselhada é uma estrutura repetitiva do tipo for. É, no entanto, curioso verificar que os programadores, por erro conceptual ou simples hábito que não se aconselha que seja reproduzido, implementam estruturas while através de estruturas for, quer usando break, quer através de condições adicionais de saída na expressão de condição_de_saída do ciclo for. Aconselha-se vivamente que, sempre que pretendermos expressar uma iteração que pode ocorrer 0 ou mais vezes, se expresse tal facto usando uma estrutura while. Sempre que pretendermos expressar uma iteração que ocorre tantas vezes quantos os valores que uma dada variável deve tomar para que, qualquer que seja o incremento, partindo de um dado valor atinja um outro, então, tal deve ser codificado usando uma estrutura for. Eu agora pergunto: Qual é a diferença, para além da estética e da parte conceptual, entre usar um for com um break ou usar um while? Penso que a maior diferença será ao nível do código Assembly gerado... Link to comment Share on other sites More sharing options...
Warrior Posted May 13, 2008 at 03:15 PM Report Share #184832 Posted May 13, 2008 at 03:15 PM Julgo que o teu professor diz isso por razões conceptuais. Mas há situações em que o break/condição extra facilita muito. Exemplo: Imprimir uma matriz respeitando a seguinte regra: nenhum número numa linha deve ser impresso se tiver sido impresso um 0 nessa linha. um código como este: for (int i=0;i<lines;i++) { for (int j=0;j<cols;j++) { cout << m[i][j] << " "; if (!m[i][j]) break; } cout << endl; } Implementar isto com while dá um bocado mais trabalho.. Link to comment Share on other sites More sharing options...
Baderous Posted May 13, 2008 at 03:34 PM Author Report Share #184835 Posted May 13, 2008 at 03:34 PM Pois dá, mas se se justificasse a um nível para além do conceptual, eu até entendia, mas fazer isso só porque sim, não me agrada muito... Link to comment Share on other sites More sharing options...
mogers Posted May 13, 2008 at 04:57 PM Report Share #184845 Posted May 13, 2008 at 04:57 PM Não usar break ou goto são velhas "boas práticas de programação", com as quais eu concordo. Através de condições, consegue-se sempre fazer um programa sem eles e bem estruturado. Claro que admito que use o break as vezes, mas eu prefiro não usar. "What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação. Link to comment Share on other sites More sharing options...
Warrior Posted May 13, 2008 at 05:21 PM Report Share #184847 Posted May 13, 2008 at 05:21 PM Atenção que eu prefiro não usar, mas em situações como aquela que eu descrevi o break vem "limpar" o código. Goto's nunca utilizo. Link to comment Share on other sites More sharing options...
Betovsky Posted May 13, 2008 at 06:03 PM Report Share #184855 Posted May 13, 2008 at 06:03 PM Hehe eu vou ser do contra. Eu gosto de usar breaks e continues, obviamente moderadamente. Mas uso bastante para criar algo tipo guardas. Acho que torna o código mais legível e mais facilmente editável a futuras alterações. Imaginemos que tenho uma colecção de um certo tipo de objectos, e quero os processar de alguma forma conforme certas propriedades dos mesmos. Se há partida não souber que todos os meus elementos respeitam essas propriedades, só tenho duas alternativas: - Filtrar previamente os elementos obtendo uma sub-colecção dos elementos e então é que vou iterar sobre essa para processar os elementos. - Itero sobre todos os elementos todas da colecção mas apenas processo os que são válidos. 90% dos casos a segunda abordagem é melhor, já que aplico uma fusão dos loops. Agora se não formos usar breaks ou continues, o código ficaria algo como: for(Tipo x; ...) { if(condicao1 x || condicao 2 || (condicao3 && condicao4)) { O elemento x é válido Toda a lógica vai é inserida aqui ... } } Eu pessoalmente não gosto nada disto. Prefiro mais desta forma: for(Tipo x; ...) { if (condicao1 x) continue; if (condicao2 x) continue; if (condicao3 x && condicao4 x) continue; O elemento x é válido Toda a lógica vai é inserida aqui ... } } Acho que torna o código mais legível. E qualquer alteração nos "filtros" é muito mais agradável. Para além que detesto ver blocos de código enormes (reminiscência de Haskell??) e no 1º caso normalmente resulta em blocos de if enormes... Agora o que eu não percebo é a diferenciação do prof perante os fors e whiles. O for é um while só tem é uma sintaxe mais agradável para o programador. "Give a man a fish and he will eat for a day; Teach a man to fish and he will eat for a lifetime. The moral? READ THE MANUAL !" Sign on a computer system consultant's desk Link to comment Share on other sites More sharing options...
DanielAmorim Posted May 13, 2008 at 06:16 PM Report Share #184859 Posted May 13, 2008 at 06:16 PM Acho que torna o código mais legível. E qualquer alteração nos "filtros" é muito mais agradável. Para além que detesto ver blocos de código enormes (reminiscência de Haskell??) e no 1º caso normalmente resulta em blocos de if enormes... Para melhorar a legibilidade nesses casos gosto mais de meter uma condição por linha, assim: for(Tipo x; ...) { if(condicao1 x || condicao 2 || (condicao3 && condicao4) ) { O elemento x é válido Toda a lógica vai é inserida aqui ... } } Quanto às questão do for vs while há linguagens (por exemplo php) em que há uma pequena diferença performance e memória utilizada entre os dois loop's, sendo o while o loop mais "leve". No entanto são diferenças mínimas e penso que não se justifica cuidados especiais... Eu escolho o while ou for em função do problema que tenho para resolver... se tenho de contagem uso o for, se é para testar uma condição uso o while. Daniel Amorim VP for xRTML http://www.xrtml.org http://www.realtime.co Link to comment Share on other sites More sharing options...
TheDark Posted May 13, 2008 at 07:22 PM Report Share #184875 Posted May 13, 2008 at 07:22 PM Implementar isto com while dá um bocado mais trabalho.. Então e se for com 2 whiles? 😉 :😛 Penso que assim o trabalho seria o mesmo, embora o for seja mais indicado para o caso 😁 Desaparecido. Link to comment Share on other sites More sharing options...
Warrior Posted May 13, 2008 at 09:11 PM Report Share #184901 Posted May 13, 2008 at 09:11 PM Então e se for com 2 whiles? 😉 :😛 Penso que assim o trabalho seria o mesmo, embora o for seja mais indicado para o caso 😁 Nunca ponderei implementar só com um.. Mas ficaria algo assim: int i=0; while (i<lines) { int j=-1; do { j++; cout << m[i][j] << " "; } while(m[i][j] && j+1<cols); i++; cout << endl; } Sinceramente, só para não usar um break, este código feio.. Só queremos varrer uma matriz! Link to comment Share on other sites More sharing options...
djthyrax Posted May 13, 2008 at 09:23 PM Report Share #184907 Posted May 13, 2008 at 09:23 PM Não obrigatoriamente. int i=0, j = 0; while (i<lines) { j = 0; do { cout << m[i][j++] << " "; } while(m[i][j] && j+1<cols); i++; cout << endl; } 😁 Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum! Link to comment Share on other sites More sharing options...
Warrior Posted May 13, 2008 at 09:44 PM Report Share #184914 Posted May 13, 2008 at 09:44 PM Esse programa não chega a imprimir o 0 (a menos que esteja na primeira linha) e vai imprimir números depois dele se estiver na primeira posição. Não estou a dizer que não é possível fazer mais pequeno sem breaks, mas acho que já demonstrei que HÁ casos em que dá muito jeito. Link to comment Share on other sites More sharing options...
DanielAmorim Posted May 13, 2008 at 09:49 PM Report Share #184917 Posted May 13, 2008 at 09:49 PM Já agora... brincando um pouco com while's int i = -1, j = -1; while(++i < lines){ while(++j < cols ){ cout << m[i][j] << " "; }while(m[i][j]); j = -1; cout << endl; } 😁 Daniel Amorim VP for xRTML http://www.xrtml.org http://www.realtime.co Link to comment Share on other sites More sharing options...
Warrior Posted May 13, 2008 at 10:06 PM Report Share #184922 Posted May 13, 2008 at 10:06 PM isso não é válido, nem compila.. Link to comment Share on other sites More sharing options...
DanielAmorim Posted May 13, 2008 at 10:21 PM Report Share #184931 Posted May 13, 2008 at 10:21 PM isso não é válido, nem compila.. Não tenho aqui nenhum compilador de C mesmo para testar, mas penso que é possivel fazer isso. Mas essa construção é válida por exemplo em C# (testado 😁) Daniel Amorim VP for xRTML http://www.xrtml.org http://www.realtime.co Link to comment Share on other sites More sharing options...
djthyrax Posted May 13, 2008 at 10:41 PM Report Share #184941 Posted May 13, 2008 at 10:41 PM Esse programa não chega a imprimir o 0 (a menos que esteja na primeira linha) e vai imprimir números depois dele se estiver na primeira posição. Não estou a dizer que não é possível fazer mais pequeno sem breaks, mas acho que já demonstrei que HÁ casos em que dá muito jeito. Não imprime o 0 porquê? Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum! Link to comment Share on other sites More sharing options...
TheDark Posted May 13, 2008 at 10:57 PM Report Share #184946 Posted May 13, 2008 at 10:57 PM Sinceramente, só para não usar um break, este código feio.. Só queremos varrer uma matriz! Não percebi que estavas a dizer que era sem break. isso não é válido, nem compila.. Se leste o que estava aqui antes, esquece o que perguntei :😁 Mas a verdade é que compila... O código é válido. Entra é em ciclo infinito... e não pára no 0. Desaparecido. Link to comment Share on other sites More sharing options...
DanielAmorim Posted May 14, 2008 at 12:25 AM Report Share #184965 Posted May 14, 2008 at 12:25 AM Se leste o que estava aqui antes, esquece o que perguntei :😉 Mas a verdade é que compila... O código é válido. Entra é em ciclo infinito... e não pára no 0. É verdade ? aquilo fica a preso no while(m[i][j]) caso o primeiro elemento não seja 0, assim fica a imprimir 1 até mais não.. ups! Lembrei-me dessa construção e mandei o código sem pensar bem no assunto... 😁 Daniel Amorim VP for xRTML http://www.xrtml.org http://www.realtime.co Link to comment Share on other sites More sharing options...
Warrior Posted May 14, 2008 at 01:15 PM Report Share #185029 Posted May 14, 2008 at 01:15 PM Ele compila porque considera isto int i = -1, j = -1; while(++i < lines){ while(++j < cols ){ cout << m[i][j] << " "; } while(m[i][j]); j = -1; cout << endl; } É-lhe indiferente ter o while na linha de cima ou na de debaixo.. Tiracio: não imprimes o 0 porque estás a: imprimir, incrementar, verificar. Ou seja, verificas antes de imprimir. Link to comment Share on other sites More sharing options...
djthyrax Posted May 14, 2008 at 02:04 PM Report Share #185045 Posted May 14, 2008 at 02:04 PM Warrior, a não ser que algo tenha mudado de repente, ele tem i=0, j=0, mostra m[ i][j], incrementa o j, verifica se o próximo está vazio ou não. Logo, imprime o m[0][0]. Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum! Link to comment Share on other sites More sharing options...
Warrior Posted May 14, 2008 at 02:52 PM Report Share #185055 Posted May 14, 2008 at 02:52 PM Não estava a falar do m[0][0], mas sim do valor "0" se estiver armazenado a meio da matriz. Tipo isto: 7 8 9 3 0 4 1 2 3 O teu programa imprime: 7 8 9 3 1 2 3 Quando se falava nisto: 7 8 9 3 0 1 2 3 Já fizemos hijack ao tópico.. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now