O que faz a seguinte função?
void imprime (char *v, int n) {
char *c;
for (c = v; c < v + n; c++)
printf ("%c", *c);
}
void imprime (char *v, int n) {
char *c;
for (c = v; c < v + n; c++)
printf ("%c", *c);
}
Passo 1
O enunciado pergunta: “O que faz a seguinte função?” e fornece o código abaixo:
void imprime (char *v, int n) {
char *c;
for (c = v; c < v + n; c++)
printf ("%c", *c);
}
Informações dadas pelo enunciado:
- A função chama‑se
imprime. - Tem dois parâmetros:
char *veint n. - Há uma variável local
char *c. - Um laço
forinicializac = v, testac < v + n, incrementac++. - Dentro do laço chama
printf("%c", *c);.
Passo 2
Significado dos parâmetros (explicação didática e sem pular etapas):
char *v: é um ponteiro parachar. Em C isso normalmente representa o início de um bloco de memória contendo bytes/ caracteres (por exemplo, uma string ou um buffer). Vou indicar esse ponteiro como. int n: é um inteiro que indica quantos caracteres (ou bytes) a função pretende processar. Vou indicar esse inteiro como.
Na prova: pense em
como “endereço do primeiro caractere” e em
como “quantos caracteres quero”. Não diz se
aponta para uma string terminada em
'\0'; apenas temos um ponteiro.Passo 3
O que faz
char *c; e c = v;:char *c;declara outra variável ponteiro parachar. Chamo‑a de. c = v;fazapontar para o mesmo endereço que — ou seja, começa apontando para o primeiro elemento do bloco apontado por . - Em termos de índices, se o bloco em
é um array , então inicialmente aponta para .
Passo 4
Entendendo a condição do laço
c < v + n (ponteiro + inteiro):- Em C, expressão
v + nrealiza aritmética de ponteiros: pega o ponteiroe avança posições de char. O resultado é o ponteiro para o elemento com índice(ou seja, para ). - A comparação
c < v + né verdadeira enquanto o ponteiroestiver antes desse endereço . - Portanto o laço percorre os ponteiros
até, mas não incluindo, . Isso corresponde a percorrer exatamente posições: índices até .
Observação importante sobre validade: essa comparação de ponteiros só é definida pelo padrão C se ambos os ponteiros apontarem para elementos do mesmo array (ou um ponteiro para uma posição logo após o array). Na prática, assume‑se que
aponta para um bloco com pelo menos
bytes.
Passo 5
O que faz
c++ no laço:c++incrementa o ponteiropara apontar ao próximo char. Em C isso significa somar1 * sizeof(char)ao endereço — comosizeof(char)vale, avança exatamente um byte. - Assim, a cada iteração
passa de para .
Passo 6
O que faz
printf("%c", *c);:*cé a operação de desreferência: obtém ochararmazenado no endereço apontado por. Se aponta para v[i], então*cé o valor dev[i].printf("%c", ...)imprime esse valor como um caractere (formato%cimprime um único caractere).- Não há
\nnem outro separador: os caracteres são enviados exatamente como estão, um após o outro, sem quebra de linha automática.
Passo 7
Juntando tudo: comportamento observável
- O laço começa com
e repete enquanto , incrementando a cada passo. - Em cada passo imprime
*ccomo caractere. - Logo, a função imprime, na saída padrão, os
bytes (ou caracteres) que se encontram nas posições , na mesma ordem, sem adicionar nova linha ou espaços extras.
Exemplo concreto (para fixar): se chamar bytes.
imprime("Olá\n", 4) (aqui a string literal tem os bytes O, l, á, \n), a função imprimirá exatamente Olá seguido de uma quebra de linha, porque foram pedidos
Passo 8
Casos especiais e comportamento indesejado (coisas que costumam cair na prova)
- Se
: o laço não executa nada — nenhum caractere é impresso. - Se
for NULLe a função for chamada comNULL, acessarvé comportamento indefinido (provavelmente crash). - Se
for maior que o tamanho real do buffer apontado por , a função lerá memória além do fim — isso é undefined behavior (pode corromper memória, mostrar lixo, travar o programa). - A função NÃO verifica
'\0', então ela não depende de string terminada; ela imprime exatamentebytes, mesmo que haja '\0'no meio (nesse caso'\0'é um caractere nulo e geralmente não visível). - Se os bytes não forem caracteres imprimíveis, a saída pode conter caracteres estranhos ou não aparecer visualmente.
Passo 9
Complexidade e alternativas seguras
- Complexidade: faz uma iteração por cada caractere, então tempo proporcional a
— ou seja, . - Alternativa segura e equivalente se o objetivo for imprimir
bytes para a saída padrão: usar fwrite(v, 1, n, stdout);— isso evita chamada repetida aprintfe é mais direta para blocos binários. - Se o objetivo é imprimir uma string C típica (até
'\0'), usarprintf("%s", v);ouputs(v);seria apropriado, mas aqui a função original não faz isso (ela usa contagem explícita).
Passo 10
Resumo didático e dica para prova (estilo amigo e encorajador)
- Resumindo em uma frase simples e prática: a função percorre os
bytes começando em e imprime cada um como caractere, sem adicionar nova linha. - Dica para prova: ao ver
for (c = v; c < v + n; c++) printf("%c", *c);traduza mentalmente para “para i = 0 até n-1, imprima v[i]”. Se precisar justificar segurança, comente sobre necessidade deter pelo menos elementos e o risco de comportamento indefinido.
Resposta
Imprime, na saída padrão, os
caracteres (bytes) começando em
— ou seja, imprime
na ordem, sem adicionar nova linha; se
não apontar para um bloco com pelo menos
bytes (ou for NULL) o comportamento é indefinido.