Questão 02 - Fazer um programa para calcular o produto interno entre dois vetores, seguindo as orientações abaixo:
- Escrever uma função para ler um vetor cujo número de elementos é passado como argumento;
- No módulo principal, chamar essa função duas vezes gerando dois vetores independentes;
- Escrever outra função que receba como argumentos esses dois vetores e o número indicando a quantidade de elementos que eles têm. Essa função deve retornar o produto interno entre os vetores;
- Fazer uma terceira função para imprimir todos os dados do problema;
- Fazer o módulo principal.
Passo 1
O enunciado pede que você escreva um programa que calcule o produto interno (produto escalar) entre dois vetores, obedecendo a estas exigências:
- Escrever uma função para ler um vetor cujo número de elementos é passado como argumento.
- No módulo principal, chamar essa função duas vezes gerando dois vetores independentes.
- Escrever outra função que receba como argumentos esses dois vetores e o número indicando a quantidade de elementos que eles têm; essa função deve retornar o produto interno entre os vetores.
- Fazer uma terceira função para imprimir todos os dados do problema.
- Fazer o módulo principal (função main) que orquestre as chamadas e libere recursos.
Informações relevantes dadas:
- Deve haver três funções além do módulo principal: (i) função de leitura de vetor, (ii) função que calcula o produto interno, (iii) função que imprime os dados.
- Os dois vetores devem ser independentes (ou seja, memória separada).
- O número de elementos dos vetores é passado como argumento às funções.
Passo 2
O que é o produto interno (produto escalar) para vetores? Vou explicar a fórmula para você entender direitinho.
Seja um vetor
com
elementos e outro vetor
com
elementos. O produto interno entre
e
é definido por
Aqui:
-
é a quantidade de componentes de cada vetor. -
é o -ésimo elemento de . -
é o -ésimo elemento de . - O somatório soma os produtos correspondentes componente a componente.
Exemplo pequeno para fixar: com
,
e
,
Passo 3
Qual linguagem usar e por quê? Vou usar a linguagem C, porque:
- O enunciado fala em “módulo principal” e em passar o número de elementos para funções, o que é bem natural em C.
- Em provas de exatas, é muito comum pedirem implementação em C para manipular vetores, malloc, ponteiros e funções — então praticar em C ajuda mais.
- A implementação em C permite mostrar claramente como garantir que os vetores sejam independentes (alocação dinâmica com malloc).
Se você preferir outra linguagem (por exemplo Python), depois posso adaptar; por enquanto, seguimos com C.
Passo 4
Projeto das funções (propostas de assinaturas):
- Função que lê um vetor:
- Protótipo:
- O que faz: aloca memória para
elementos do tipo , lê valores do teclado e retorna o ponteiro para o vetor. - Por que retornar um ponteiro: em C não podemos retornar um array local; precisamos alocar dinamicamente para que o vetor exista depois que a função acabar.
- Protótipo:
- Função que calcula o produto interno:
- Protótipo:
- O que faz: percorre de
até , acumula numa soma e retorna essa soma. - Use
para indicar que a função não modifica os vetores.
- Protótipo:
- Função que imprime tudo:
- Protótipo:
- O que faz: imprime os vetores
e (elemento a elemento) e imprime o valor do produto interno .
- Protótipo:
- Função principal:
- Pede ao usuário o número de elementos
, valida . - Chama
duas vezes para obter e . - Chama
e guarda o resultado. - Chama
. - Libera a memória com
.
- Pede ao usuário o número de elementos
Passo 5
Detalhes didáticos sobre leitura e independência dos vetores:
- Em C, ao fazer
você obtém um bloco de memória capaz de armazenar números em ponto flutuante. Para garantir que os vetores sejam independentes, você deve chamar duas vezes — uma para e outra para . - Se você fizesse algo como retornar um array local (declarado como
dentro da função), esse array deixa de existir quando a função retorna — resultado: comportamento indefinido. Por isso usamos . - Sempre cheque se
retornou ; se for ocorreu falha na alocação.
Como ler os valores sem complicação:
- Use
para ler um número do tipo . - Num loop para
de a , leia .
Passo 6
Como implementar a função do produto interno passo a passo:
- Inicialize uma variável
. - Faça um loop
. - Em cada iteração, calcule
. - Ao final, retorne
.
Por que esse método é bom para prova?
- É direto, usa apenas aritmética básica e um laço. É muito eficiente: complexidade
, ou seja, escala linearmente com . - Não depende de bibliotecas especiais.
Passo 7
O que a função de impressão deve mostrar (sugestão didática):
- Imprimir o vetor
no formato: . - Imprimir o vetor
no mesmo formato. - Imprimir o produto interno com uma mensagem clara, por exemplo: “Produto interno = …”.
- Use formatação com
, por exemplo para mostrar com 6 casas decimais (ou escolha outra precisão).
Passo 8
Tratamento de entradas inválidas e casos especiais:
- Se
, informe erro e saia. - Cuidado com overflow: se os números forem muito grandes, o
pode ultrapassar; em provas geralmente trabalham com valores moderados. - Caso
, o produto interno é definido por convenção como . Você pode permitir e retornar ou exigir . Vou exigir para simplificar e validar entrada.
Passo 9
Exemplo de execução (fluxo que sua solução deve suportar):
- Usuário entra com
. - Lê vetor
: . - Lê vetor
: . - Programa calcula e imprime os vetores e o produto interno
.
Passo 10
Dicas rápidas para a prova:
- Escreva primeiro as assinaturas das funções, depois implemente uma por uma e teste.
- Teste com vetores simples (ex.: todos zeros, vetor igual aos dois vetores iguais).
- Lembre de liberar a memória com
para evitar vazamento. - Comente brevemente cada função para o corretor entender sua lógica.
- Mantenha código legível e trate entradas inválidas.
Resposta
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
double *read_vector(int n) {
double *v = (double *)malloc(n * sizeof(double));
if (v == NULL) {
fprintf(stderr, “Erro: falha na alocacao de memoria.\n”);
exit(EXIT_FAILURE);
}
for (int i = 0; i < n; ++i) {
printf(“Digite o elemento %d: “, i);
if (scanf(”%lf”, &v[i]) != 1) {
fprintf(stderr, “Erro: entrada invalida.\n”);
free(v);
exit(EXIT_FAILURE);
}
}
return v;
}
double *v = (double *)malloc(n * sizeof(double));
if (v == NULL) {
fprintf(stderr, “Erro: falha na alocacao de memoria.\n”);
exit(EXIT_FAILURE);
}
for (int i = 0; i < n; ++i) {
printf(“Digite o elemento %d: “, i);
if (scanf(”%lf”, &v[i]) != 1) {
fprintf(stderr, “Erro: entrada invalida.\n”);
free(v);
exit(EXIT_FAILURE);
}
}
return v;
}
double dot_product(const double *a, const double *b, int n) {
double sum = 0.0;
for (int i = 0; i < n; ++i) {
sum += a[i] * b[i];
}
return sum;
}
double sum = 0.0;
for (int i = 0; i < n; ++i) {
sum += a[i] * b[i];
}
return sum;
}
void print_all(const double *a, const double *b, int n, double result) {
printf(“Vetor a = [”);
for (int i = 0; i < n; ++i) {
printf("%.6f", a[i]);
if (i < n - 1) printf(", “);
}
printf(”]\n");
printf(“Vetor a = [”);
for (int i = 0; i < n; ++i) {
printf("%.6f", a[i]);
if (i < n - 1) printf(", “);
}
printf(”]\n");
printf("Vetor b = [");
for (int i = 0; i < n; ++i) {
printf("%.6f", b[i]);
if (i < n - 1) printf(", ");
}
printf("]\n");
printf("Produto interno = %.6f\n", result);
}
int main(void) {
int n;
printf(“Digite o numero de elementos do vetor: “);
if (scanf(”%d”, &n) != 1) {
fprintf(stderr, “Erro: entrada invalida para n.\n”);
return EXIT_FAILURE;
}
if (n <= 0) {
fprintf(stderr, “Erro: n deve ser > 0.\n”);
return EXIT_FAILURE;
}
int n;
printf(“Digite o numero de elementos do vetor: “);
if (scanf(”%d”, &n) != 1) {
fprintf(stderr, “Erro: entrada invalida para n.\n”);
return EXIT_FAILURE;
}
if (n <= 0) {
fprintf(stderr, “Erro: n deve ser > 0.\n”);
return EXIT_FAILURE;
}
printf("Leitura do vetor a:\n");
double *a = read_vector(n);
printf("Leitura do vetor b:\n");
double *b = read_vector(n);
double result = dot_product(a, b, n);
print_all(a, b, n, result);
free(a);
free(b);
return EXIT_SUCCESS;
}