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 u com n elementos e outro vetor v com n elementos. O produto interno entre u e v é definido por
\langle u, v \rangle = \sum_{i=0}^{n-1} u_i \, v_i.
Aqui:
  • n é a quantidade de componentes de cada vetor.
  • u_i é o i-ésimo elemento de u.
  • v_i é o i-ésimo elemento de v.
  • O somatório soma os produtos correspondentes componente a componente.
Exemplo pequeno para fixar: com n=3, u=(1,2,3) e v=(4,5,6),
\langle u,v \rangle = 1\cdot4 + 2\cdot5 + 3\cdot6 = 4 + 10 + 18 = 32.

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: `double *read_vector(int n)`
    • O que faz: aloca memória para n elementos do tipo `double`, lê n 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.
  • Função que calcula o produto interno:
    • Protótipo: `double dot_product(const double *a, const double *b, int n)`
    • O que faz: percorre de i=0 até i=n-1, acumula `a[i] * b[i]` numa soma e retorna essa soma.
    • Use `const` para indicar que a função não modifica os vetores.
  • Função que imprime tudo:
    • Protótipo: `void print_all(const double *a, const double *b, int n, double result)`
    • O que faz: imprime os vetores a e b (elemento a elemento) e imprime o valor do produto interno `result`.
  • Função principal:
    • Pede ao usuário o número de elementos n, valida n>0.
    • Chama `read_vector(n)` duas vezes para obter `a` e `b`.
    • Chama `dot_product(a,b,n)` e guarda o resultado.
    • Chama `print_all(a,b,n,result)`.
    • Libera a memória com `free`.

Passo 5

Detalhes didáticos sobre leitura e independência dos vetores:
  • Em C, ao fazer `double *a = malloc(n * sizeof(double));` você obtém um bloco de memória capaz de armazenar n números em ponto flutuante. Para garantir que os vetores sejam independentes, você deve chamar `malloc` duas vezes — uma para `a` e outra para `b`.
  • Se você fizesse algo como retornar um array local (declarado como `double arr[n];` dentro da função), esse array deixa de existir quando a função retorna — resultado: comportamento indefinido. Por isso usamos `malloc`.
  • Sempre cheque se `malloc` retornou `NULL`; se for `NULL` ocorreu falha na alocação.
Como ler os valores sem complicação:
  • Use `scanf("%lf", &x)` para ler um número do tipo `double`.
  • Num loop para `i` de 0 a n-1, leia `a[i]`.

Passo 6

Como implementar a função do produto interno passo a passo:
  1. Inicialize uma variável `double sum = 0.0;`.
  2. Faça um loop `for (int i = 0; i < n; ++i)`.
  3. Em cada iteração, calcule `sum += a[i] * b[i];`.
  4. Ao final, retorne `sum`.
Por que esse método é bom para prova?
  • É direto, usa apenas aritmética básica e um laço. É muito eficiente: complexidade \mathcal{O}(n), ou seja, escala linearmente com n.
  • 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 a no formato: [a_0, a_1, \dots, a_{n-1}].
  • Imprimir o vetor b no mesmo formato.
  • Imprimir o produto interno com uma mensagem clara, por exemplo: “Produto interno = …”.
  • Use formatação com `printf`, por exemplo `printf("%.6f", a[i])` para mostrar com 6 casas decimais (ou escolha outra precisão).

Passo 8

Tratamento de entradas inválidas e casos especiais:
  • Se n \le 0, informe erro e saia.
  • Cuidado com overflow: se os números forem muito grandes, o `double` pode ultrapassar; em provas geralmente trabalham com valores moderados.
  • Caso n = 0, o produto interno é definido por convenção como 0. Você pode permitir n=0 e retornar 0.0 ou exigir n>0. Vou exigir n>0 para simplificar e validar entrada.

Passo 9

Exemplo de execução (fluxo que sua solução deve suportar):
  • Usuário entra com n=3.
  • Lê vetor a: 1 2 3.
  • Lê vetor b: 4 5 6.
  • Programa calcula e imprime os vetores e o produto interno 32.

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 `free` 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>
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 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;
}
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 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;
}
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;
}

Exercícios relacionados