Sobre strings de caracteres

23 views
Skip to first unread message

Fabiano Vasconcelos

unread,
Aug 29, 2010, 2:38:24 PM8/29/10
to ccppb...@googlegroups.com
Ol�, amigos dos forums e listas!

Eu t� aqui com uma d�vida cruel. O objetivo do c�digo abaixo �
simplesmente receber strings, linha a linha, e numer�-las antes. At� a�
tudo bem, funciona perfeitamente. Mas eu queria que o programa, quando
encontrasse um cifr�o ($), terminasse a execu��o simplesmente, o que n�o
est� acontecendo de jeito nenhum. Algu�m poderia me dar uma m�o?
Grande abra�o a todos!

#include <stdio.h>
#include <stdlib.h>

int main()
{
int count;
char str[100];
int a;

printf("Editor de texto - teste\n\n");
for(count=1; count<=100; count++) {
if (count<10) printf("0");
printf("%d ", count);
gets(str);

for (a=1; a<=100; a++){
if (str[a]=="\36") break;
}

}

return 0;
}


Eric Chiesse

unread,
Aug 29, 2010, 2:55:54 PM8/29/10
to ccppb...@googlegroups.com
Teu erro está nesta linha:

    if (str[a]=="\36") break;

Vc está usando aspas e não o apóstrofo. Vc quer comparar caracteres e nao strings.

Abraço.

Eric.

Em 29 de agosto de 2010 15:38, Fabiano Vasconcelos <fvasco...@gmail.com> escreveu:
Olá, amigos dos forums e listas!

Eu tô aqui com uma dúvida cruel. O objetivo do código abaixo é simplesmente receber strings, linha a linha, e numerá-las antes. Até aí tudo bem, funciona perfeitamente. Mas eu queria que o programa, quando encontrasse um cifrão ($), terminasse a execução simplesmente, o que não está acontecendo de jeito nenhum. Alguém poderia me dar uma mão?
Grande abraço a todos!


#include <stdio.h>
#include <stdlib.h>

int main()
{
   int count;
   char str[100];
   int a;

   printf("Editor de texto - teste\n\n");
   for(count=1; count<=100; count++) {
       if (count<10) printf("0");
       printf("%d ", count);
       gets(str);

       for (a=1; a<=100; a++){
           if (str[a]=="\36") break;
       }

   }

   return 0;
}


--
Antes de enviar um e-mail para o grupo leia:                     http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
--~--~---------~--~----~---------------------------------~----------~--~----~
[&] Colabore com a Pesquisa de Preferência de Conteúdo              para Eventos do Grupo C & C++ Brasil:
                      http://www.surveymonkey.com/s/GBBGTXN
------~----~-------~---~---~---~---~----------------~------------~---------~
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
Para mais opções, visite http://groups.google.com/group/ccppbrasil
--~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
Emprego & carreira:  vag...@ccppbrasil.org
http://groups.google.com/group/dev-guys?hl=en

Fabiano Vasconcelos

unread,
Aug 29, 2010, 2:59:01 PM8/29/10
to ccppb...@googlegroups.com
Eric, e se eu te disser que eu já usei foi tudo e dá na mesma??? '$', "$", "\36", '\36', "\0x24", '\0x24'...
Aí compilou na boa???

Marcio Gil

unread,
Aug 29, 2010, 3:11:23 PM8/29/10
to ccppb...@googlegroups.com
Seu c�digo est� errado por diversos motivos, vou tentar lista-los para voc�:

Em 29/8/2010 15:38, Fabiano Vasconcelos escreveu:
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int main()
> {
> int count;
> char str[100];
> int a;
>
> printf("Editor de texto - teste\n\n");
> for(count=1; count<=100; count++) {

> if (count<10) printf("0");
> printf("%d ", count);

Sugest�o (n�o � erro): voc� pode substituir estas duas linhas por:

printf("%02d",count);

> gets(str);
>
> for (a=1; a<=100; a++){

Aqui tem um erro:
Em C os vetores tem o �ndice iniciado em zero, ent�o o correto �:

for (a=0; a<100; a++){

Outro problema � que voc� continua percorrendo a linha ap�s o fim dela,
onde h� um monte de lixo (caracteres aleat�rios). Se por acaso houver um
caractere '$' no meio deste lixo seu c�digo n�o vai funcionar. Solu��o:

for (a=0; a<100 && str[a] != '\0'; a++){


> if (str[a]=="\36") break;

Dois erros:
1 - Voc� colocou aspas duplas no lugar de aspas simples;
2 - O sequ�ncia '\36' � em octal (base 8) ent�o voc� na verdade est�
procurando o caracter 30 que nunca vai encontrar, o n�mero 36(base 10)
em octal � 44(base 8)

Corre��o:

if (str[a]=='\44') break;

Mas ficaria mais simples assim:

if (str[a]=='$') break;

> }

Outro erro:

O comando 'break' sai do primeiro la�o, mas n�o do segundo. Duas solu��es:

for (a=0; a<100 && str[a] != '\0'; a++){
if (str[a]=='\44')
break;
}
if (a<100 && str[a] != '\0')
break;
}

Ou

for (a=0; a<100 && str[a] != '\0'; a++){
if (str[a]=='\44')
goto fimdolaco;
}
}
fimdolaco:


>
> }
>
> return 0;
> }
>
>

C�digo sugerido completo:

#include <stdio.h>
#include <stdlib.h>

int main()
{
int count;
char str[100];
int a;

printf("Editor de texto - teste\n\n");
for(count=1; count<=100; count++)
{

printf("%02d ", count);
gets(str);

for (a=0; a<100 && str[a] != '\0'; a++){
if (str[a]=='$')
goto fimdolaco;
}
}
fimdolaco:

return 0;
}

Eric Chiesse

unread,
Aug 29, 2010, 3:12:52 PM8/29/10
to ccppb...@googlegroups.com
Nao tinha tentado ainda. Dá warnings. Vc não mencionou isso. A minha correção resolve um warning nao o outro.

Vi que vc tb nao sai do loop externo. Verifica isso.

Abraço

Eric

Eric Chiesse

unread,
Aug 29, 2010, 3:26:18 PM8/29/10
to ccppb...@googlegroups.com
Márcio, só um comentário. Por favor não entenda como reclamaçao, não quero começar uma flame.

Podíamos ter dado ao Fabiano a chance de achar a solução final sem dar o código pronto.

É só uma lembrança pra ajudar o pessoal que tá começando.

Mas enfim, cada um com sua abordagem. Sem stress.

Abraço.

Eric.

Em 29 de agosto de 2010 16:11, Marcio Gil <marci...@bol.com.br> escreveu:
Seu código está errado por diversos motivos, vou tentar lista-los para você:


Em 29/8/2010 15:38, Fabiano Vasconcelos escreveu:


#include <stdio.h>
#include <stdlib.h>

int main()
{
int count;
char str[100];
int a;

printf("Editor de texto - teste\n\n");
for(count=1; count<=100; count++) {

if (count<10) printf("0");
printf("%d ", count);
Sugestão (não é erro): você pode substituir estas duas linhas por:


printf("%02d",count);


gets(str);

for (a=1; a<=100; a++){

Aqui tem um erro:
Em C os vetores tem o índice iniciado em zero, então o correto é:


for (a=0; a<100; a++){

Outro problema é que você continua percorrendo a linha após o fim dela, onde há um monte de lixo (caracteres aleatórios). Se por acaso houver um caractere '$' no meio deste lixo seu código não vai funcionar. Solução:


for (a=0; a<100 && str[a] != '\0'; a++){



if (str[a]=="\36") break;

Dois erros:
1 - Você colocou aspas duplas no lugar de aspas simples;
2 - O sequência '\36' é em octal (base 8) então você na verdade está procurando o caracter 30 que nunca vai encontrar, o número 36(base 10) em octal é 44(base 8)

Correção:


if (str[a]=='\44') break;

Mas ficaria mais simples assim:

if (str[a]=='$') break;

}

Outro erro:

O comando 'break' sai do primeiro laço, mas não do segundo. Duas soluções:


   for (a=0; a<100 && str[a] != '\0'; a++){
     if (str[a]=='\44')
       break;
   }
   if (a<100 && str[a] != '\0')
     break;
 }

Ou

   for (a=0; a<100 && str[a] != '\0'; a++){
     if (str[a]=='\44')
       goto fimdolaco;
   }
 }
fimdolaco:



}

return 0;
}



Código sugerido completo:


#include <stdio.h>
#include <stdlib.h>

int main()
{
 int count;
 char str[100];
 int a;

 printf("Editor de texto - teste\n\n");
 for(count=1; count<=100; count++)
 {
   printf("%02d ", count);
   gets(str);

   for (a=0; a<100 && str[a] != '\0'; a++){
     if (str[a]=='$')
       goto fimdolaco;
   }
 }
fimdolaco:


 return 0;
}

Marcio Gil

unread,
Aug 29, 2010, 3:32:25 PM8/29/10
to ccppb...@googlegroups.com
Pois �, minha falha foi ter listado o c�digo completo no final...

Mas de qualquer forma ele j� tinha quebrado a cabe�a mesmo :-)

Em 29/8/2010 16:26, Eric Chiesse escreveu:
> M�rcio, s� um coment�rio. Por favor n�o entenda como reclama�ao, n�o
> quero come�ar uma flame.
>
> Pod�amos ter dado ao Fabiano a chance de achar a solu��o final sem dar o
> c�digo pronto.
>
> � s� uma lembran�a pra ajudar o pessoal que t� come�ando.


>
> Mas enfim, cada um com sua abordagem. Sem stress.
>

> Abra�o.
>
> Eric.
>

Eric Chiesse

unread,
Aug 29, 2010, 3:58:17 PM8/29/10
to ccppb...@googlegroups.com
Suspeitei desde o princípio !!

Tranquilo.

Abraço.

Eric.

Em 29 de agosto de 2010 16:32, Marcio Gil <marci...@bol.com.br> escreveu:
Pois é, minha falha foi ter listado o código completo no final...

Mas de qualquer forma ele já tinha quebrado a cabeça mesmo :-)


Em 29/8/2010 16:26, Eric Chiesse escreveu:
Márcio, só um comentário. Por favor não entenda como reclamaçao, não
quero começar uma flame.

Podíamos ter dado ao Fabiano a chance de achar a solução final sem dar o
código pronto.

É só uma lembrança pra ajudar o pessoal que tá começando.


Mas enfim, cada um com sua abordagem. Sem stress.

Abraço.

Eric.


Fabiano Vasconcelos

unread,
Aug 29, 2010, 4:03:33 PM8/29/10
to ccppb...@googlegroups.com
Bem, pessoal, deixa eu me apresentar:

meu nome � Fabiano Quebra-cabe�as! :D
Podem ter certeza de que se eu postei aqui � porque eu n�o achei a
solu��o nem em google, nem em Herbert Schildt, nem em nada! Aqui � meu
�ltimo recurso.

Bem, daqui a pouco, quando eu fizer o c�digo funcionar, eu volto pra
comentar mais. T� recebendo o bicho agora.
De cara eu vi algo aqui um pouco estranho, se � que o amigo M�rcio me
permite comentar: � que muitos programadores, inclusive eu (se � que
posso ser rotulado como programador) foram instru�dos com o princ�pio de
NUNCA usar o goto, por ser considerado um mau estilo de programa��o.
Ainda n�o analisei o c�digo pra ver como posso subistitu�-lo, mas sei
que ele n�o � necess�rio. N�o querendo desfazer do seu precios�ssimo
favor, pelo amor de Deus nem sonhe com isso, mas � que a palavra-chave
goto realmente � abominada no meio acad�mico.
Voc� poderia pensar em uma outra solu��o que n�o use goto? Eu vou pensar
aqui e te digo. N�o poste ainda!!! Vou pensar primeiro!!!

