Pergunta

Atualmente estou trabalhando através dos exercícios em 'The C Programming Language'. Aqui está uma das minhas soluções:

int c;

while ((c=getchar()) != EOF) {

if (c == ' ') {

    while ((c = getchar()) == ' ')

    {}  // do nothing?

    putchar(' ');

}

putchar(c);

}

Eu encontrei algumas soluções aqui que são bem diferentes do meu e usar uma variável extra para acompanhar o que está acontecendo, enquanto eu só usar um loop while para saltar através de todos os espaços. Minha solução sente um confuso pouco, como parece hackish pouco para ter um loop while com nada entre as chaves. Eu queria saber se existem boas razões para não fazer isso? Obrigado por qualquer conselho :-)

Foi útil?

Solução

Nem um pouco - Eu acredito que você vai encontrar não fazer nada loops como estes em K & R, de modo que é quase tão oficial quanto ele ganha

.

É uma questão de preferência pessoal, mas eu prefiro meus não fazer nada laços como este:

while(something());

Outros preferem o ponto e vírgula para ir em uma linha separada, para reforçar o fato de que é um loop:

while(something())
  ;

Ainda outros preferem usar os suportes com nada dentro, como você tem feito:

while(something())
{
}

É tudo válido -. Você só tem que escolher o estilo que você gosta e ficar com ele

Outras dicas

A sua pergunta "Está usando um bloco de tempo para não fazer nada uma coisa ruim?" também pode ser respondida em termos de desperdício de ciclos de CPU. Neste caso, a resposta é "Não", uma vez que, o processo vai dormir enquanto aguarda o usuário para inserir um caractere.

O processo vai acordar só depois de um personagem é de entrada. Em seguida, o teste irá ocorrer e se o teste passa, ou seja, c == '', o processo vai para dormir de novo até que um próximo caractere é inserido. Isso se repete até que um caractere não-espaço é inserido.

Eu acho que é perfeitamente aceitável.

Eu seria ou escrevê-lo:

//skip all spaces
while ((c = getchar()) == ' ') {} 

para torná-lo óbvio que esta linha de código faz uma coisa.

Ou eu ia escrever assim:

while ((c = getchar()) == ' ') {
    //no processing required for spaces
}

para que ele corresponda o resto do formato do seu código.

Pessoalmente, eu não sou um fã do

while ((c = getchar()) == ' ');

formato. Eu acho que é fácil ignorar o ponto e vírgula.

Bem, se você realmente não gosto das chaves vazias, você pode refatorar que loop interno em

while (c == ' ') {c = getchar();}

Isto custa uma comparação extra, porém, de modo a fazer loop while seria melhor.

Eu não acho que o procedimento é, mas a formatação é muito estranho. Não há nada de errado com:

/* Eat spaces */
while ((c = getchar()) == ' ');

(isto é, indicam que intencionalmente não é um corpo)

Eu seria a favor:

while ((c = getchar()) == ' ') /* Eat spaces */;

Eu também sido conhecido por ter um procedimento chamado DoNothing especificamente para chamar em casos como este. Torna-se muito claro que você realmente quer dizer para não fazer nada.

Enquanto corpos de loop inexistentes são perfeitamente aceitáveis ??deve ser muito claro que é intencional.

A while que não faz nada, provavelmente, é uma coisa ruim:

while(!ready) {
   /* Wait for some other thread to set ready */
}

... é um muito, muito, muito caro para esperar - ele vai usar tanto CPU como o sistema operacional irá dar-lhe, enquanto ready é falsa, roubando tempo de CPU com que o outro segmento poderia ser fazendo um trabalho útil.

No entanto o seu ciclo é não não fazer nada:

while ((c = getchar()) == ' ')
    {};  // skip

... porque é chamar getchar() em cada iteração. Assim, como toda a gente concordou, o que você fez é bom.

Eu usei um código como este. Eu não acho que não há realmente nenhuma razão para não usá-lo se a situação o justificar-lo.

I acha que não há problema nisso. Você pode usá-lo, Em muitas situações eu prefiro-o.

A forma canônica - usado desde tempos imemoriais, ter um olhar, por exemplo, no livro de Lyons - é

while(condition)       // Here's the whole thing
    ;                  // empty body.

Na verdade, em geral, o 'semicolor em uma linha separada' convenção é usada para uma declaração nulo. Você vai, por exemplo, ocasionalmente ver

if( condition-1)
     ;
else if (condition-2)
     stmt;
else {
     // do stuff here
}

É muito mais raro, mas mostra-se tanto que condição-1 é muito complicado, então você não quer negá-lo e oportunidade confusão, ou onde o código foi otimizado mão dentro de uma polegada de sua vida, de modo que você quer que o caso mais comum em primeiro lugar.

O

while(condition) ;

formulário deve ser servilmente evitada, porque isso é um erro de digitação comum e chato: você deve deixar claro que você fez isso de propósito. chaves vazias

 while(condition){
 }

ou suas variantes, são também problemas porque ou não se destacam o suficiente, ou pior levar a outros erros de digitação.

Bem, não realmente, mas isso depende de sua arquitetura.

if (dosomething()) { ; }

O acima vai ser constantemente empurrando e estalando de sua pilha local, que tem uma sobrecarga de memória. Além disso, você também estará liberando pipelines de seus processadores com operações NOOP.

Uma opção alternativa que não tenha sido mencionado ainda:

while(condition)
    (void)0;

Eu realmente não prefiro escrever meus laços dessa maneira , mas eu tinha um último semestre TA que fez.

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