Quase todas as linguagens possuem um foreach
loop ou algo semelhante. C tem um? Você pode postar algum código de exemplo?
110
Quase todas as linguagens possuem um foreach
loop ou algo semelhante. C tem um? Você pode postar algum código de exemplo?
foreach
" de quê?foreach
loop em um programa C?Respostas:
C não tem um foreach, mas as macros são freqüentemente usadas para emular que:
E pode ser usado como
A iteração sobre uma matriz também é possível:
E pode ser usado como
Editar: caso você também esteja interessado em soluções C ++, C ++ tem uma sintaxe nativa para cada chamada "intervalo baseado em"
fonte
#define foreach(item, array) int count=0, size=sizeof(array)/sizeof(*(array)); for(item = (array); count != size; count++, item = (array)+count)
um problema que posso ver é que a contagem e o tamanho das variáveis residem fora do loop for e podem causar um conflito. É este o motivo de você usar dois loops for? [código colado aqui ( pastebin.com/immndpwS )]if(...) foreach(int *v, values) ...
. Se eles estiverem fora do loop, ele se expandiráif(...) int count = 0 ...; for(...) ...;
e será interrompido.Aqui está um exemplo de programa completo de uma macro para cada em C99:
fonte
list[]
definição? Você não poderia simplesmente escrever emnext
vez de.next
?free()
) e por outro tem uma referência ao valor dentro de sua definição. É realmente um exemplo de algo que é muito inteligente; o código é complexo o suficiente sem adicionar inteligência propositalmente a ele. O aforismo de Kernighan ( stackoverflow.com/questions/1103299/… ) se aplica!Não há foreach em C.
Você pode usar um loop for para percorrer os dados, mas o comprimento precisa ser conhecido ou os dados precisam ser encerrados por um valor conhecido (por exemplo, nulo).
fonte
Como você provavelmente já sabe, não há loop no estilo "foreach" em C.
Embora já existam muitas macros excelentes fornecidas aqui para contornar isso, talvez você ache esta macro útil:
... que pode ser usado com
for
(como emfor each (...)
).Vantagens desta abordagem:
item
é declarado e incrementado dentro da instrução for (assim como no Python!).p
,item
) não são visíveis fora do escopo do loop (já que são declaradas no cabeçalho do loop for).Desvantagens:
typeof()
, que é uma extensão GNU, não faz parte do padrão CSó para economizar seu tempo, veja como você pode testá-lo:
Parece funcionar no gcc e clang por padrão; não testei outros compiladores.
fonte
Esta é uma pergunta bastante antiga, mas eu pensei que deveria postar isto. É um loop foreach para GNU C99.
Este código foi testado para funcionar com gcc, icc e clang no GNU / Linux.
fonte
Embora C não tenha um para cada construção, sempre teve uma representação idiomática para um após o final de um array
(&arr)[1]
. Isso permite que você escreva uma linguagem idiomática simples para cada loop da seguinte maneira:fonte
(&arr)[1]
não significa um item do array após o final do array, significa um array após o final do array.(&arr)[1]
não é o último item da matriz [0], é a matriz [1], que se transforma em um ponteiro para o primeiro elemento (da matriz [1]). Eu acredito que seria muito melhor, mais seguro e idiomático de fazerconst int* begin = arr; const int* end = arr + sizeof(arr)/sizeof(*arr);
e entãofor(const int* a = begin; a != end; a++)
.C tem palavras-chave 'para' e 'enquanto'. Se uma instrução foreach em uma linguagem como C # for assim ...
... então o equivalente a esta instrução foreach em C pode ser como:
fonte
Aqui está o que eu uso quando estou preso com C. Você não pode usar o mesmo nome de item duas vezes no mesmo escopo, mas isso não é realmente um problema, pois nem todos nós conseguimos usar novos compiladores legais :(
Uso:
EDIT: Aqui está uma alternativa para
FOREACH
usar a sintaxe c99 para evitar poluição do namespace:fonte
VAR(i) < (size) && (item = array[VAR(i)])
iria parar quando o elemento da matriz tivesse um valor 0. Portanto, usar isso comdouble Array[]
pode não iterar por todos os elementos. Parece que o teste de loop deve ser um ou outro:i<n
ouA[i]
. Talvez adicione casos de uso de amostra para maior clareza.if ( bla ) FOREACH(....) { } else....
FOREACH
que usa a sintaxe c99 para evitar poluição do namespace.A resposta de Eric não funciona quando você está usando "break" ou "continue".
Isso pode ser corrigido reescrevendo a primeira linha:
Linha original (reformatada):
Fixo:
Se você comparar com o loop de Johannes, verá que ele está realmente fazendo o mesmo, só que um pouco mais complicado e feio.
fonte
Aqui está um simples, único loop for:
Fornece acesso ao índice, caso você queira (
i
) e ao item atual sobre o qual estamos iterando (it
). Observe que você pode ter problemas de nomenclatura ao aninhar loops, você pode fazer com que os nomes dos itens e índices sejam parâmetros para a macro.Editar: aqui está uma versão modificada da resposta aceita
foreach
. Permite que você especifique ostart
índice, osize
para que funcione em matrizes decadentes (ponteiros), sem necessidade deint*
e alteradocount != size
parai < size
apenas no caso de o usuário modificar acidentalmente 'i' para ser maior quesize
e ficar preso em um loop infinito.Resultado:
fonte
Se você está planejando trabalhar com ponteiros de função
Uso:
Mas acho que isso funcionará apenas no gcc (não tenho certeza).
fonte
C não tem uma implementação de
for-each
. Ao analisar um array como um ponto, o receptor não sabe o tamanho do array, portanto, não há como saber quando você chega ao final do array. Lembre-se, em Cint*
é um ponto para um endereço de memória contendo um int. Não há nenhum objeto de cabeçalho contendo informações sobre quantos inteiros são colocados em sequência. Portanto, o programador precisa acompanhar isso.No entanto, para listas, é fácil implementar algo que se pareça com um
for-each
loop.Para obter algo semelhante para arrays, você pode fazer uma das duas coisas.
A seguir está um exemplo de tal estrutura:
fonte