Grande abra�o!

Pedro d'Aquino

unread,
Aug 29, 2010, 4:10:34 PM8/29/10
to ccppb...@googlegroups.com
Fabiano, o próprio Márcio já deu uma solução sem goto.

Cuidado com dogmas: goto é perigoso, mas tem seus usos (este caso não
é um deles, na minha opinião).

On Sunday, August 29, 2010, Fabiano Vasconcelos <fvasco...@gmail.com> wrote:
> Bem, pessoal, deixa eu me apresentar:
>

> meu nome é Fabiano Quebra-cabeças! :D
> Podem ter certeza de que se eu postei aqui é porque eu não achei a solução nem em google, nem em Herbert Schildt, nem em nada! Aqui é meu último recurso.
>
> Bem, daqui a pouco, quando eu fizer o código funcionar, eu volto pra comentar mais. Tô recebendo o bicho agora.
> De cara eu vi algo aqui um pouco estranho, se é que o amigo Márcio me permite comentar: é que muitos programadores, inclusive eu (se é que posso ser rotulado como programador) foram instruídos com o princípio de NUNCA usar o goto, por ser considerado um mau estilo de programação. Ainda não analisei o código pra ver como posso subistituí-lo, mas sei que ele não é necessário. Não querendo desfazer do seu preciosíssimo favor, pelo amor de Deus nem sonhe com isso, mas é que a palavra-chave goto realmente é abominada no meio acadêmico.
> Você poderia pensar em uma outra solução que não use goto? Eu vou pensar aqui e te digo. Não poste ainda!!! Vou pensar primeiro!!!
>
> Grande abraço!


>
> On 29-08-2010 16:32, Marcio Gil wrote:
>

> Pois é, minha falha foi ter listado o código completo no final...
>

> Mas de qualquer forma ele já tinha quebrado a cabeça mesmo :-)


>
> Em 29/8/2010 16:26, Eric Chiesse escreveu:
>

> Márcio, só um comentário. Por favor não entenda como reclamaçao, não
> quero começar uma flame.
>
> Podíamos ter dado ao Fabiano a chance de achar a solução final sem dar o
> código pronto.
>

> É só uma lembrança pra ajudar o pessoal que tá começando.


>
> Mas enfim, cada um com sua abordagem. Sem stress.
>

> Abraço.
>
> Eric.

Ivo Calado

unread,
Aug 29, 2010, 4:11:06 PM8/29/10
to ccppb...@googlegroups.com
Olá Fabiano,
    o goto é muitas vezes abominado porque os programadores abusam de sua utilização e acabam quebrando o fluxo do código. A forma ideal de utilização do goto é possibilitar a saída imediata de vários laços, como apresentado no exemplo do Marcio. Se você for tentar implementar uma abordagem sem o goto para esse exemplo (sair de um for duplo) vai acabar, invariavelmente, tendo de fazer alguma gambiarra. Um exemplo de onde o goto é bastante utilizado é na programação para o kernel. Lá o que mais você vai ver é goto.

Espero ter ajudado...
[]'s

2010/8/29 Fabiano Vasconcelos <fvasco...@gmail.com>
Bem, pessoal, deixa eu me apresentar:

meu nome é Fabiano Quebra-cabeças! :D
Podem ter certeza de que se eu postei aqui é porque eu não achei a solução nem em google, nem em Herbert Schildt, nem em nada! Aqui é meu último recurso.

Bem, daqui a pouco, quando eu fizer o código funcionar, eu volto pra comentar mais. Tô recebendo o bicho agora.
De cara eu vi algo aqui um pouco estranho, se é que o amigo Márcio me permite comentar: é que muitos programadores, inclusive eu (se é que posso ser rotulado como programador) foram instruídos com o princípio de NUNCA usar o goto, por ser considerado um mau estilo de programação. Ainda não analisei o código pra ver como posso subistituí-lo, mas sei que ele não é necessário. Não querendo desfazer do seu preciosíssimo favor, pelo amor de Deus nem sonhe com isso, mas é que a palavra-chave goto realmente é abominada no meio acadêmico.
Você poderia pensar em uma outra solução que não use goto? Eu vou pensar aqui e te digo. Não poste ainda!!! Vou pensar primeiro!!!

Grande abraço!


On 29-08-2010 16:32, Marcio Gil wrote:
Pois é, minha falha foi ter listado o código completo no final...

Mas de qualquer forma ele já tinha quebrado a cabeça mesmo :-)


Em 29/8/2010 16:26, Eric Chiesse escreveu:
Márcio, só um comentário. Por favor não entenda como reclamaçao, não
quero começar uma flame.

Podíamos ter dado ao Fabiano a chance de achar a solução final sem dar o
código pronto.

É só uma lembrança pra ajudar o pessoal que tá começando.


Mas enfim, cada um com sua abordagem. Sem stress.

Abraço.

Eric.



--
Antes de enviar um e-mail para o grupo leia:                     http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
--~--~---------~--~----~---------------------------------~----------~--~----~
[&] Colabore com a Pesquisa de Preferência de Conteúdo              para Eventos do Grupo C & C++ Brasil:
                      http://www.surveymonkey.com/s/GBBGTXN
------~----~-------~---~---~---~---~----------------~------------~---------~
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
Para mais opções, visite http://groups.google.com/group/ccppbrasil
--~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
Emprego & carreira:  vag...@ccppbrasil.org
http://groups.google.com/group/dev-guys?hl=en



--
Ivo Augusto Andrade Rocha Calado
PhD candidate in Electrical Engineering
Embedded Systems and Pervasive Computing Lab - http://embedded.ufcg.edu.br
Electrical Engineering Department - http://dee.ufcg.edu.br/
Electrical Engineering and Informatics Center - http://www.ceei.ufcg.edu.br
Federal University of Campina Grande - http://www.ufcg.edu.br

PGP: 0xD7C3860A pgp.mit.edu
Putt's Law:
       Technology is dominated by two types of people:
               Those who understand what they do not manage.
               Those who manage what they do not understand.

Fabiano Vasconcelos

unread,
Aug 29, 2010, 4:09:59 PM8/29/10
to ccppb...@googlegroups.com
Outra coisa, quanto aos Warnings, não dá nenhum aqui. Não sei setar o meu Code::Blocks (gcc) pro nível máximo de alertas. Vou procurar aqui como se faz.

Marcio Gil

unread,
Aug 29, 2010, 4:16:14 PM8/29/10
to ccppb...@googlegroups.com
Em 29/8/2010 17:03, Fabiano Vasconcelos escreveu:
> Bem, pessoal, deixa eu me apresentar:
>
> meu nome � Fabiano Quebra-cabe�as! :D
> Podem ter certeza de que se eu postei aqui � porque eu n�o achei a
> solu��o nem em google, nem em Herbert Schildt, nem em nada! Aqui � meu
> �ltimo recurso.
>
> Bem, daqui a pouco, quando eu fizer o c�digo funcionar, eu volto pra
> comentar mais. T� recebendo o bicho agora.
> De cara eu vi algo aqui um pouco estranho, se � que o amigo M�rcio me
> permite comentar: � que muitos programadores, inclusive eu (se � que
> posso ser rotulado como programador) foram instru�dos com o princ�pio de
> NUNCA usar o goto, por ser considerado um mau estilo de programa��o.
> Ainda n�o analisei o c�digo pra ver como posso subistitu�-lo, mas sei
> que ele n�o � necess�rio. N�o querendo desfazer do seu precios�ssimo
> favor, pelo amor de Deus nem sonhe com isso, mas � que a palavra-chave
> goto realmente � abominada no meio acad�mico.
> Voc� poderia pensar em uma outra solu��o que n�o use goto? Eu vou pensar
> aqui e te digo. N�o poste ainda!!! Vou pensar primeiro!!!
>
> Grande abra�o!
>

Caro Fabiano, acho que voc� n�o reparou que eu j� havia lhe dado suas
sugest�es, uma sem 'goto' e outra com 'goto':

- Solu��o n�mero 1:

(...)


for (a=0; a<100 && str[a] != '\0'; a++){
if (str[a]=='\44')
break;
}

if (a<100 && str[a] != '\0') // <-- Primeira solu��o
break;
}

- Solu��o n�mero 2:

(...)


for (a=0; a<100 && str[a] != '\0'; a++){
if (str[a]=='\44')

goto fimdolaco; // <-- Segunda solu��o, mais eficiente
}
}
fimdolaco:


Agora um informa��o que devo lhe passar � que o 'goto' � abominado para
todos os casos, menos este. Isto porque para sair de dois la�os esta � a
solu��o mais eficiente, foi s� � preciso uma compara��o e n�o duas.

Outra solu��o sem 'goto' � utilizando uma fun��o do C para procurar pelo
caracter:

#include <string.h>
(...)

if (strchr(str,'$') != NULL)
break;
}

// Repare que eu removi o segundo la�o por este 'if'

Marcio Gil

unread,
Aug 29, 2010, 4:48:33 PM8/29/10
to ccppb...@googlegroups.com
Em 29/8/2010 17:16, Marcio Gil escreveu:
> (...)
> for (a=0; a<100 && str[a] != '\0'; a++){
> if (str[a]=='\44')
> goto fimdolaco; // <-- Segunda solu��o, mais eficiente
> }
> }
> fimdolaco:
>
>
> Agora um informa��o que devo lhe passar � que o 'goto' � abominado para
> todos os casos, menos este. Isto porque para sair de dois la�os esta � a
> solu��o mais eficiente, foi s� � preciso uma compara��o e n�o duas.
>

Acho que forcei um pouco a barra dizendo que este � o �nico uso
aceit�vel de goto :-)

O uso do 'goto' pode ser essencial se voc� precisa ter o c�digo mais
eficiente poss�vel. � por isso que o kernel do Linux usa tanto.

Mas posso afirmar que este � um dos poucos usos aceit�veis (sair de
v�rios n�veis de la�o). Me lembrei inclusive que a linguagem D
implementa uma alternativa para este uso espec�fico:

http://www.digitalmars.com/d/1.0/ctod.html#labeledbreak

Ent�o no lugar de:

for(count=1; count<=100; count++)
{
printf("%02d ", count);
gets(str);

for (a=0; a<100 && str[a] != '\0'; a++){

if (str[a]=='$')
goto fimdolaco;
}
}
fimdolaco:

Ter�amos (s� com exemplo):

Laco1: for(count=1; count<=100; count++)


{
printf("%02d ", count);
gets(str);

Laco2: for (a=0; a<100 && str[a] != '\0'; a++){
if (str[a]=='$')
break Laco2;
}
}

Que na verdade � a mesma coisa, s� muda a posi��o do "label" e a troca
da palavra chave "goto" por "break".

Fabiano Vasconcelos

unread,
Aug 29, 2010, 5:08:09 PM8/29/10
to ccppb...@googlegroups.com
Vamos l� aos coments:

