Exercício 1. Considere o trexo de código abaixo:
char string1[128];
printf("digite uma palavra:\n");
fgets(string1, 128, stdin);
*(strchr(string1, '\n')) = '\0';
Explique, passo a passo, o que faz a última linha *(strchr(string1, '\n')) = '\0'. Consute a documentação da função strchr aqui.
(1) strchr(string1, '\n') retorna um ponteiro para a primeira ocorrência de quebra de linha ('\n') em string1. (2) *(x) = '\0' coloca o caractere terminador '\0' na posição apontada por x. (3) No caso, *(strchr(string1, '\n')) = '\0' coloca o caractere terminador '\0' na posição onde ocorre a primeira ocorrência de quebra de linha em string1. Esse comando efetivamente retira o caractere '\n' de string1 substituindo-o pelo caractere terminador '\0'.
Exercício 2. Todos os programas abaixo têm um erro. Explique detalhadamente o erro e como consertá-lo. Você pode baixar o código fonte dos programas para testá-los aqui.
Programa 1
#include <stdio.h>
int main(int argc, char **argv)
{
int i = 0;
int j = 0;
int contador = 0;
for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++);
contador++;
printf("contador = %d\n", contador);
printf("pressione qualquer tecla para terminar\n");
getc(stdin);
return 0;
}
Esse programa tem um ponto-e-vírgula depois do segundo for. Isso faz com que o segundo for tenha um bloco de comandos vazio. O comando contador++ está fora dos dois fors e é executado apenas uma vez.
Programa 2
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
int soma;
for(i = 0; i < 10; i++) {
soma += 10;
}
printf("10 * 10 = %d\n", soma);
printf("pressione qualquer tecla para terminar\n");
getc(stdin);
return 0;
}
A variável soma não é inicializada. O resultado impresso no printf não é definido.
Programa 3
#include <stdio.h>
int main(int argc, char **argv)
{
char linha[128];
int num;
int resto;
printf("digite um numero:\n");
fgets(linha, 128, stdin);
sscanf(linha, "%d\n", &num);
resto = num % 2;
if(resto = 0) {
printf("num eh par\n");
} else {
printf("num eh impar\n");
}
printf("pressione qualquer tecla para terminar\n");
getc(stdin);
return 0;
}
O if não está usando o operador de comparação (==), mas sim o operador de atribuição (=). Neste caso, a expressão resto = 0 coloca o valor zero na variável resto. O valor dessa expressão, utilizado no if, é zero (falso). Logo, essa função sempre imprime "num eh impar".
Programa 4
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char string1[128];
char string2[128];
printf("digite uma palavra:\n");
fgets(string1, 128, stdin);
*(strchr(string1, '\n')) = '\0';
printf("digite outra palavra:\n");
fgets(string2, 128, stdin);
*(strchr(string2, '\n')) = '\0';
if(string1 == string2) {
printf("strings %s e %s sao iguais\n", string1, string2);
} else {
printf("strings %s e %s sao diferentes\n", string1, string2);
}
printf("pressione qualquer tecla para terminar\n");
getc(stdin);
return 0;
}
A expressão string1 == string2 converte o nome string1 e string2 para a posição de memória das variáveis string1[0] e string2[0] (as primeiras variáveis em cada vetor), depois compara as duas posições de memória. A expressão no if deveria testar se os caracteres nos vetores string1 e string2 são os mesmos (por exemplo, usando a função strcmp), não comparar as posições de memória.
Programa 5
#include <stdio.h>
int main(int argc, char **argv)
{
int numbers[10];
int i;
for(i = 0; i <= 10; i++) {
numbers[i] = 0;
}
printf("pressione qualquer tecla para terminar\n");
getc(stdin);
return 0;
}
Esse programa escreve zero na posição de memória numbers[10], que não faz parte do vetor. No caso, se i for alocado logo depois do vetor numbers na memória do computador, colocar zero na posição numbers[10] é equivalente a colocar zero na variável i e o programa entra em loop infinito.
Programa 6
#include <stdio.h>
int main(int argc, char **argv)
{
char palavra[128];
palavra[0] = 'b';
palavra[1] = 'a';
palavra[2] = 'n';
palavra[3] = 'a';
palavra[4] = 'n';
palavra[5] = 'a';
printf("{{{%s}}}\n", palavra);
printf("pressione enter para terminar\n");
getc(stdin);
return 0;
}
Esse programa não termina o string "banana" com o caractere terminador '\0'. Neste caso, o printf pode imprimir uma quantidade arbitrária de lixo até encontrar um caractere terminador. Se nenhum caractere terminador for encontrado o programa travará quando fizer acesso além da memória dele.
Programa 7
#include <stdio.h>
int main(int argc, char **argv)
{
char palavra[5] = "hello";
int i = -1;
printf("%d {{{%s}}}\n", i, palavra);
printf("pressione enter para terminar\n");
getc(stdin);
return 0;
}
Problema similar ao do exercício 6; a palavra "hello" não tem o caractere terminador '\0' porque o arranjo não tem espaço sufiente para armazenar os seis caracteres necessários.