Este documento apresenta uma série de exercícios de programação em C, abrangendo diferentes aspectos da linguagem, desde manipulação de strings e arrays até operações com arquivos e cálculo de séries. Cada conjunto de exercícios inclui um problema de preenchimento de código, um de modificação de código e um de design de função, todos com foco na lógica e na correção.
Conjunto 76
1. Preenchimento de Código
Na função fornecida, o objetivo é encontrar todos os números inteiros entre 100 e 999 (inclusive) cuja soma dos dígitos seja igual a um valor específico somaAlvo (um inteiro positivo). A função deve imprimir esses números e retornar a contagem de quantos números atendem à condição.
Por exemplo, se somaAlvo for 5, os números entre 100 e 999 com soma de dígitos igual a 5 são: 104, 113, 122, 131, 140, 203, 212, 230, 302, 311, 320, 401, 410, 500. Existem 15 números no total.
Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
int encontrarNumerosComSomaDeDigitos(int somaAlvo)
{
int numeroAtual, digitoUnidade, digitoDezena, digitoCentena;
int contador = 0;
numeroAtual = 100;
// Lacuna 1
while (numeroAtual <= ___1___)
{
digitoUnidade = numeroAtual % 10;
// Lacuna 2
digitoDezena = (___2___ / 10) % 10;
digitoCentena = numeroAtual / 100;
// Lacuna 3
if (digitoUnidade + digitoDezena + digitoCentena == ___3___)
{
printf("%d ", numeroAtual);
contador++;
}
numeroAtual++;
}
return contador;
}
int main()
{
int valorUsuario = -1;
while (valorUsuario < 0)
{
printf("Por favor, insira um valor (soma > 0): ");
scanf("%d", &valorUsuario);
}
printf("\nO resultado e: %d\n", encontrarNumerosComSomaDeDigitos(valorUsuario));
return 0;
}
2. Modificação de Código
A função processarNumeros tem como objetivo selecionar números entre 10 e 55 que são divisíveis por 3 e contêm o dígito 5 em qualquer uma de suas posições. Esses números devem ser armazenados em um array apontado por arraySaida, e a função deve retornar a quantidade de números encontrados.
Corrija os erros nas partes indicadas da função processarNumeros para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
int processarNumeros(int *arraySaida)
{
int numero, digitoUnidade, digitoDezena;
int indice = 0;
for (numero = 10; numero <= 55; numero++)
{
// ERRO 1
digitoDezena = numero % 10;
digitoUnidade = numero - digitoDezena * 10;
if ((numero % 3 == 0 && digitoDezena == 5) || (numero % 3 == 0 && digitoUnidade == 5))
{
arraySaida[indice] = numero;
indice++;
}
}
// ERRO 2
return numero;
}
int main()
{
int meuArray[100], k, quantidade;
quantidade = processarNumeros(meuArray);
printf("Os numeros encontrados sao:\n");
for (k = 0; k < quantidade; k++)
printf("%4d", meuArray[k]);
printf("\n");
return 0;
}
3. Design de Função
Assumindo que uma string de entrada contém apenas letras e asteriscos (\*), crie a função removerAsteriscosFinais. Sua funcionalidade é remover todos os asteriscos que aparecem no final da string. Os asterisocs localizados no início ou no meio da string não devem ser removidos.
Por exemplo, se a string for "\*****A\*BC\*DEF\*G\***", após a remoção, o conteúdo da string deverá ser "\*****A\*BC\*DEF\*G".
Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função removerAsteriscosFinais.
#include <stdio.h>
#include <string.h>
void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar
void removerAsteriscosFinais(char *texto)
{
// SEU CÓDIGO AQUI
}
int main()
{
char textoEntrada[81];
printf("Digite uma string:\n");
fgets(textoEntrada, sizeof(textoEntrada), stdin); // Usar fgets para entrada segura
textoEntrada[strcspn(textoEntrada, "\n")] = 0; // Remover newline, se houver
removerAsteriscosFinais(textoEntrada);
printf("A string apos remocao e:\n");
puts(textoEntrada);
funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
return 0;
}
void funcaoAuxiliarNaoModificar(void)
{
/* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
FILE *entradaArquivo, *saidaArquivo;
int i;
char buffer[81];
entradaArquivo = fopen("entrada.dat", "r");
saidaArquivo = fopen("saida.dat", "w");
if (!entradaArquivo || !saidaArquivo) {
perror("Erro ao abrir arquivos");
return;
}
for (i = 0; i < 10; i++)
{
if (fscanf(entradaArquivo, "%s", buffer) != 1) break;
removerAsteriscosFinais(buffer);
fprintf(saidaArquivo, "%s\n", buffer);
}
fclose(entradaArquivo);
fclose(saidaArquivo);
}
Soluções para o Conjunto 76
1. Preenchimento de Código:
while (numeroAtual <= 999) // ___1___
{
// ...
digitoDezena = (numeroAtual / 10) % 10; // ___2___
// ...
if (digitoUnidade + digitoDezena + digitoCentena == somaAlvo) // ___3___
// ...
2. Modificação de Código:
digitoUnidade = numero % 10; // ERRO 1 Corrigido
digitoDezena = numero / 10; // ERRO 1 Corrigido
// ...
return indice; // ERRO 2 Corrigido
3. Design de Função:
void removerAsteriscosFinais(char *texto)
{
int tamanho = strlen(texto);
if (tamanho == 0) return;
int indiceFinal = tamanho - 1;
while (indiceFinal >= 0 && texto[indiceFinal] == '*')
{
indiceFinal--;
}
// O próximo caractere após 'indiceFinal' deve ser o terminador nulo
texto[indiceFinal + 1] = '\0';
}
Conjunto 77
1. Preenchimento de Código
A função calcularSerie é responsável por computar a soma de uma série até que o valor absoluto do termo atual seja menor ou igual a um limite limiteErro (10-3 no exemplo). O resultado da soma é retornado como o valor da função.
Por exemplo, se o valor do parâmetro limiteErro for 1e-3, o valor retornado da função é 2.985678.
Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
#include <math.h> // Para usar fabs
double calcularSerie(double limiteErro)
{
int contadorTermo;
double somaTotal, valorTermo;
// Lacuna 1
somaTotal = 0;
contadorTermo = ___1___;
valorTermo = 1.0;
while (fabs(valorTermo) > limiteErro) // Usando fabs para valor absoluto
{
// Lacuna 2
___2___;
// Lacuna 3
valorTermo = (2.0 * contadorTermo - 1) / ((___3___) * (2.0 * contadorTermo));
somaTotal += valorTermo;
}
return somaTotal;
}
int main()
{
double e = 1e-3;
printf("\nO resultado e: %f\n", calcularSerie(e));
return 0;
}
2. Modificação de Código
A função unirStringReversa é projetada para concatenar uma string (apontada por stringOriginal) com sua versão invertida, armazenando o novo resultado em um array apontado por stringConcatenada.
Por exemplo, se stringOriginal for "ABCD", o conteúdo de stringConcatenada deverá ser "ABCDDCBA".
Corrija os erros nas partes indicadas da função unirStringReversa para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
#include <string.h>
// ERRO 1
void unirStringReversa(char stringOriginal, char stringConcatenada)
{
int i, comprimento;
comprimento = strlen(stringOriginal);
for (i = 0; i < comprimento; i++)
stringConcatenada[i] = stringOriginal[i];
for (i = 0; i < comprimento; i++)
stringConcatenada[comprimento + i] = stringOriginal[comprimento - 1 - i];
// ERRO 2
stringConcatenada[2 * comprimento - 1] = '\0';
}
int main()
{
char s[100], t[100];
printf("\nPor favor, digite a string S: ");
scanf("%s", s);
unirStringReversa(s, t);
printf("\nO resultado e: %s\n", t);
return 0;
}
3. Design de Função
Implemente a função filtrarCaracteres. Sua tarefa é remover da string apontada por stringFonte todos os caracteres, exceto aqueles cujo índice na string é ímpar E cujo valor ASCII também é ímpar. Os caracteres restantes devem formar uma nova string, armazenada no array apontado por stringDestino.
Por exemplo, se o conteúdo de stringFonte for "ABCDEFG12345", o conteúdo de stringDestino deverá ser "135".
Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função filtrarCaracteres.
#include <stdio.h>
#include <string.h>
void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar
void filtrarCaracteres(char *stringFonte, char stringDestino[])
{
// SEU CÓDIGO AQUI
}
int main()
{
char s[100], t[100];
printf("\nPor favor, digite a string S: ");
scanf("%s", s);
filtrarCaracteres(s, t);
printf("\nO resultado e: %s\n", t);
funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
return 0;
}
void funcaoAuxiliarNaoModificar(void)
{
/* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
char s[100], t[100];
FILE *leituraArquivo, *escritaArquivo;
int i;
leituraArquivo = fopen("entrada.dat", "r");
escritaArquivo = fopen("saida.dat", "w");
if (!leituraArquivo || !escritaArquivo) {
perror("Erro ao abrir arquivos");
return;
}
for (i = 0; i < 10; i++)
{
if (fscanf(leituraArquivo, "%s", s) != 1) break;
filtrarCaracteres(s, t);
fprintf(escritaArquivo, "%s\n", t);
}
fclose(leituraArquivo);
fclose(escritaArquivo);
}
Soluções para o Conjunto 77
1. Preenchimento de Código:
contadorTermo = 0; // ___1___
// ...
contadorTermo++; // ___2___
// ...
valorTermo = (2.0 * contadorTermo - 1) / ((2.0 * contadorTermo) * (2.0 * contadorTermo)); // ___3___
// ...
2. Modificação de Código:
void unirStringReversa(char *stringOriginal, char *stringConcatenada) // ERRO 1 Corrigido
{
// ...
stringConcatenada[2 * comprimento] = '\0'; // ERRO 2 Corrigido
}
3. Design de Função:
void filtrarCaracteres(char *stringFonte, char stringDestino[])
{
int i, j = 0;
for (i = 0; stringFonte[i] != '\0'; i++)
{
// Verifica se o índice é ímpar E o valor ASCII é ímpar
if ((i % 2 != 0) && (stringFonte[i] % 2 != 0))
{
stringDestino[j++] = stringFonte[i];
}
}
stringDestino[j] = '\0'; // Termina a nova string
}
Conjunto 78
1. Preenchimento de Código
A função inverterArray tem a finalidade de inverter os valores dos elementos em um array.
Por exemplo, se os dados no array apontado por arr forem sequencialmente: 1, 2, 3, 4, 5, 6, 7, 8, 9, após a inversão eles deverão ser: 9, 8, 7, 6, 5, 4, 3, 2, 1.
Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
void inverterArray(int arr[], int tamanho)
{
int i, temp;
// Lacuna 1
for (i = 0; i < ___1___; i++)
{
temp = arr[i];
// Lacuna 2
arr[i] = arr[tamanho - 1 - ___2___];
// Lacuna 3
___3___ = temp;
}
}
int main()
{
int dados[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}, i;
printf("\nDados originais:\n");
for (i = 0; i < 9; i++)
printf("%4d ", dados[i]);
printf("\n");
inverterArray(dados, 9);
printf("\nDados apos inversao:\n");
for (i = 0; i < 9; i++)
printf("%4d ", dados[i]);
printf("\n");
return 0;
}
2. Modificação de Código
A função produtoDosDigitos tem a funcionalidade de calcular o produto dos dígitos de um número inteiro valor.
Por exemplo, se a entrada for 252, a saída deverá ser 20; se a entrada for 202, a saída deverá ser 0.
Corrija os erros nas partes indicadas da função produtoDosDigitos para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do prograam.
#include <stdio.h>
long produtoDosDigitos(long valor)
{
// ERRO 1
long resultadoProduto;
do
{
resultadoProduto *= valor % 10;
// ERRO 2
valor = 10;
} while (valor);
return (resultadoProduto);
}
int main()
{
long n;
printf("Por favor, digite um numero: ");
scanf("%ld", &n);
printf("\n%ld\n", produtoDosDigitos(n));
return 0;
}
3. Design de Função
Desenvolva a função encontrarMaximoEIndice. Sua finalidade é encontrar o maior valor em um array unidimensional e seu respectivo índice. O maior valor e o índice são retornados através dos parâmetros de ponteiro maximo e indiceMaximo, respectivamente.
Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função encontrarMaximoEIndice.
#include <stdio.h>
#include <stdlib.h> // Para rand()
void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar
void encontrarMaximoEIndice(int arr[], int tamanho, int *maximo, int *indiceMaximo)
{
// SEU CÓDIGO AQUI
}
int main()
{
int i, valores[20], maiorValor, indiceDoMaior, N = 10;
for (i = 0; i < N; i++)
{
valores[i] = rand() % 50;
printf("%4d", valores[i]);
}
printf("\n");
encontrarMaximoEIndice(valores, N, &maiorValor, &indiceDoMaior);
printf("Max =%5d , Indice =%4d\n", maiorValor, indiceDoMaior);
funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
return 0;
}
void funcaoAuxiliarNaoModificar(void)
{
/* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
FILE *arquivoLeitura, *arquivoEscrita;
int i, x[20], max, index, n = 10, j;
arquivoLeitura = fopen("entrada.dat", "r");
arquivoEscrita = fopen("saida.dat", "w");
if (!arquivoLeitura || !arquivoEscrita) {
perror("Erro ao abrir arquivos");
return;
}
for (i = 0; i < 10; i++)
{
for (j = 0; j < n; j++)
if (fscanf(arquivoLeitura, "%d,", &x[j]) != 1) break;
encontrarMaximoEIndice(x, n, &max, &index);
fprintf(arquivoEscrita, "Max=%d,Indice=%d\n", max, index);
}
fclose(arquivoLeitura);
fclose(arquivoEscrita);
}
Soluções para o Conjunto 78
1. Preenchimento de Código:
for (i = 0; i < tamanho / 2; i++) // ___1___
{
temp = arr[i];
arr[i] = arr[tamanho - 1 - i]; // ___2___
arr[tamanho - 1 - i] = temp; // ___3___
}
2. Modificação de Código:
long produtoDosDigitos(long valor)
{
long resultadoProduto = 1; // ERRO 1 Corrigido: Inicializar com 1 para produto
do
{
resultadoProduto *= valor % 10;
valor /= 10; // ERRO 2 Corrigido: Dividir por 10 para remover o último dígito
} while (valor);
return (resultadoProduto);
}
3. Design de Função:
void encontrarMaximoEIndice(int arr[], int tamanho, int *maximo, int *indiceMaximo)
{
int i;
// Assume que o array não está vazio e inicializa com o primeiro elemento
*maximo = arr[0];
*indiceMaximo = 0;
for (i = 1; i < tamanho; i++)
{
if (arr[i] > *maximo)
{
*maximo = arr[i];
*indiceMaximo = i;
}
}
}
Conjunto 79
1. Preenchimento de Código
A função analisarNumeros calcula a média de NUM_ELEMENTOS números (todos positivos) em um array apontado por dados. A média é retornada à função principal através do parâmetro de ponteiro mediaCalculada. Além disso, a função retorna como seu valor o número que é menor que a média e o mais próximo dela.
Por exemplo, para 10 números positivos: 40 30 32 40 6 17 45 15 48 26, a média é: 35.500000. O valor retornado pela função principal deve ser 30.0.
Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
#include <stdlib.h> // Para rand()
#define NUM_ELEMENTOS 10
double analisarNumeros(double dados[], double *mediaCalculada)
{
int i, indiceProximo = 0;
double diferencaMinima = 32767.0; // Um valor grande inicial para a menor diferença
double soma = 0;
for (i = 0; i < NUM_ELEMENTOS; i++)
soma += dados[i];
// Lacuna 1
___1___ = soma / NUM_ELEMENTOS;
for (i = 0; i < NUM_ELEMENTOS; i++)
if (dados[i] < *mediaCalculada && (*mediaCalculada - dados[i]) <= diferencaMinima)
{
// Lacuna 2
diferencaMinima = *mediaCalculada - dados[i];
indiceProximo = ___2___;
}
// Lacuna 3
return ___3___;
}
int main()
{
int i;
double valores[NUM_ELEMENTOS], media, numeroProximo;
for (i = 0; i < NUM_ELEMENTOS; i++)
{
valores[i] = rand() % 50 + 1; // Gerar números positivos
printf("%4.0f ", valores[i]);
}
printf("\n");
numeroProximo = analisarNumeros(valores, &media);
printf("\nA media e: %f\n", media);
printf("O numero mais proximo e: %5.1f\n", numeroProximo);
printf("\n");
return 0;
}
2. Modificação de Código
A função calcularSerieSubtrativa tem a finalidade de calcular o valor de S, onde S é uma série do tipo aa..aa - ...aaa - aa - a (onde aa..aa representa n repetições do dígito a, e os valores de a e n estão entre 1 e 9).
Por exemplo, se a=3 e n=6, a expressão é: S = 333333 - 33333 - 3333 - 333 - 33 - 3, cujo valor é 296298.
Corrija os erros nas partes indicadas da função calcularSerieSubtrativa para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
long calcularSerieSubtrativa(int digito, int repeticoes)
{
int j;
// ERRO 1
long somaSerie = 0, termoAtual = 1;
for (j = 0; j < repeticoes; j++)
termoAtual = termoAtual * 10 + digito; // Constrói o maior número a...a
somaSerie = termoAtual; // Inicializa a soma com o maior número
for (j = 1; j < repeticoes; j++)
{
// ERRO 2
termoAtual = termoAtual % 10; // Reduz o termo atual para o próximo na série
somaSerie = somaSerie - termoAtual;
}
return (somaSerie);
}
int main()
{
int a, n;
printf("\nPor favor, digite 'a' e 'n': ");
scanf("%d%d", &a, &n);
printf("O valor da funcao e: %ld\n", calcularSerieSubtrativa(a, n));
return 0;
}
3. Design de Função
Crie a função contarFrequenciaLetras. Sua função é contar quantas vezes cada uma das 26 letras minúsculas ('a' a 'z') aparece na string textoEntrada e armazenar essas contagens no array apontado por frequencias.
Por exemplo, se a string de entrada for: "abcdefgabcdeabc", a saída do programa deverá ser: 3 3 3 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (representando as contagens de 'a' a 'z').
Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função contarFrequenciaLetras.
#include <stdio.h>
#include <string.h>
void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar
void contarFrequenciaLetras(char *textoEntrada, int frequencias[])
{
// SEU CÓDIGO AQUI
}
int main()
{
char texto[1000];
int contagens[26], k;
printf("\nPor favor, digite uma string de caracteres: ");
scanf("%s", texto);
contarFrequenciaLetras(texto, contagens);
for (k = 0; k < 26; k++)
printf("%d ", contagens[k]);
printf("\n");
funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
return 0;
}
void funcaoAuxiliarNaoModificar(void)
{
/* Esta função é usada para abrir arquivos, inserir dados de teste, chamar a função fun e exibir/gravar dados. */
char texto[1000];
int contagens[26], k, i;
FILE *leituraArquivo, *escritaArquivo;
leituraArquivo = fopen("entrada.dat", "r");
escritaArquivo = fopen("saida.dat", "w");
if (!leituraArquivo || !escritaArquivo) {
perror("Erro ao abrir arquivos");
return;
}
for (i = 0; i < 10; i++)
{
if (fscanf(leituraArquivo, "%s", texto) != 1) break;
contarFrequenciaLetras(texto, contagens);
for (k = 0; k < 26; k++)
fprintf(escritaArquivo, "%d ", contagens[k]);
fprintf(escritaArquivo, "\n");
}
fclose(leituraArquivo);
fclose(escritaArquivo);
}
Soluções para o Conjunto 79
1. Preenchimento de Código:
*mediaCalculada = soma / NUM_ELEMENTOS; // ___1___
// ...
indiceProximo = i; // ___2___
// ...
return dados[indiceProximo]; // ___3___
2. Modificação de Código:
long calcularSerieSubtrativa(int digito, int repeticoes)
{
int j;
long somaSerie = 0, termoAtual = 0; // ERRO 1 Corrigido: Inicializar termoAtual com 0
for (j = 0; j < repeticoes; j++)
termoAtual = termoAtual * 10 + digito;
somaSerie = termoAtual;
for (j = 1; j < repeticoes; j++)
{
termoAtual = termoAtual / 10; // ERRO 2 Corrigido: Dividir por 10 para remover o último dígito
somaSerie = somaSerie - termoAtual;
}
return (somaSerie);
}
3. Design de Função:
void contarFrequenciaLetras(char *textoEntrada, int frequencias[])
{
int i;
// Inicializa todas as contagens para zero
for (i = 0; i < 26; i++)
{
frequencias[i] = 0;
}
// Percorre a string e conta as frequências
for (i = 0; textoEntrada[i] != '\0'; i++)
{
if (textoEntrada[i] >= 'a' && textoEntrada[i] <= 'z')
{
frequencias[textoEntrada[i] - 'a']++;
}
}
}
Conjunto 80
1. Preenchimento de Código
O programa define uma estrutura Aluno para armazenar número de matrícula, nome e notas de 3 disciplinas. Todos os dados dos alunos são escritos em modo binário no arquivo "student.dat". A função atualizarNotasAluno busca os dados de um aluno específico pelo número de matrícula no arquivo. Se encontrado, lê os dados, aumenta cada nota em 3 pontos e reescreve os dados modificados no mesmo local do arquivo, mantendo os outros dados inalterados. Se o aluno não for encnotrado, nenhuma ação é realizada.
Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
#define NUM_ALUNOS 5
typedef struct aluno
{
long matricula;
char nome[10];
float notas[3];
} Aluno;
void atualizarNotasAluno(char *nomeArquivo, long matriculaAlvo)
{
FILE *fp;
Aluno alunoLido;
int i;
fp = fopen(nomeArquivo, "rb+");
if (fp == NULL) {
perror("Erro ao abrir o arquivo");
return;
}
// Lacuna 1
while (!___1___(fp))
{
fread(&alunoLido, sizeof(Aluno), 1, fp);
// Lacuna 2
if (alunoLido.matricula ___2___ matriculaAlvo)
break;
}
if (!feof(fp)) // Se o aluno foi encontrado e o final do arquivo não foi atingido
{
for (i = 0; i < 3; i++)
alunoLido.notas[i] += 3;
// Lacuna 3: Voltar o ponteiro para o início do registro lido
fseek(fp, -1L * ___3___, SEEK_CUR);
fwrite(&alunoLido, sizeof(Aluno), 1, fp);
}
fclose(fp);
}
int main()
{
Aluno listaAlunos[NUM_ALUNOS] = {{10001, "MaChao", 91, 92, 77},
{10002, "CaoKai", 75, 60, 88},
{10003, "LiSi", 85, 70, 78},
{10004, "FangFang", 90, 82, 87},
{10005, "ZhangSan", 95, 80, 88}},
alunosLidos[NUM_ALUNOS];
int i, j;
FILE *fp;
fp = fopen("student.dat", "wb");
if (fp == NULL) { perror("Erro ao criar student.dat"); return 1; }
fwrite(listaAlunos, sizeof(Aluno), NUM_ALUNOS, fp);
fclose(fp);
printf("\nDados originais:\n");
fp = fopen("student.dat", "rb");
if (fp == NULL) { perror("Erro ao abrir student.dat"); return 1; }
fread(alunosLidos, sizeof(Aluno), NUM_ALUNOS, fp);
fclose(fp);
for (j = 0; j < NUM_ALUNOS; j++)
{
printf("\nMatricula: %ld Nome: %-8s Notas: ", alunosLidos[j].matricula, alunosLidos[j].nome);
for (i = 0; i < 3; i++)
printf("%6.2f ", alunosLidos[j].notas[i]);
printf("\n");
}
atualizarNotasAluno("student.dat", 10003); // Modificar notas do aluno 10003
fp = fopen("student.dat", "rb");
if (fp == NULL) { perror("Erro ao reabrir student.dat"); return 1; }
fread(alunosLidos, sizeof(Aluno), NUM_ALUNOS, fp);
fclose(fp);
printf("\nDados apos modificacao:\n");
for (j = 0; j < NUM_ALUNOS; j++)
{
printf("\nMatricula: %ld Nome: %-8s Notas: ", alunosLidos[j].matricula, alunosLidos[j].nome);
for (i = 0; i < 3; i++)
printf("%6.2f ", alunosLidos[j].notas[i]);
printf("\n");
}
return 0;
}
2. Modificação de Código
A função calcularProdutoSerie é projetada para calcular o valor de S, que representa o produto da série: S = (2/1 * 2/3) * (4/3 * 4/5) * (6/5 * 6/7) * ... ou equivalentemente S = produto_{n=1 até k} ( (2n)^2 / ((2n-1)*(2n+1)) ).
Por exemplo, quando k=10, o valor da função deverá ser aproximadamente: 1.533852.
Corrija os erros nas partes indicadas da função calcularProdutoSerie para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.
#include <stdio.h>
// ERRO 1
void calcularProdutoSerie(int k)
{
int nIteracao;
float produtoTotal, num, den1, den2; // Variáveis float para precisão
nIteracao = 1;
produtoTotal = 1.0; // Inicializar com 1.0 para produto
while (nIteracao <= k)
{
num = 2.0 * nIteracao;
den1 = num - 1.0;
den2 = num + 1.0;
produtoTotal = produtoTotal * num * num / den1 / den2;
nIteracao++;
}
// ERRO 2
return produtoTotal
}
int main()
{
printf("%f\n", calcularProdutoSerie(10));
return 0;
}
3. Design de Função
Escreva a função somarSerie. Sua função é calcular a soma da seguinte série: S = 1/(1*2) + 1/(2*3) + 1/(3*4) + ... + 1/(n*(n+1)).
Por exemplo, quando n=10, o valor da função deverá ser aproximadamente 0.909091.
Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função somarSerie.
#include <stdio.h>
void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar
double somarSerie(int nTermos)
{
// SEU CÓDIGO AQUI
}
int main()
{
printf("%f\n", somarSerie(10));
funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
return 0;
}
void funcaoAuxiliarNaoModificar(void)
{
/* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
FILE *leituraArquivo, *escritaArquivo;
int i, n;
double resultadoSoma;
leituraArquivo = fopen("entrada.dat", "r");
escritaArquivo = fopen("saida.dat", "w");
if (!leituraArquivo || !escritaArquivo) {
perror("Erro ao abrir arquivos");
return;
}
for (i = 0; i < 10; i++)
{
if (fscanf(leituraArquivo, "%d", &n) != 1) break;
resultadoSoma = somarSerie(n);
fprintf(escritaArquivo, "%f\n", resultadoSoma);
}
fclose(leituraArquivo);
fclose(escritaArquivo);
}
Soluções para o Conjunto 80
1. Preenchimento de Código:
while (!feof(fp)) // ___1___
{
// ...
if (alunoLido.matricula == matriculaAlvo) // ___2___
break;
}
// ...
fseek(fp, -1L * sizeof(Aluno), SEEK_CUR); // ___3___
2. Modificação de Código:
double calcularProdutoSerie(int k) // ERRO 1 Corrigido: Tipo de retorno deve ser float ou double
{
// ...
return produtoTotal; // ERRO 2 Corrigido: Ponto e vírgula ausente
}
3. Design de Função:
double somarSerie(int nTermos)
{
double somaAcumulada = 0.0;
int i;
for (i = 1; i <= nTermos; i++)
{
somaAcumulada += 1.0 / ((double)i * (i + 1));
}
return somaAcumulada;
}