On 29-08-2010 16:11, Marcio Gil wrote:
> Seu c�digo est� errado por diversos motivos, vou tentar lista-los para
> voc�:
>
> Em 29/8/2010 15:38, Fabiano Vasconcelos escreveu:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> int main()
>> {
>> int count;
>> char str[100];
>> int a;
>>
>> printf("Editor de texto - teste\n\n");
>> for(count=1; count<=100; count++) {
>
>> if (count<10) printf("0");
>> printf("%d ", count);
> Sugest�o (n�o � erro): voc� pode substituir estas duas linhas por:
>
> printf("%02d",count);

Gostei da dica! Bem mais profissional! :D


>
>> gets(str);
>>
>> for (a=1; a<=100; a++){
>
> Aqui tem um erro:
> Em C os vetores tem o �ndice iniciado em zero, ent�o o correto �:
>
> for (a=0; a<100; a++){

Eu havia come�ado do ZERO em outra tentativa, mas � que no desespero de
fazer funcionar, coloquei esse 1 a� insanamente.


>
> Outro problema � que voc� continua percorrendo a linha ap�s o fim
> dela, onde h� um monte de lixo (caracteres aleat�rios). Se por acaso
> houver um caractere '$' no meio deste lixo seu c�digo n�o vai
> funcionar. Solu��o:
>
> for (a=0; a<100 && str[a] != '\0'; a++){
>

Mas veja, M�rcio, a minha inten��o foi que assim que ele achasse o
carcatere $, independente do que tem pela frente, ele parasse a execu��o
do programa. Com o la�o for ele n�o iria analisar cada caractere, um a
um, e compar�-los pra ver se acha um $? Por que ele continua percorrendo
a string? Por que o break aqui n�o foi funcional? Juro que n�o entendi!

for (a=1; a<=100; a++){

if (str[a]=="\36") break;
> if (str[a]=="\36") break;
>
> Dois erros:
> 1 - Voc� colocou aspas duplas no lugar de aspas simples;
> 2 - O sequ�ncia '\36' � em octal (base 8) ent�o voc� na verdade est�
> procurando o caracter 30 que nunca vai encontrar, o n�mero 36(base 10)
> em octal � 44(base 8)

Eu me baseei na tabela ASCII (http://www.asciitable.com/) pra achar esse
36. L� nesse site e em http://pt.wikipedia.org/wiki/ASCII dizem que $ �
36 em decimal. Mas, pelo que eu acabei de perceber aqui testtando, o que
ele aceta nesse formato � OCTAL mesmo, n�? Pois �. Achei que fosse
decimal! S� por curiosidade: e se eu quisesse usar o mesmo artif�cio,
sendo com decimal?
As aspas duplas foi outra tentativa insana.


>
> Corre��o:
>
> if (str[a]=='\44') break;
>
> Mas ficaria mais simples assim:
>
> if (str[a]=='$') break;
>
>> }
>
> Outro erro:
>
> O comando 'break' sai do primeiro la�o, mas n�o do segundo. Duas
> solu��es:
>
> for (a=0; a<100 && str[a] != '\0'; a++){
> if (str[a]=='\44')
> break;
> }
> if (a<100 && str[a] != '\0')
> break;
> }
>

Respondida a pergunta do break.

> Ou
>
> for (a=0; a<100 && str[a] != '\0'; a++){
> if (str[a]=='\44')
> goto fimdolaco;
> }
> }
> fimdolaco:
>
>
>>
>> }
>>
>> return 0;
>> }
>>
>>

Fico com a vers�o sem goto! :D


>
> C�digo sugerido completo:
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int main()
> {
> int count;
> char str[100];
> int a;
>
> printf("Editor de texto - teste\n\n");
> for(count=1; count<=100; count++)
> {
> printf("%02d ", count);
> gets(str);
>
> for (a=0; a<100 && str[a] != '\0'; a++){
> if (str[a]=='$')
> goto fimdolaco;
> }
> }
> fimdolaco:
>
> return 0;
> }
>

Obrigado pela dica e pode ter certeza de que eu n�o acharia a resposta
por mim mesmo t������o cedo!
Grande abra�o, amigos! :)

Marcio Gil

unread,
Aug 29, 2010, 5:25:14 PM8/29/10
to ccppb...@googlegroups.com
Em 29/8/2010 18:08, Fabiano Vasconcelos escreveu:
> Vamos l� aos coments:
>
>>(...)
>>
>> Outro problema � que voc� continua percorrendo a linha ap�s o fim
>> dela, onde h� um monte de lixo (caracteres aleat�rios). Se por acaso
>> houver um caractere '$' no meio deste lixo seu c�digo n�o vai
>> funcionar. Solu��o:

>>
>> for (a=0; a<100 && str[a] != '\0'; a++){
>>
> Mas veja, M�rcio, a minha inten��o foi que assim que ele achasse o
> carcatere $, independente do que tem pela frente, ele parasse a execu��o
> do programa. Com o la�o for ele n�o iria analisar cada caractere, um a
> um, e compar�-los pra ver se acha um $? Por que ele continua percorrendo
> a string? Por que o break aqui n�o foi funcional? Juro que n�o entendi!
>
Experimenta fazer assim:

(...)


for (a=0; a<100; a++){

printf( "[%c]", str[a] ); // Mostra o que est� sendo processado


if (str[a]=='$')
break;
}

printf( "\n" ); // S� para melhorar a visualiza��o
if (a<100)
break;
}
return 0;
}

Aqui eu obtive este resultado:

$ gcc editor.c
$ ./a.out


Editor de texto - teste

01 teste
[t][e][s][t][e][]["][]][][][a][][][][][][�]["][][@][][][][][][][][�][5][][a][][][][][][][][][][][][][�][�]["][a][-][c][][a][][][][][U][T][F][-][8][][][a]][][][a][][][][][h][�]["][][�][][][][�][�][][a][][][][][A][S][C][I][I][][][a]][][][a]
02 teste$
[t][e][s][t][e][$]

Viu quanta sujeira? � porque a linguagem C n�o limpa o conte�do
preexistente no espa�o da mem�ria destinado a sua vari�vel 'str'.

Se um destes caracteres fosse '$', o programa seria interrompido mesmo
que o usu�rio n�o digitasse o '$', entendeu?

O que marca o fim da cadeia de caracteres � o caracter zero ou '\0'

> for (a=1; a<=100; a++){
> if (str[a]=="\36") break;
>> if (str[a]=="\36") break;
>>
>> Dois erros:

>> 1 - Voc� colocou aspas duplas no lugar de aspas simples;
>> 2 - O sequ�ncia '\36' � em octal (base 8) ent�o voc� na verdade est�
>> procurando o caracter 30 que nunca vai encontrar, o n�mero 36(base 10)
>> em octal � 44(base 8)


> Eu me baseei na tabela ASCII (http://www.asciitable.com/) pra achar esse

> 36. L� nesse site e em http://pt.wikipedia.org/wiki/ASCII dizem que $ �


> 36 em decimal. Mas, pelo que eu acabei de perceber aqui testtando, o que

> ele aceta nesse formato � OCTAL mesmo, n�? Pois �. Achei que fosse
> decimal! S� por curiosidade: e se eu quisesse usar o mesmo artif�cio,
> sendo com decimal?

Bom neste caso voc� faria assim:

if (str[a]==(char)36) break; // Agora sim 36 � em decimal.

Resumo:
- '$' Literal
- '0x24' Hexadecimal
- '\044' Octal (prefiro assim pois deixa mais claro que � octal)
- '\44' Octal (assim confunde)
- (char)36 Decimal

>
> Obrigado pela dica e pode ter certeza de que eu n�o acharia a resposta
> por mim mesmo t������o cedo!
> Grande abra�o, amigos! :)
>

Disponha.

Fabiano Vasconcelos

unread,
Aug 29, 2010, 6:57:08 PM8/29/10
to ccppb...@googlegroups.com
Tudo perfeitamente entendido, sábio guru!!!
Eu não havia me tocado que no meio desse lixo poderia haver um $, e aquela sintaxe lá do (char)36 eu nem tava me lembrando dela!
Quanto ao goto, vou usar quando não houver saída. Eu mesmo, com a minha pouca experiência em programação, já tive problemas com ele. Mas o que me surpreende - e muito - é saber que o kernel do linux está recheado dele! Mal dá pra acreditar nisso. Mas só transcrevendo o que disse o mestre Herbert Schildt, em "C completo e total", 3ª edição, página 86:

"Uma vez que C tem um rico conjunto de estruturas de controle e permite um controle adicional usando break e continue, há pouca necessidade do goto. A grande preocupação da maioria dos programadores sobre goto é a sua tendência de tornar os programas ilegíveis. Entretanto, embora o goto tenha sido desencorajado a alguns anos atrás, ele tem recentemente polido um pouco a sua imagem manchada. Não há nenhuma situação na programação que necessite do goto. Apesar disso, contudo, goto é uma conveniência que, se usada prudentemente, pode ser uma vantagem em certas situações na programação. Sendo assim, goto não é usado fora dessa seção."

Como os amigos vêem, eu prefiro fazer parte dessa corrente, mais saudável do ponto de vista a forçar a pessoa a pensar em uma saída diferente - estimular o cérebro a fazer algorítimos - e também não quero me arriscar a fazer um novelo de lã incompreenível. Mas é isso aí: em tudo existe divergência. Existem correntes e correntes. Assim como tem que apoie o goto, tem que o abomine e existem os meios-termos. Eu, prefiro não me arriscar. :D

Será que demorará muito pra eu ser programador profissional??? hehehehheh...

Um grande abraço a vocês todos!


On 29-08-2010 18:25, Marcio Gil wrote:
Em 29/8/2010 18:08, Fabiano Vasconcelos escreveu:
Vamos lá aos coments:

(...)

Outro problema é que você continua percorrendo a linha após o fim
dela, onde há um monte de lixo (caracteres aleatórios). Se por acaso
houver um caractere '$' no meio deste lixo seu código não vai
funcionar. Solução:

for (a=0; a<100 && str[a] != '\0'; a++){

Mas veja, Márcio, a minha intenção foi que assim que ele achasse o
carcatere $, independente do que tem pela frente, ele parasse a execução
do programa. Com o laço for ele não iria analisar cada caractere, um a
um, e compará-los pra ver se acha um $? Por que ele continua percorrendo
a string? Por que o break aqui não foi funcional? Juro que não entendi!

Experimenta fazer assim:

(...)
    for (a=0; a<100; a++){
      printf( "[%c]", str[a] ); // Mostra o que está sendo processado
      if (str[a]=='$')
        break;
    }
    printf( "\n" );  // Só para melhorar a visualização
    if (a<100)
      break;
  }
  return 0;
}

Aqui eu obtive este resultado:

$ gcc editor.c
$ ./a.out
Editor de texto - teste

01 teste
[t][e][s][t][e][]["][]][][][a][][][][][][Ð]["][][@][][][][][][][][ð][5][][a][][][][][][][][][][][][][á][›]["][a][-][c][][a][][][][][U][T][F][-][8][][][a]][][][a][][][][][h][Í]["][][À][][][][ƒ][Î][][a][][][][][A][S][C][I][I][][][a]][][][a]
02 teste$
[t][e][s][t][e][$]

Viu quanta sujeira? É porque a linguagem C não limpa o conteúdo
preexistente no espaço da memória destinado a sua variável 'str'.

Se um destes caracteres fosse '$', o programa seria interrompido mesmo
que o usuário não digitasse o '$', entendeu?

O que marca o fim da cadeia de caracteres é o caracter zero ou '\0'

