Use o botão abaixo para reportar erros ou dar sugestões.

Computação Científica - Um Livro Colaborativo

6.1 Passagem de vetores para função


Exemplo 6.1.1. Escreva um programa com uma função que recebe um vetor e devolve outro vetor contento mínimo, máximo e norma.

#include <stdio.h>  
#include <math.h>  
#define N 4  
void teste(double x[N], double saida[3])  
{  
  double max=x[0], norma=0, min=x[0];  
  int i;  
  for (i=0;i<N;i++)  
  {  
    norma+=x[i]*x[i];  
    if (max<x[i]) max=x[i];  
    if (min>x[i]) min=x[i];  
  }  
saida[0]=min;  
saida[1]=max;  
saida[2]=sqrt(norma);  
return;  
}  
 
 
main (void)  
{  
  double a[N]={1,-2,3,4},saida[3];  
  teste(a,saida);  
  printf("mínimo=%f, máximo=%f, norma=%f\n",saida[0],saida[1],saida[2]);  
}

Quando passamos um vetor de N posições para dentro de uma função, não estamos levando N valores, mas um único valor que é o endereço de memória dos vetores. Veja como chamamos a linha teste(a,saida);. Aqui a e saida são endereços de memória dos vetores. Naturalmente, a protótipo void teste(double x[N], double saida[3]) também funciona da forma void teste(double *x, double *saida), pois, de fato, estamos passando um ponteiro.

#include <stdio.h>  
#include <math.h>  
#define N 4  
void teste(double *x, double *saida)  
{  
  double max=*x, norma=0, min=*x;  
  int i;  
  for (i=0;i<N;i++)  
  {  
    norma+=*(x+i)**(x+i);  
    if (max<*(x+i)) max=*(x+i);  
    if (min>*(x+i)) min=*(x+i);  
  }  
*saida=min;  
saida++;  
*saida=max;  
saida++;  
*saida=sqrt(norma);  
return;  
}  
main (void)  
{  
  double a[N]={1,-2,3,4},saida[3];  
  teste(a,saida);  
  printf("mínimo=%f, máximo=%f, norma=%f\n",saida[0],saida[1],saida[2]);  
}

Uma versão mista do código também funciona.

Uma grande vantagem dos ponteiros é evitar a copia um vetor inteiro de uma posição da memória para outra, mas apenas trocar um ponteiro que aponta para o tal vetor. Isso reduz significantemente o custo computacional de um processo iterativo.

Exemplo 6.1.2. Vamos refazer o exemplo 4.3.1, que resolve um problema de contorno, melhorando a performance do processo iterativo com uso de ponteiros

#include <stdio.h>  
#include <math.h>  
 
#define N 101 /* dimensão do sistema*/  
 
double norma_2(double x[N])  
{  
  int i;  
  double norma2=x[0]*x[0]/(2*(N-1));  
  for (i=1;i<N-1;i++)  
  {  
    norma2+=x[i]*x[i]/(N-1);  
  }  
  norma2+=x[N-1]*x[N-1]/(2*(N-1));  
  return sqrt(norma2);  
}  
void Iteracao(double u_antigo[N],double u_atual[N],double matriz[N][N], double vetor[N])  
{  
  double aux;  
  int i,j;  
  for (i=0;i<N;i++)  
  {  
    aux=0;  
    for (j=0;j<i;j++)  
    aux+=matriz[i][j]*u_antigo[j];  
    for (j=i+1;j<N;j++)  
    aux+=matriz[i][j]*u_antigo[j];  
    u_atual[i]=(vetor[i]-aux)/matriz[i][i];  
  }  
}  
void Jacobi(double tolerancia,double u_atual[N],double vetor[N],double matriz[N][N],double malha[N])  
{  
  double u_antigo[N],dif[N];  
  int i,controle=3;  
  double *pu_antigo=u_antigo,*pu_atual=u_atual,*pswap;  
 
  //chute inicial  
  for (i=0;i<N;i++)u_antigo[i]=0;  
 
  //iteração  
  while (controle)  
  {  
    Iteracao(pu_antigo,pu_atual,matriz,vetor);  
    for (i=0;i<N;i++) dif[i]=u_atual[i]-u_antigo[i];  
    if (norma_2(dif)<tolerancia) controle--;  
    else controle=3;  
    pswap=pu_atual;  
    pu_atual=pu_antigo;  
    pu_antigo=pswap;  
  }  
  return;  
}  
 
double solucao_analitica(double x)  
{  
return -25.*(x-1.)*(x-1.)*(x-1.)*(x-1.)/3-25.*x/3+25./3.;  
}  
 
main (void)  
{  
  int i,j;  
  double tolerancia=1e-10,solucao[N];  
  double matriz[N][N];  
  double vetor[N],x[N];  
  //malha  
  double h=1./(N-1);  
  for (i=0;i<N;i++) x[i]=i*h;  
 
 
  //matriz e vetor  
  for (i=0;i<N;i++) for (j=0;j<N;j++) matriz[i][j]=0;  
  matriz[0][0]=1;  
  vetor[0]=0;  
  for (i=1;i<N-1;i++)  
  {  
    matriz[i][i]=-2;  
    matriz[i][i+1]=1;  
    matriz[i][i-1]=1;  
    vetor[i]=-100*h*h*(x[i]-1)*(x[i]-1);  
  }  
  matriz[N-1][N-1]=1;  
  vetor[N-1]=0;  
 
  Jacobi(tolerancia,solucao,vetor,matriz,x);  
  //erro médio  
  double erro=0;  
  for (i=0;i<N;i++) erro+=fabs(solucao[i]-solucao_analitica(x[i]));  
  erro/=N;  
  printf("erro médio = %f\n",erro);  
//  for (i=0;i<N;i++)     printf("u_%d=%f, u(x[%d]) = %f\n",i,solucao[i],i,solucao_analitica(x[i]));  
}

Creative Commons License Este texto é disponibilizado nos termos da licença Creative Commons Atribuição-CompartilhaIgual 3.0 Não Adaptada (CC-BY-SA 3.0). Página gerada em 19/8/2020 às 17:33:16.

Informe erros ou edite você mesmo!