for (a=1; a<=100; a++){
if (str[a]=="\36") break;
if (str[a]=="\36") break;

Dois erros:
1 - Você colocou aspas duplas no lugar de aspas simples;
2 - O sequência '\36' é em octal (base 8) então você na verdade está
procurando o caracter 30 que nunca vai encontrar, o número 36(base 10)
em octal é 44(base 8)
Eu me baseei na tabela ASCII (http://www.asciitable.com/) pra achar esse
36. Lá nesse site e em http://pt.wikipedia.org/wiki/ASCII dizem que $ é
36 em decimal. Mas, pelo que eu acabei de perceber aqui testtando, o que
ele aceta nesse formato é OCTAL mesmo, né? Pois é. Achei que fosse
decimal! Só por curiosidade: e se eu quisesse usar o mesmo artifício,
sendo com decimal?

Bom neste caso você faria assim:

if (str[a]==(char)36) break; // Agora sim 36 é em decimal.

Resumo:
- '$'      Literal
- '0x24'   Hexadecimal
- '\044'   Octal (prefiro assim pois deixa mais claro que é octal)
- '\44'    Octal (assim confunde)
- (char)36 Decimal


Obrigado pela dica e pode ter certeza de que eu não acharia a resposta
por mim mesmo tãããããão cedo!
Grande abraço, amigos! :)


Disponha.


Sulivan

unread,
Aug 29, 2010, 4:45:00 PM8/29/10
to ccppb...@googlegroups.com


    Aeeee irmão, sem goto, mas não está completo. Tá parando a execução quando vc digitar um $ 'solitário' . mas dá pra trabalhar em cima deste algoritmo..

   int main(int argc, char *argv[])
{
  
  
   int count;
 char str[100];


 printf("Editor de texto - teste\n\n");
 for(count=1; count<=100; count++)
 {
   printf("%02d ", count);
   gets(str);

     scanf("%c",&str[count]);
     if (str[count]=='$'){
       system("PAUSE");
       return 0;
       }
  
 }

  
  system("PAUSE");
  return 0;
}

--
Sulivan

"É uma infelicidade da época, que os doidos guiem os cegos."
- William Shakespeare
 

Humberto Pereira

unread,
Aug 29, 2010, 8:54:58 PM8/29/10
to ccppb...@googlegroups.com
Apenas meus 2 centavos,

   já que voce esta ainda aprendendo, tente sempre usar os comandos p/ o que eles foram designados. Voce pode fazer qualquer loop em C com um for, while, do/while, if/goto ou chamando uma funcao recursivamente.

Mas qual é o melhor em cada caso? Usar um for com break, por ex., parece mais o caso de usar um while, nao? Exemplo:

// enquanto a string nao acabar e nao achar o caracter $, vá p/ o proximo
int i = 0;
while(i < 100 && str[i] != 0 && str[i] != '$')
  i++;

Veja, nao existe certo ou errado, existe o mais apropriado e o menos apropriado p/ cada caso.

Eh o caso do goto, usar ele p/ sair de um loop eh um bom indicativo que vc esta fazendo algo errado. Mas existem casos onde ele eh apropriado, como se recuperar de um possivel problema "inesperado" que invalida seu codigo (um arquivo que falhou ao abrir, memoria que nao conseguiu alocar, etc), da mesmoa forma que as linguagens orientadas a objeto usam o try / catch.

[]s
Humberto Pereira

2010/8/29 Fabiano Vasconcelos <fvasco...@gmail.com>

Fabiano Vasconcelos

unread,
Aug 29, 2010, 9:10:56 PM8/29/10
to ccppb...@googlegroups.com
Humbeto e Sulivan:

Obrigado demais pelas dicas! Só enriquece a lista. Isso aqui é um poço de petróleo, uma mina de outro!
Só um detalhe pro Sulivan: system("pause") não funfa no Linux, que é o meu S.O. (pelo menos até onde eu saiba).

Grande abraço! ;)

Virgilio Alexandre Fornazin

unread,
Aug 30, 2010, 8:40:12 AM8/30/10
to ccppb...@googlegroups.com

- system(”PAUSE”) soa tão nostálgico como programar pra M$-DOS em 1993 J...

 

Use getch(), ele faz o que você precisa.

Marcio Gil

unread,
Aug 30, 2010, 9:46:20 AM8/30/10
to ccppbrasil

On 29 ago, 19:57, Fabiano Vasconcelos <fvasconce...@gmail.com> wrote:
> (...) Mas só transcrevendo o que disse o mestre Herbert Schildt,
> em "C completo e total", 3ª edição, página 86:
>
> /"Uma vez que C tem um rico conjunto de estruturas de controle e
> permite um controle adicional usando break e continue, há pouca
> necessidade do goto. A grande preocupação da maioria dos
> programadores sobre goto é a sua tendência de tornar os programas
> ilegíveis. Entretanto, embora o goto tenha sido desencorajado a
> alguns anos atrás, ele tem recentemente polido um pouco a sua
> imagem manchada. *Não há nenhuma situação na programação que
> necessite do goto.* Apesar disso, contudo, goto é uma conveniência
> que, se usada prudentemente, pode ser uma vantagem em certas
> situações na programação. Sendo assim, goto não é usado fora dessa
> seção."/
>
Isto é algo que não vale só para programação, mas para todas as
situações da vida: *SEMPRE* duvide das afirmações absolutas. Mesmo
que isto venha do mestre dos mestres de alguma área.

Veja só a justificativa dos desenvolvedores da linguagem D, que se
propuseram a repensar totalmente a linguagem C++, em manter o 'goto':

http://www.digitalmars.com/d/1.0/ctod.html#goto

Tradução livre: "Muitos usos do 'goto' na linguagem C podem ser
eliminados com o uso de recursos da linguagem D, como o 'labeled
break' e 'labeled continue'. Mas a linguagem D é um linguagem
prática para programadores práticos, que sabem quando as regras
precisam ser quebradas. Então é claro que a linguagem D suporta o
uso do 'goto'."

Vou tentar da um exemplo: cálculo de matrizes. Vamos supor que você
precise percorrer uma lista de matrizes para fazer cálculos, mas se
encontar um zero o cálculo pode ser reduzido, e se encontrar -1 toda
a lista é invalidada:

for (k = 0; k < qtd_matrizes; ++k)
{
for (i = 0; i < m; ++i)
{
for (j = 0; j < n; ++j)
{
switch( matriz[k][i][j] )
{
case 0:
goto fim_matriz;
case -1
goto fim_lista;
default:
(...)
}
}
}
fim_matriz:
(...)
}
fim_lista:
(...)

Imagine que este código precise ser rodado milhões de vezes a fim de
fazer uma simulção. Você poderia substituir os 'gotos' substituindo o
'swith' por 'ifs' e colocando um 'if' adicional em cada nível, mas
isso vai sacrificar a eficiência do seu código. Também poderia
colocar o segundo laço em uma função 'inline', mas aí como fica o
segundo 'goto'?

Por isso eu proponho este desafio: reimplementar o exemplo acima sem
'gotos' e mantendo a mesma eficiência, sem acrescentar comparações
extras.

P.

unread,
Aug 30, 2010, 9:57:16 AM8/30/10
to ccppbrasil
Fabiano Vasconcelos wrote:

> De cara eu vi algo aqui um pouco estranho, se � que o amigo M�rcio me
> permite comentar: � que muitos programadores, inclusive eu (se � que
> posso ser rotulado como programador) foram instru�dos com o princ�pio de
> NUNCA usar o goto, por ser considerado um mau estilo de programa��o.

É preciso colocar a máxima "goto considered harmful" na perspectiva
histórica adequada.

Acredito que praticamente todo programador treinado nos últimos vinte
anos aprendeu a programar com if e while. Essas são as estruturas
básicas de programas e aparecem rapidamente nos manuais e nos cursos
de programação. Toda linguagem de programação moderna tem if e while,
e variantes como switch, for etc.

Essas coisas são chamadas estruturas de controle porque fazem
exatamente isso: controlam a execução do programa, às vezes indo para
uma sequência de sentenças, às vezes indo para outra, de acordo com
testes explícitos. Arranjar um programa com sequências de sentenças
com if e while é fazer programação estruturada.

Agora, a não ser que algum curso maravilhoso e desconhecido para mim
tenha história da programação no seu currículo, este programador
provavelmente não percebe que if e while nem sempre existiram e que a
programação estruturada foi inventada mais ou menos na década de 70.

Mas como você pode programar sem if e while? Este é o ponto sobre
goto.

Considere este fragmento:

char target = 'f';
char * i = input;
while (*i != '\0')
if (*i == target) goto exit;
else ++i;
:exit
return i;

O fragmento acima _não_ é o objeto da proibição do uso de goto. Este
fragmento exibe honrada programação estruturada. goto está ali como
bem poderia estar break. Tanto faz.

Agora, observe este fragmento:

char target = 'f';
char * i = input;
:loop
if (*i == '\0') goto exit;
if (*i == target) goto exit;
++i;
goto loop;
:exit
return i;

Isto é o que você não deve fazer.

O objetivo do combate ao goto era combater a programação não-
estruturada, e esse combate foi vencido com a introdução das
linguagens estruturadas. Tais linguagens levam o programador
naturalmente ao caminho certo e proíbem os maiores absurdos.

Existem linguagens em que o último fragmento acima era _a única
alternativa_. (Ou coisa pior.)

--
P.

Maurício Gomes

unread,
Aug 30, 2010, 10:10:08 AM8/30/10
to ccppb...@googlegroups.com
Tem um post recent no DailyWTF que se o cara tivesse usado goto seria melhor (ele usou um for vazio e um kctilhão de break)

2010/8/30 P. <pedro....@ccppbrasil.org>

Adriano dos Santos Fernandes

unread,
Aug 30, 2010, 10:17:01 AM8/30/10
to ccppb...@googlegroups.com
On 30/08/2010 10:46, Marcio Gil wrote:
>
> Imagine que este c�digo precise ser rodado milh�es de vezes a fim de
> fazer uma simul��o. Voc� poderia substituir os 'gotos' substituindo o
> 'swith' por 'ifs' e colocando um 'if' adicional em cada n�vel, mas
> isso vai sacrificar a efici�ncia do seu c�digo. Tamb�m poderia
> colocar o segundo la�o em uma fun��o 'inline', mas a� como fica o

> segundo 'goto'?
>
> Por isso eu proponho este desafio: reimplementar o exemplo acima sem
> 'gotos' e mantendo a mesma efici�ncia, sem acrescentar compara��es
> extras.
>
Isso na teoria...

Na pr�tica o compilador tem as informa��es necess�rias pra fazer a
otimiza��o se o c�digo foi escrito com breaks e vari�veis locais. Se
faz, � outra hist�ria.

Eu n�o vejo o goto como algo necess�rio referente a essa quest�o de sair
de loops com efici�ncia...


Adriano

Gianni Rossi

unread,
Aug 30, 2010, 10:15:03 AM8/30/10
to ccppb...@googlegroups.com

Há muito tempo não via um comentário sobre o uso de goto que não mencionasse dinosauros.

Corrigida essa falta, eu diria mais: esse papo de 'X é considerado prejudicial' é geralmente uma super-simplificação do problema. Goto é um grande exemplo. Quem aqui na lista sofreu já com espaguettificação de código por causa de goto em C++? Eu senti na pele o quão goto pode ser prejudicial, quando programava em Tk3000 com um Basic bem básico mesmo. Apesar de ter passado por isso, hoje eu uso goto sem medo, pois na maioria das vezes, o goto serve para simplificar o código.

E isso vale para todos os outros recursos do C++. Já ouvi bastante gente falando que templates devem ser evitados, não o uso, mas a criação de templates; ou seja, um programador só pode usar templates da STL mas não criar o seu. No final, tudo acaba sendo ferramentas disponíveis ao programador, como um martelo. Vc pode usar para pregar quadros, ou quebrar seus dedos.

Humberto Pereira

unread,
Aug 30, 2010, 10:19:37 AM8/30/10
to ccppb...@googlegroups.com
Simples, apenas setar os indices p/ o valor de saida deles. Vc vai gastar 2 comparacoes a mais que a sua tecnica com goto no caso de sair da matriz, e vai gastar 3 a mais no caso de sair da lista.

for (k = 0; k < qtd_matrizes; ++k)
{
    for (i = 0; i < m; ++i)
    {
        for (j = 0; j < n; ++j)
        {
            switch( matriz[k][i][j] )
            {
                case 0:
                    //goto fim_matriz;
                    i = m;
                    j = n;
                    break;
                case -1
                   i = m;
                   j = n;
                   k = qtd_matrizes;
                   break;
               default:
            }
        }
    }
}

Em casos de super-otimizacoes, onde vc tem sua funcao sendo chamada bilhoes de vezes, eh melhor usar algoritmos e estruturas mais complicadas do que desestruturar seu codigo. Nesse caso por ex, q economizar uns poucos ifs fazem tanta diferenca, nao seria melhor tratar essa matriz como um vetor? Em vez de 3 lacos vc soh tem um e economiza n * m comparacoes. Ou entao fazer loop unrolling? (http://en.wikipedia.org/wiki/Loop_unwinding) ? Ou os 2?


[]s
Humberto Pereira

2010/8/30 Marcio Gil <marci...@bol.com.br>

Adriano dos Santos Fernandes

unread,
Aug 30, 2010, 10:30:19 AM8/30/10
to ccppb...@googlegroups.com
On 30/08/2010 11:15, Gianni Rossi wrote:
>
> Há muito tempo não via um comentário sobre o uso de goto que não
> mencionasse dinosauros <http://xkcd.com/292/>.

>
> Corrigida essa falta, eu diria mais: esse papo de 'X é considerado
> prejudicial' é geralmente uma super-simplificação do problema. Goto é
> um grande exemplo. Quem aqui na lista sofreu já com espaguettificação
> de código por causa de goto em C++? Eu senti na pele o quão goto pode
> ser prejudicial, quando programava em Tk3000 com um Basic bem básico
> mesmo. Apesar de ter passado por isso, hoje eu uso goto sem medo, pois
> na maioria das vezes, o goto serve para simplificar o código.
>
> E isso vale para todos os outros recursos do C++. Já ouvi bastante
> gente falando que templates devem ser evitados, não o uso, mas a
> criação de templates; ou seja, um programador só pode usar templates
> da STL mas não criar o seu. No final, tudo acaba sendo ferramentas
> disponíveis ao programador, como um martelo. Vc pode usar para pregar
> quadros, ou quebrar seus dedos.
>
>

Concordo. E também tem a questão de gosto pessoal, como já disseram
nesse tópico "usar while ao invés de for" e outros. Cada um é cada um e
acha uma coisa mais simples ou complicada de escrever e/ou dar manutenção.

Só não acho válido justificar o uso com casos teóricos de melhoria de
desempenho, e isso até para casos onde o desempenho não justificaria em
nada a escolha de um código ou outro.


Adriano

Cinthia Meireles

unread,
Aug 30, 2010, 10:21:04 AM8/30/10
to ccppb...@googlegroups.com
Acho q o goto deve ser evitado por precaução. Se vc começar a usar goto direto, corre um risco muito grande de se empolgar e fazer uma besteira enorme.

Além disso, sempre é possível fazer um programa razoavelmente bonitinho substituindo o goto por outra coisa. No máximo você vai ter q mudar sua forma de pensar determinada função.

Agora, quanto ao q o Maurício disse... for vazio não, pelo amor de deus. Deve ter um jeito de fazer o q ele fez sem essas "gambiarras" e sem usar goto.
--
Cinthia Meireles

"Se você tem que fazer uma escolha, use os motivos que quiser para justificá-la, mas faça-a."
=)

Marcio Gil

unread,
Aug 30, 2010, 10:56:58 AM8/30/10
to ccppbrasil


On 30 ago, 11:19, Humberto Pereira <begn...@gmail.com> wrote:
> Simples, apenas setar os indices p/ o valor de saida deles. Vc vai gastar 2
> comparacoes a mais que a sua tecnica com goto no caso de sair da matriz, e
> vai gastar 3 a mais no caso de sair da lista.
>
> for (k = 0; k < qtd_matrizes; ++k)
> {
>     for (i = 0; i < m; ++i)
>     {
>         for (j = 0; j < n; ++j)
>         {
>             switch( matriz[k][i][j] )
>             {
>                 case 0:
>                     //goto fim_matriz;
>                     i = m;
>                     j = n;
Com 'goto': zero comparações
Sem 'goto': mais duas comparações

>                     break;
>                 case -1
>                    i = m;
>                    j = n;
>                    k = qtd_matrizes;
Com 'goto': zero comparações
Sem 'goto': mais três comparações

>                    break;
>                default:
>             }
>         }

E se hovessem cálculos aqui, que não deveriam ser feitos caso haja um
-1.
Reposta: mais uma comparação

>     }
>
> }
>

> Em casos de super-otimizacoes, onde vc tem sua funcao sendo chamada bilhoes
> de vezes, eh melhor usar algoritmos e estruturas mais complicadas do que
> desestruturar seu codigo.

Em que sentido o código de exemplo é desestruturado?

> Nesse caso por ex, q economizar uns poucos ifs
> fazem tanta diferenca, nao seria melhor tratar essa matriz como um vetor?

Como, sem acrescentar comparações extra?

> Em
> vez de 3 lacos vc soh tem um e economiza n * m comparacoes. Ou entao fazer
> loop unrolling? (http://en.wikipedia.org/wiki/Loop_unwinding) ? Ou os 2?
>

Mais tarde eu analiso isto com calma.

> []s
> Humberto Pereira
>
> 2010/8/30 Marcio Gil <marciom...@bol.com.br>

Maurício Gomes

unread,
Aug 30, 2010, 11:15:13 AM8/30/10
to ccppb...@googlegroups.com
O mencionado for vazio:

bool bCreateModel = false;
for (;;)
{
    if (!pModel)
    {
        bCreateModel = true;
        break;
    }

    if (asModelParts.GetSize() != asModelPartsToLoad.GetSize())
    {
        bCreateModel = true;
        break;
    }

    for (UINT32 i = 0; i < asModelPartsToLoad.GetSize(); ++i)
    {
        if (asModelPartsToLoad[i] != asModelParts[i])
        {
            bCreateModel = true;
            break;
        }
    }

    break;
}

Esse é um caso em que acho que goto se sairia melhor :P

2010/8/30 Andre Simoes <andrer...@gmail.com>
Você pode evitar o uso de goto em laços usando as palavras reservadas  "break" ou "continue"

por exemplo:

int i = 0;
while( i < 10 )
{
      if( i == 9 )
            break;

      if( i == 3 )
      {
            i += 2;
            continue;
      }

      printf( "%d\n", i );
      ++i;
}

- o break no caso quebra o laço atual do seu bloco e termina o loop de execução continuando na próxima linha após o bloco do while.
- continue faz com que o loop do seu bloco atual retorne para a primeira linha de teste de sua execução descartando dessa forma o codigo
abaixo de sua chamada.

não são viáveis em questão de fluxograma ou análises de uml mas são bem melhores que goto porque eles quebram o bloco e um terceiro pode facilmente identificar para onde o código deve seguir.

Mesmo assim por bons costumes, o código pode ficar muito melhor sem eles. Quanto ao o goto deveria ser considerado deprecado mas não foi retirado pois vários programas em c mais antigos o usavam e precisavam dele na definição da linguagem para continuarem a serem compatíveis.

Abraços
André

Maurício Gomes

unread,
Aug 30, 2010, 11:15:40 AM8/30/10
to ccppb...@googlegroups.com
Pelo menos seria sincero...

Alex Queiroz

unread,
Aug 30, 2010, 11:21:18 AM8/30/10
to ccppb...@googlegroups.com
2010/8/30 Maurício Gomes <orsp...@gmail.com>:

> O mencionado for vazio:
>
> bool bCreateModel = false;
> for (;;)
> {
> if (!pModel)
> {
> bCreateModel = true;
> break;
> }
>
> if (asModelParts.GetSize() != asModelPartsToLoad.GetSize())
> {
> bCreateModel = true;
> break;
> }
>
> for (UINT32 i = 0; i < asModelPartsToLoad.GetSize(); ++i)
> {
> if (asModelPartsToLoad[i] != asModelParts[i])
> {
> bCreateModel = true;
> break;
> }
> }
>
> break;
> }
>
> Esse é um caso em que acho que goto se sairia melhor :P
>

bool bCreateModel = false;
if (!pModel || asModelParts.GetSize() != asModelPartsToLoad.GetSize()) {
bCreateModel = true;
} else {


for (UINT32 i = 0; i < asModelPartsToLoad.GetSize(); ++i) {
if (asModelPartsToLoad[i] != asModelParts[i]) {
bCreateModel = true;
break;
}
}
}

--
-alex
http://www.artisancoder.com/

Andre Simoes

unread,
Aug 30, 2010, 11:07:07 AM8/30/10
to ccppb...@googlegroups.com
Você pode evitar o uso de goto em laços usando as palavras reservadas  "break" ou "continue"

por exemplo:

int i = 0;
while( i < 10 )
{
      if( i == 9 )
            break;

      if( i == 3 )
      {
            i += 2;
            continue;
      }

      printf( "%d\n", i );
      ++i;
}

- o break no caso quebra o laço atual do seu bloco e termina o loop de execução continuando na próxima linha após o bloco do while.
- continue faz com que o loop do seu bloco atual retorne para a primeira linha de teste de sua execução descartando dessa forma o codigo
abaixo de sua chamada.

não são viáveis em questão de fluxograma ou análises de uml mas são bem melhores que goto porque eles quebram o bloco e um terceiro pode facilmente identificar para onde o código deve seguir.

Mesmo assim por bons costumes, o código pode ficar muito melhor sem eles. Quanto ao o goto deveria ser considerado deprecado mas não foi retirado pois vários programas em c mais antigos o usavam e precisavam dele na definição da linguagem para continuarem a serem compatíveis.

Abraços
André

Em 30 de agosto de 2010 11:21, Cinthia Meireles <cinthia...@gmail.com> escreveu:

dedesan

unread,
Aug 30, 2010, 12:09:03 PM8/30/10
to ccppb...@googlegroups.com
Sei não viu... 
Eu acho que o maior problema deve ser em relação a manutenção... Embora o goto seja um recurso ainda presente, creio que ficar saltando de um lado para outro do código pra poder entendê-lo dificultaria um pouco mais as coisas... não sei bem o motivo, mas pode ser por motivo de compatibilidade a codificações legadas... Mas acho que ainda vale a metodologia KISS. Tudo deve ser simples e não creio que uma metodologia de desenvolvimento baseada em goto pra la e goto pra ca seja o ideal.
As vezes um código maior porém compreensível seja melhor que um menor e de difícil entendimento.

2010/8/30 Alex Queiroz <asan...@gmail.com>

--
Antes de enviar um e-mail para o grupo leia:
                    http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
--~--~---------~--~----~---------------------------------~----------~--~----~
[&] Colabore com a Pesquisa de Preferência de Conteúdo
             para Eventos do Grupo C & C++ Brasil:
                       http://www.surveymonkey.com/s/GBBGTXN
------~----~-------~---~---~---~---~----------------~------------~---------~
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
Para mais opções, visite http://groups.google.com/group/ccppbrasil
--~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
Emprego & carreira:  vag...@ccppbrasil.org
http://groups.google.com/group/dev-guys?hl=en



--
Dedésan / DDS
(11)8568-1010
(11)6130-8345

Bruno Sanches

unread,
Aug 30, 2010, 1:05:18 PM8/30/10
to ccppb...@googlegroups.com
O melhor (e único uso sensato) que tenho visto pra goto (que já discutiram em algum lugar aqui) é para sair de múltiplos loops. Fora isso todas as vezes que encontrei goto era problema de design mesmo.

Se alguém tem algum exemplo bom de uso de goto (sem ser múltiplos loops) gostaria muito de ver.

Abraços

Bruno Sanches
========================
http://www.pontov.com.br


2010/8/30 dedesan <dede...@gmail.com>

ToNi Albuquerque

unread,
Aug 30, 2010, 1:09:33 PM8/30/10
to ccppb...@googlegroups.com
GOTO era uma gambiarra PURA!

admitam...
_________________________________________
Antonio Albuquerque

+55 81 9175-3108
http://www.papogeek.com.br
http://www.twitter.com/acalbuquerque

Eduardo Vieira

unread,
Aug 30, 2010, 1:12:23 PM8/30/10
to ccppb...@googlegroups.com
Linux: Using goto In Kernel Code

http://kerneltrap.org/node/553/2131
Eduardo Vieira

Fabiano Vasconcelos

unread,
Aug 30, 2010, 1:11:08 PM8/30/10
to ccppb...@googlegroups.com
No linux nem precisa de nada, ele dá a pausa automaticamente! :D

Douglas Lopes Pereira

unread,
Aug 30, 2010, 1:20:43 PM8/30/10
to ccppb...@googlegroups.com
Tenho um exemplo muito utilizado nos códigos que trabalhei:

error = 0;

if (um tratamento qualquer)
{
error = 1;
goto finalDaFuncao;
}
else
{
processamento();
if (outro tratamento)
{
error = 2;
goto finalDaFuncao;
}
}

finalDaFuncao:
if (error)
{
tratamentoOuExibicaoDoErro();
}

Eu acredito que existe uma explicação que diz que essa forma de codificação traz algum benefício que não me lembro agora qual é. 
Mas, para mim, só o fato de não precisar replicar o código de tratamento de erros em cada um dos ifs (no meu exemplo são só 2, mas normalmente há vários) já deixa o código bem limpo, fácil de manter e não quebra a estrutura do programa.
Sempre escutei no colégio e faculdade que GOTO é ruim. Depois começar a trabalhar, percebi que se utilizado corretamente, pode ser útil sim.
Att,
Douglas


2010/8/30 Bruno Sanches <bcsa...@gmail.com>

Adriano dos Santos Fernandes

unread,
Aug 30, 2010, 1:24:54 PM8/30/10
to ccppb...@googlegroups.com
On 30/08/2010 14:12, Eduardo Vieira wrote:
> Linux: Using goto In Kernel Code
>
> http://kerneltrap.org/node/553/2131

O uso do goto no Linux se resume a um fato: O Linus gosta, e enquanto
ele gostar vai continuar sendo usado. Como eu disse, quest�o de gosto. E
como diz nesse link, desempenho � problema do compilador.


Adriano

Virgilio Fornazin

unread,
Aug 30, 2010, 2:22:40 PM8/30/10
to ccppb...@googlegroups.com
Antigamente (por volta de 98/2000  + ou -), alguns compiladores C++ (não estou falando C),
permitiam você fazer isso sem te dar nenhum warning:

void classe::funcao(const char * buffer)
{
if (
buffer == NULL)
{
goto xyz;
}

std::string s(
buffer);

xyz:

s += "problema";
}

Como o construtor de s náo era chamado, ja podem prever o que pode acontecer nesse caso.

Mas enfim, tem gente também que nao usa goto e faz uns lacos / ifs `mirabolantes`, por puro
despreparo. Com goto, se não souber usar direito, pode ser ainda pior.

E pra quem sabe o que acontece 'under the hood', uma estrutura for / while / do, se resumem
a instruções TEST / COMPARE, o que dá no mesmo usando if / goto.

Resumindo: goto pode trazer muito mais problemas do que benefícios, se você não souber usar.

Mas dizer que é gambiarra / porcaria, é pura ignorância.


2010/8/30 Adriano dos Santos Fernandes <adri...@gmail.com>
 On 30/08/2010 14:12, Eduardo Vieira wrote:
Linux: Using goto In Kernel Code

http://kerneltrap.org/node/553/2131

O uso do goto no Linux se resume a um fato: O Linus gosta, e enquanto ele gostar vai continuar sendo usado. Como eu disse, questão de gosto. E como diz nesse link, desempenho é problema do compilador.


Adriano

Maurício Gomes

unread,
Aug 30, 2010, 2:35:34 PM8/30/10
to ccppb...@googlegroups.com
Eu já usei goto uma vez, em um código de inicialização de um programa, ele tinha um kazilhão de IFs e #ifdefs e laços, que iam testando várias combinações de driver e hardware e sistema operacional (o trabalho dos #ifdefs era checkar o OS), e precisou de goto para não fazer uns loops bizarros para tratamento de erro (o programa era mais ou menos assim: executava um código "espaguético", se falhasse mudava as configurações e tentava denovo, e assim por diante, mas ia mudando a área de checagem e etc... até funcionar, ou acabar as alternativas). O código só precisou de 1 goto, e ficou bem mais organizado com a presença do goto..

2010/8/30 Virgilio Fornazin <virgilio...@gmail.com>

Fabiano Vasconcelos

unread,
Aug 30, 2010, 2:44:27 PM8/30/10
to ccppb...@googlegroups.com
Pois é... Eu achei muito adequada a justificativa da Cinthia, aliás, a
que mais me agradou. Não que eu descarte a possibilidade TOTAL de usar
goto, mas, como ela mesma falou, goto deve ser evitado por precaução. Um
código macarrônico, cheio de gotos, ninguém merece, né? Não existe
alternativa? Então que se use as alternativas enquanto for possível! Nem
tão ao céu, nem tão a terra.
Pensando logicamente, todo mundo sabe que goto pode causar dores de
cabeça grandes.
Bom, ainda estou engatinhando. Pode ser que esteja falando besteira. A
experiência me dará a resposta que eu quero encontrar.

Pedro d'Aquino

unread,
Aug 30, 2010, 3:00:08 PM8/30/10
to ccppb...@googlegroups.com
Eu acho que se você tem tantos loops aninhados que precisa de um goto para sair deles, isso já é um problema de projeto.

(Exceção feita, claro, às raras situações em que um eventual ganho de desempenho seria significativo.)

2010/8/30 Fabiano Vasconcelos <fvasco...@gmail.com>

Maurício Gomes

unread,
Aug 30, 2010, 3:02:41 PM8/30/10
to ccppb...@googlegroups.com
No meu caso era mais por organização mesmo... fazer código que carrega vários drivers diferentes em vários sistemas operacionais resulta em umas coisas bem macarrônicas (o código ainda tenta várias formas de inicializar cada driver)

2010/8/30 Pedro d'Aquino <bud...@gmail.com>

Luis Miranda

unread,
Aug 30, 2010, 5:18:07 PM8/30/10
to ccppb...@googlegroups.com
Me admira que um programador C/C++, onde "o programador deve saber oq está fazendo", vir dizer que o problema de desempenho é do compilador. Não importa quão bom seja o compilador, quem já precisou escovar bit´s pra ganhar desempenho, sabe que as vezes ou você desce pro assembly ou coloca um goto aqui e ali.

Não existe esse papo de certo, errado. A questão é "vc sabe oq está fazendo? os ganhos são maiores que as perdas?".
Esse papinho de não usar GOTO nunca, que é erro de projeto ou algo do tipo, é papinho de aula de AED na faculdade.....lá fora a realidade as vezes é outra.

2010/8/30 Adriano dos Santos Fernandes <adri...@gmail.com>
 On 30/08/2010 14:12, Eduardo Vieira wrote:

Linux: Using goto In Kernel Code

http://kerneltrap.org/node/553/2131

O uso do goto no Linux se resume a um fato: O Linus gosta, e enquanto ele gostar vai continuar sendo usado. Como eu disse, questão de gosto. E como diz nesse link, desempenho é problema do compilador.


Adriano

--

Adriano dos Santos Fernandes

unread,
Aug 30, 2010, 5:35:14 PM8/30/10
to ccppb...@googlegroups.com
On 30-08-2010 18:18, Luis Miranda wrote:
> Me admira que um programador C/C++, onde "o programador deve saber oq
> est� fazendo", vir dizer que o problema de desempenho � do compilador.

Se vc ler minha outra mensagem, vai ver que o que eu disse est�
relacionado a um contexto.

> N�o importa qu�o bom seja o compilador, quem j� precisou escovar bit�s
> pra ganhar desempenho, sabe que as vezes ou voc� desce pro assembly ou


> coloca um goto aqui e ali.
>

E muitas vezes uma otimiza��o "mirabolante" feita pelo programador pode
resultar em um c�digo que rode bem mais lento.

Ent�o se o programador � o bonz�o, os compiladores n�o deveriam otimizar
o c�digo gerado?

A otimiza��o n�o existe pra transformar um programador ruim em bom, e
sim para que o programador possa escrever um c�digo mais decente e ainda
assim r�pido. Se n�o era s� deixar tudo em assembly e pronto...

> N�o existe esse papo de certo, errado. A quest�o � "vc sabe oq est�
> fazendo? os ganhos s�o maiores que as perdas?".
> Esse papinho de n�o usar GOTO nunca, que � erro de projeto ou algo do
> tipo, � papinho de aula de AED na faculdade.....l� fora a realidade as
> vezes � outra.
>
Eu concordo com isso. Tem professorzinho que diz que n�o se deve usar
break e continue, e sim fazer tudo com os testes de whiles e ifs. Pra
mim o que essas pessoas que s� sabem teoria falam n�o tem muito valor...


Adriano

Marcio Gil

unread,
Aug 30, 2010, 7:57:51 PM8/30/10
to ccppb...@googlegroups.com
Em 30/8/2010 18:35, Adriano dos Santos Fernandes escreveu:
> On 30-08-2010 18:18, Luis Miranda wrote:
>> N�o importa qu�o bom seja o compilador, quem j� precisou escovar
>> bit�s pra ganhar desempenho, sabe que as vezes ou voc� desce pro
>> assembly ou coloca um goto aqui e ali.
>>
> E muitas vezes uma otimiza��o "mirabolante" feita pelo programador
> pode resultar em um c�digo que rode bem mais lento.
>
> Ent�o se o programador � o bonz�o, os compiladores n�o deveriam
> otimizar o c�digo gerado?
>
> A otimiza��o n�o existe pra transformar um programador ruim em
> bom, e sim para que o programador possa escrever um c�digo mais
> decente e ainda assim r�pido. Se n�o era s� deixar tudo em
> assembly e pronto...
>

Me desculpe, mas esta afirma��o de que o compilador � o �nico
respons�vel pelo desempenho � fora da realidade pr�tica. Compilador
n�o faz milagres. Um bom programador sabe instintivamente como
ajudar o otimizador e obt�m um programa mais r�pido, e n�o �
necess�rio nada mirabolante.

No entanto, quando a otimiza��o � necess�ria, deve ser feito com
mensura��o de tempo de processamento, preferencialmente depois de
localizados os gargalos no sistema. Neste caso n�o tem como resultar
em c�digo mais lento, pois voc� s� vai utilizar o novo c�digo depois
de ter comprovado a melhoria no desempenho e se o c�digo faz o que
precisa.

Atualmente trabalhei em um projeto que, apesar de ser escrito em C++
e muito bom do ponto de vista l�gico, ficou um pouco lento por causa
de um detalhe aqui e ali. Isto porque os programadores atuais est�o
perdendo a capacidade de saber otimizar as coisas. Eles sabem obter o
resultado, mais a� vem um programador mais experiente e faz o mesmo
trabalho at� 10 vezes mais eficiente.

Uns anos atr�s eu abri um t�pico neste grupo pedindo ajuda para
otimizar um c�digo:

http://groups.google.com.br/group/ccppbrasil/browse_thread/thread/6ca6fce4e2c59a6

Era uma fun��o que fazia um milh�o de multiplica��es em 38 segundos,
conseguimos melhorar para cerca de 2 segundos.

Gianni

unread,
Aug 30, 2010, 8:10:52 PM8/30/10
to ccppb...@googlegroups.com

On Aug 30, 2010, at 8:57 PM, Marcio Gil wrote:

> Em 30/8/2010 18:35, Adriano dos Santos Fernandes escreveu:
> > On 30-08-2010 18:18, Luis Miranda wrote:

> >> Não importa quão bom seja o compilador, quem já precisou escovar
> >> bit´s pra ganhar desempenho, sabe que as vezes ou você desce pro


> >> assembly ou coloca um goto aqui e ali.
> >>

> > E muitas vezes uma otimização "mirabolante" feita pelo programador
> > pode resultar em um código que rode bem mais lento.
> >
> > Então se o programador é o bonzão, os compiladores não deveriam
> > otimizar o código gerado?
> >
> > A otimização não existe pra transformar um programador ruim em
> > bom, e sim para que o programador possa escrever um código mais
> > decente e ainda assim rápido. Se não era só deixar tudo em
> > assembly e pronto...
> >
>
> Me desculpe, mas esta afirmação de que o compilador é o único
> responsável pelo desempenho é fora da realidade prática. Compilador
> não faz milagres. Um bom programador sabe instintivamente como
> ajudar o otimizador e obtém um programa mais rápido, e não é
> necessário nada mirabolante.

Olha, não foi bem isso que foi dito, que o compilador é o *único* responsável. Ele é sim o maior responsável. Diria que o processo normal, que acho que todos aqui devem considerar o 'certo', é o programador fazer 99% do código só seguindo boas práticas e deixar a optimização para o compilador, e depois só fazer o 1% no lugar acusado pelo profiler ou testes unitários ou alguma métrica similar.

O ponto é: o compilador sim acaba fazendo a maior parte da optimização, o programador precisa só ajudar 'um pouco', fazendo uso de boas práticas.

>
> No entanto, quando a otimização é necessária, deve ser feito com
> mensuração de tempo de processamento, preferencialmente depois de
> localizados os gargalos no sistema. Neste caso não tem como resultar
> em código mais lento, pois você só vai utilizar o novo código depois
> de ter comprovado a melhoria no desempenho e se o código faz o que


> precisa.
>
> Atualmente trabalhei em um projeto que, apesar de ser escrito em C++

> e muito bom do ponto de vista lógico, ficou um pouco lento por causa
> de um detalhe aqui e ali. Isto porque os programadores atuais estão


> perdendo a capacidade de saber otimizar as coisas. Eles sabem obter o

> resultado, mais aí vem um programador mais experiente e faz o mesmo
> trabalho até 10 vezes mais eficiente.
>
> Uns anos atrás eu abri um tópico neste grupo pedindo ajuda para
> otimizar um código:
>
> http://groups.google.com.br/group/ccppbrasil/browse_thread/thread/6ca6fce4e2c59a6
>
> Era uma função que fazia um milhão de multiplicações em 38 segundos,


> conseguimos melhorar para cerca de 2 segundos.
>

Marcio Gil

unread,
Aug 30, 2010, 8:31:40 PM8/30/10
to ccppb...@googlegroups.com
Em 30/8/2010 21:10, Gianni escreveu:
>
> Olha, n�o foi bem isso que foi dito, que o compilador � o *�nico*
> respons�vel. Ele � sim o maior respons�vel. Diria que o processo
> normal, que acho que todos aqui devem considerar o 'certo', � o
> programador fazer 99% do c�digo s� seguindo boas pr�ticas e deixar
> a optimiza��o para o compilador, e depois s� fazer o 1% no lugar
> acusado pelo profiler ou testes unit�rios ou alguma m�trica
> similar.
>
> O ponto �: o compilador sim acaba fazendo a maior parte da
> optimiza��o, o programador precisa s� ajudar 'um pouco', fazendo
> uso de boas pr�ticas.
>
Mas se um escovador de bits pega um c�digo que foi escrito seguindo
todas as boas pr�ticas e o deixa 20 vezes mais r�pido, ent�o o
programador n�o ajudou um "pouquinho", ajudou um "pouc�o" :-)

Agora falando s�rio, � raro um c�digo ser melhorado em 20 vezes, no
entanto sempre � poss�vel melhorar um pouco, e este pouco
frequentemente ultrapassa os 100%, ou seja, um bom otimizador
humano pode tornar um c�digo 2 vezes mais r�pido ou ainda mais.

Emerson de Freitas Barcelos

unread,
Aug 30, 2010, 8:36:40 PM8/30/10
to ccppb...@googlegroups.com
goto chega;
.
.
.

chega:
exit(EXIT_FAILURE);


"goto" é como cerveja, beba com moderação.

Adriano dos Santos Fernandes

unread,
Aug 30, 2010, 8:42:23 PM8/30/10
to ccppb...@googlegroups.com
On 30-08-2010 20:57, Marcio Gil wrote:
> Em 30/8/2010 18:35, Adriano dos Santos Fernandes escreveu:
>> On 30-08-2010 18:18, Luis Miranda wrote:
>>> N�o importa qu�o bom seja o compilador, quem j� precisou escovar
>>> bit�s pra ganhar desempenho, sabe que as vezes ou voc� desce pro
>>> assembly ou coloca um goto aqui e ali.
>>>
>> E muitas vezes uma otimiza��o "mirabolante" feita pelo programador
>> pode resultar em um c�digo que rode bem mais lento.
>>
>> Ent�o se o programador � o bonz�o, os compiladores n�o deveriam
>> otimizar o c�digo gerado?
>>
>> A otimiza��o n�o existe pra transformar um programador ruim em
>> bom, e sim para que o programador possa escrever um c�digo mais
>> decente e ainda assim r�pido. Se n�o era s� deixar tudo em
>> assembly e pronto...
>>
>
> Me desculpe, mas esta afirma��o de que o compilador � o �nico
> respons�vel pelo desempenho � fora da realidade pr�tica.

Eu n�o fa�o id�ia de onde voc� leu isso.

> Compilador
> n�o faz milagres. Um bom programador sabe instintivamente como
> ajudar o otimizador e obt�m um programa mais r�pido, e n�o �
> necess�rio nada mirabolante.
>
> No entanto, quando a otimiza��o � necess�ria, deve ser feito com
> mensura��o de tempo de processamento, preferencialmente depois de
> localizados os gargalos no sistema. Neste caso n�o tem como resultar
> em c�digo mais lento, pois voc� s� vai utilizar o novo c�digo depois
> de ter comprovado a melhoria no desempenho e se o c�digo faz o que
> precisa.
>

Na verdade tem como resultar em c�digo mais lento sim. Existe um exemplo
(da AMD, pelo que lembro) que mostra exatamente algo com matrizes em que
diferentes maneiras de passar pelos dados deixa o c�digo mais r�pido ou
mais lento. Isto est� relacionado ao cache. Se vc pega uma arquitetura
que tenha um cache que trabalhe diferente, seu algoritmo pode ficar pior.

> Atualmente trabalhei em um projeto que, apesar de ser escrito em C++
> e muito bom do ponto de vista l�gico, ficou um pouco lento por causa
> de um detalhe aqui e ali. Isto porque os programadores atuais est�o
> perdendo a capacidade de saber otimizar as coisas. Eles sabem obter o
> resultado, mais a� vem um programador mais experiente e faz o mesmo
> trabalho at� 10 vezes mais eficiente.
>
> Uns anos atr�s eu abri um t�pico neste grupo pedindo ajuda para
> otimizar um c�digo:
>
> http://groups.google.com.br/group/ccppbrasil/browse_thread/thread/6ca6fce4e2c59a6
>
>
> Era uma fun��o que fazia um milh�o de multiplica��es em 38 segundos,
> conseguimos melhorar para cerca de 2 segundos.
>

Me parece que n�o foi substituindo uma ou outra vari�vel local e breaks
por goto...


Adriano

Gianni

unread,
Aug 30, 2010, 8:38:57 PM8/30/10
to ccppb...@googlegroups.com

On Aug 30, 2010, at 9:31 PM, Marcio Gil wrote:

> Em 30/8/2010 21:10, Gianni escreveu:
> >

> > Olha, não foi bem isso que foi dito, que o compilador é o *único*

> > responsável. Ele é sim o maior responsável. Diria que o processo
> > normal, que acho que todos aqui devem considerar o 'certo', é o


> > programador fazer 99% do código só seguindo boas práticas e deixar

> > a optimização para o compilador, e depois só fazer o 1% no lugar


> > acusado pelo profiler ou testes unitários ou alguma métrica
> > similar.
> >

> > O ponto é: o compilador sim acaba fazendo a maior parte da
> > optimização, o programador precisa só ajudar 'um pouco', fazendo
> > uso de boas práticas.
> >
> Mas se um escovador de bits pega um código que foi escrito seguindo
> todas as boas práticas e o deixa 20 vezes mais rápido, então o
> programador não ajudou um "pouquinho", ajudou um "poucão" :-)
>
> Agora falando sério, é raro um código ser melhorado em 20 vezes, no
> entanto sempre é possível melhorar um pouco, e este pouco


> frequentemente ultrapassa os 100%, ou seja, um bom otimizador

> humano pode tornar um código 2 vezes mais rápido ou ainda mais.

Com certeza; mas o que adianta fazer um processo que, por exemplo, gera um HTTP request rodar em 50ms ao invés de 100ms se o round-trip inteiro vai demorar 2s?

Um programador é um recurso limitado e o optimizador do compilador é ilimitado. Nós nunca aqui falamos que o optimizador é melhor que ninguém, mas que em um processo normal de desenvolvimento, usar o optimizador (ou seja, usar boas práticas para deixar o optimizador fazer bem o trabalho dele) é a técnica que vai dar o melhor ganho de performance se todo o programa for considera, e não só um processo.

Pedro d'Aquino

unread,
Aug 30, 2010, 8:44:19 PM8/30/10
to ccppb...@googlegroups.com
Regra de ouro: faça funcionar do jeito mais simples, rode em um profiler, e só então otimize.

2010/8/30 Adriano dos Santos Fernandes <adri...@gmail.com>
On 30-08-2010 20:57, Marcio Gil wrote:

> Em 30/8/2010 18:35, Adriano dos Santos Fernandes escreveu:
>> On 30-08-2010 18:18, Luis Miranda wrote:
>>> Não importa quão bom seja o compilador, quem já precisou escovar
>>> bit´s pra ganhar desempenho, sabe que as vezes ou você desce pro

>>> assembly ou coloca um goto aqui e ali.
>>>
>> E muitas vezes uma otimização "mirabolante" feita pelo programador
>> pode resultar em um código que rode bem mais lento.
>>
>> Então se o programador é o bonzão, os compiladores não deveriam
>> otimizar o código gerado?
>>
>> A otimização não existe pra transformar um programador ruim em
>> bom, e sim para que o programador possa escrever um código mais
>> decente e ainda assim rápido. Se não era só deixar tudo em
>> assembly e pronto...
>>
>

> Me desculpe, mas esta afirmação de que o compilador é o único
> responsável pelo desempenho é fora da realidade prática.

Eu não faço idéia de onde você leu isso.

> Compilador
> não faz milagres. Um bom programador sabe instintivamente como
> ajudar o otimizador e obtém um programa mais rápido, e não é
> necessário nada mirabolante.

>
> No entanto, quando a otimização é necessária, deve ser feito com
> mensuração de tempo de processamento, preferencialmente depois de
> localizados os gargalos no sistema. Neste caso não tem como resultar
> em código mais lento, pois você só vai utilizar o novo código depois
> de ter comprovado a melhoria no desempenho e se o código faz o que
> precisa.
>
Na verdade tem como resultar em código mais lento sim. Existe um exemplo

(da AMD, pelo que lembro) que mostra exatamente algo com matrizes em que
diferentes maneiras de passar pelos dados deixa o código mais rápido ou
mais lento. Isto está relacionado ao cache. Se vc pega uma arquitetura

que tenha um cache que trabalhe diferente, seu algoritmo pode ficar pior.

> Atualmente trabalhei em um projeto que, apesar de ser escrito em C++
> e muito bom do ponto de vista lógico, ficou um pouco lento por causa
> de um detalhe aqui e ali. Isto porque os programadores atuais estão

> perdendo a capacidade de saber otimizar as coisas. Eles sabem obter o
> resultado, mais aí vem um programador mais experiente e faz o mesmo
> trabalho até 10 vezes mais eficiente.
>
> Uns anos atrás eu abri um tópico neste grupo pedindo ajuda para
> otimizar um código:
>
> http://groups.google.com.br/group/ccppbrasil/browse_thread/thread/6ca6fce4e2c59a6
>
>
> Era uma função que fazia um milhão de multiplicações em 38 segundos,

> conseguimos melhorar para cerca de 2 segundos.
>
Me parece que não foi substituindo uma ou outra variável local e breaks
por goto...


Adriano

Marcio Gil

unread,
Aug 30, 2010, 9:24:16 PM8/30/10
to ccppb...@googlegroups.com
Em 30/8/2010 21:38, Gianni escreveu:
>
> Com certeza; mas o que adianta fazer um processo que, por exemplo,
> gera um HTTP request rodar em 50ms ao inv�s de 100ms se o

> round-trip inteiro vai demorar 2s?
>
Pois �, mas at� a intera��o com programas ou dispositivos externos
ao sistema pode ser otimizado.

Um exemplo triste que presenciei recentemente: constatar que o
sistema da concorr�ncia escrito em VB � mais r�pido que o seu
escrito em C++...

Se voc� cronometrar o seu programa, localizar os gargalos e ir
melhorando um pouco aqui, um pouco l�, vai ver que o ganho ser� bem
maior que 1%

André Tupinambá

unread,
Aug 30, 2010, 10:58:08 PM8/30/10
to ccppb...@googlegroups.com
Bom,

Esse é um assunto no mínimo interessante, pois trás de volta questões
muito antigas.

Aconselho a leitura de dois textos, o artigo original do E.W. Dijkstra
que propõe o fim do goto [1] (literalmente "Goto Statement Considered
Harmful"), e o texto a seguir do professor que recusou o artigo,
retirado de [2].

[1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.92.4846&rep=rep1&type=pdf
[2] http://www.fang.ece.ufl.edu/reject.html

Boa leitura,

[]'s
André


E.W. DIJKSTRA

"Goto Statement Considered Harmful." This paper tries to convince us
that the well-known goto statement should be eliminated from our
programming languages or, at least (since I don't think that it will
ever be eliminated), that programmers should not use it. It is not
clear what should replace it. The paper doesn't explain to us what
would be the use of the "if" statement without a "goto" to redirect
the flow of execution: Should all our postconditions consist of a
single statement, or should we only use the arithmetic "if," which
doesn't contain the offensive "goto"?
And how will one deal with the case in which, having reached the end
of an alternative, the program needs to continue the execution
somewhere else?
The author is a proponent of the so-called "structured programming"
style, in which, if I get it right, gotos are replaced by indentation.
Structured programming is a nice academic exercise, which works well
for small examples, but I doubt that any real-world program will ever
be written in such a style. More than 10 years of industrial
experience with Fortran have proved conclusively to everybody
concerned that, in the real world, the goto is useful and necessary:
its presence might cause some inconveniences in debugging, but it is a
de facto standard and we must live with it. It will take more than the
academic elucubrations of a purist to remove it from our languages.
Publishing this would waste valuable paper: Should it be published, I
am as sure it will go uncited and unnoticed as I am confident that, 30
years from now, the goto will still be alive and well and used as
widely as it is today.
Confidential comments to the editor: The author should withdraw the
paper and submit it someplace where it will not be peer reviewed. A
letter to the editor would be a perfect choice: Nobody will notice it
there!

wander

unread,
Aug 31, 2010, 6:49:19 AM8/31/10
to ccppbrasil
> É preciso colocar a máxima "goto considered harmful" na perspectiva
> histórica adequada.
>

Eu geralmente uso goto para fazer cleanup quando saio de uma função
(código C, C++ eu sei
que tem destrutora). Por exemplo:

int foo(void)
{
int ret = 0;
pthread_mutex_lock(&mutex);
/* ,,,,, */

if (deu_merda_no_meio_da_funcao)
{
ret = MEU_CODIGO_DE_ERRO;
goto exit_error;
}

/* ... */

return 0;

exit_error:
pthread_mutex_unlock(&mutex);
return ret;
}

No exemplo acima por simplicidade aloquei apenas um recurso (aquisição
do mutex), mas muitas vezes além
de um mutex, você aloca memória, abre um arquivo, etc... Eu acho que
goto neste caso deixa um código um pouco
mais claro, colocando todo o cleanup no fim da função.

Wander

Douglas Lopes Pereira

unread,
Aug 31, 2010, 6:52:05 AM8/31/10
to ccppb...@googlegroups.com
Agree!

É exatamente isso que tentei exemplificar no e-mail anterior!

Sem contar que se você usa logs nas entradas e saídas das funções (para debug, por exemplo), você só tem um ponto de saída, o que facilita bastante.

Douglas

2010/8/31 wander <wander....@gmail.com>

Gianni

unread,
Aug 31, 2010, 8:07:03 AM8/31/10
to ccppb...@googlegroups.com

On Aug 30, 2010, at 10:24 PM, Marcio Gil wrote:

> Em 30/8/2010 21:38, Gianni escreveu:
> >
> > Com certeza; mas o que adianta fazer um processo que, por exemplo,

> > gera um HTTP request rodar em 50ms ao invés de 100ms se o


> > round-trip inteiro vai demorar 2s?
> >

> Pois é, mas até a interação com programas ou dispositivos externos


> ao sistema pode ser otimizado.
>
> Um exemplo triste que presenciei recentemente: constatar que o

> sistema da concorrência escrito em VB é mais rápido que o seu
> escrito em C++...
>
> Se você cronometrar o seu programa, localizar os gargalos e ir
> melhorando um pouco aqui, um pouco lá, vai ver que o ganho será bem
> maior que 1%

Eu não disse que o ganho seria de 1%, mas que a proporção de código que se precisa mexer ao invés de deixar para o optimizador seria 1%; e ainda assim, esse 1% é figurativo. E o exemplo que citei mostra como não vale a pena ficar optimizando tudo, pois 50ms de ganho em um processo que demora 2s não vale nada. Eu acho que vc entendeu tudo ao contrário que eu disse.

Rafael Bueno

unread,
Aug 31, 2010, 8:41:58 AM8/31/10
to ccppb...@googlegroups.com
Bom, em meus programas em C++ eu utilizo tratamento de erro para isso try/catch, ficando muito mais elegante o código.


Mas, já em C já não sei como esse tratamento se realize, talvez essa seja uma forma para realizar isso.

Abraços,

2010/8/31 Gianni <nasus....@gmail.com>

--
Antes de enviar um e-mail para o grupo leia:
                    http://www.ccppbrasil.org/wiki/Lista:AntesdePerguntar
--~--~---------~--~----~---------------------------------~----------~--~----~
[&] Colabore com a Pesquisa de Preferência de Conteúdo
             para Eventos do Grupo C & C++ Brasil:
                       http://www.surveymonkey.com/s/GBBGTXN
------~----~-------~---~---~---~---~----------------~------------~---------~
[&] C & C++ Brasil - http://www.ccppbrasil.org/
Para sair dessa lista, envie um e-mail para ccppbrasil-...@googlegroups.com
Para mais opções, visite http://groups.google.com/group/ccppbrasil
--~--~---------~--~----~--~-~--~---~----~-----------------~--~----------~
Emprego & carreira:  vag...@ccppbrasil.org
http://groups.google.com/group/dev-guys?hl=en



--
Rafael Bueno

Felipe Magno de Almeida

unread,
Aug 31, 2010, 9:39:23 AM8/31/10
to ccppb...@googlegroups.com
2010/8/30 André Tupinambá <andr...@gmail.com>:

> Bom,
>
> Esse é um assunto no mínimo interessante, pois trás de volta questões
> muito antigas.
>
> Aconselho a leitura de dois textos, o artigo original do E.W. Dijkstra
> que propõe o fim do goto [1] (literalmente "Goto Statement Considered
> Harmful"), e o texto a seguir do professor que recusou o artigo,
> retirado de [2].

O segundo paper parece bem estranho. A pessoa rejeita papers por não
compreender formalismos, e implica que if's só funcionam com apenas um
statement. E em nenhum momento discute sobre as "coordenadas"
explicadas pelo paper do Dijkstra.


--
Felipe Magno de Almeida

Igor Léopoldès

unread,
Aug 31, 2010, 9:49:56 AM8/31/10
to ccppb...@googlegroups.com
Bom dia pessoal.

Sou novo na lista, minha primeira participação. 

Mas só para endossar o que o Rafael Bueno falou: no kernel do linux, por exemplo, se utiliza sim o goto para tratamento de exceção.

Paulo Igor Leopoldes Bender                      
#452400

P.

unread,
Aug 31, 2010, 10:10:52 AM8/31/10
to ccppbrasil
Marcio Gil wrote:

> Em 30/8/2010 18:35, Adriano dos Santos Fernandes escreveu:
> Me desculpe, mas esta afirma��o de que o compilador � o �nico
> respons�vel pelo desempenho � fora da realidade pr�tica. Compilador
> n�o faz milagres. Um bom programador sabe instintivamente como
> ajudar o otimizador e obt�m um programa mais r�pido, e n�o �
> necess�rio nada mirabolante.

O instinto, infelizmente, precisa ser treinado, como qualquer outra
faculdade do indivíduo produtivo. O instinto dos novatos e dos
incompetentes sugere absurdos.

Na empresa do vizinho, houve um profissional cujo instinto sugeriu que
a seguinte lista de parâmetros era otimizada:

// esta função não está definida inline
void foo (char const & x, char const & y, char const & z);

Eu já mostrei para mim mesmo que um loop se tornava muito mais rápido
trocando um código desse tipo:

integer x;
integer y;

while x < last x
{
y = /* compute y from x */
/* computation with generated x and y */
increment x
}

por um código desse tipo:

for each integer x in whatever
{
integer y = /* compute y from x */
/* computation with generated x and y */
}

usando um certo compilador. A intuição de que programador C sugere
isso?

Eu vi de perto profissionais otimizando funções cuja demora, contada
no relógio da parede, era causada pela preempção da tarefa, devido ao
excesso de threads concorrentes.

O discurso do "escovador de bits" pra mim é muitíssimo suspeito.

--
P.

Wander Lairson

unread,
Aug 31, 2010, 10:33:09 AM8/31/10
to ccppb...@googlegroups.com
> Eu já mostrei para mim mesmo que um loop se tornava muito mais rápido
> trocando um código desse tipo:
>
> integer x;
> integer y;
>
> while x < last x
> {
>   y =  /* compute y from x */
>   /* computation with generated x and y */
>   increment x
> }
>
> por um código desse tipo:
>
> for each integer x in whatever
> {
>   integer y = /* compute y from x */
>   /* computation with generated x and y */
> }
>
> usando um certo compilador. A intuição de que programador C sugere
> isso?
>

Eu tive um caso interessante com o Keil, quando estava desenvolvendo pra ARM.

fazer:

if (condicao)
{
do
{
} while (condicao)
}

ao invés de:

while (condicao)
{
}

Não só era mais rápido como também economizava 4 bytes do binário final!

Wander

André Tupinambá

unread,
Sep 5, 2010, 1:08:15 PM9/5/10
to ccppb...@googlegroups.com
O segundo nem é um artigo em si, foi a justificativa de um professor
para recusar o artigo de Dijkstra. No site tem outras bem
interessantes, como o cara que recusou o artigo do Codd criando o
conceito de banco de dados relacional, o de Turing que definiu a
máquina de Turing, entre outros.

Mas como a pergunta é "Por quê goto foi considerado prejudicial?",
nada melhor que ler o texto original que propôs isso.

[]'s
André Tupinambá

2010/8/31 Felipe Magno de Almeida <felipe.m...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages