Ir ao conteúdo
  • Cadastre-se

C Exercicio com funçoes e vetores


Giovanaf

Posts recomendados

Boa noite, estou empacada em um problema que envolve funções. não consigo somar os valores do vetor para fazer a média e nem ao menos tentei por o valor mínimo e máximo. Talvez eu não tenha fixado direito a passagem passagem por referência, espero que me ajudem com o código.

 

Enunciado: Crie uma função que receba um vetor de 100 valores tipo int como parâmetro (valores devem
ser gerados aleatoriamente pelo programa principal) e retorne a média, valor máximo e o valor mínimo.

 

#include <stdio.h>
#include <time.h>
void vetor_aleatorios (int vet[], int n){
	 srand (time(NULL)); 
	 
     for ( int i = 0; i < n; i++){
		 printf ("%d ", rand () %10);
	 }
 }


int main () {

	int vetor [100];
	vetor_aleatorios (vetor, 100);
	
	
	return 0;
}

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Giovanaf Olá. Em questão como essa sugiro procurar resolver o problema por partes.

Vamos ver o q diz o enunciado do exercício:

1 hora atrás, Giovanaf disse:

um vetor de 100 valores tipo int

Isso você fez da maneira correta.

1 hora atrás, Giovanaf disse:

(valores devem
ser gerados aleatoriamente pelo programa principal)

Qual é o programa principal? 

É o main. (main traduzindo para o português significa principal)

Essa parte vou passar abaixo.

1 hora atrás, Giovanaf disse:

Crie uma função que receba um vetor de 100 valores

A função na parte dos parâmetros você fez da maneira correta também, mas vale lembra que nela serão feito os cálculos solicitados

Logo, a parte q vou passar seria a parte de gerar os 100 números aleatórios, para você ter um ponto d partida:

#include <stdio.h>
#include <time.h>     // para a função time()
#include <stdlib.h>   // para as funções rand() e srand()

void calculos(int vet[], int n) {

    int menor, maior; // menor e maior valor
    float media = 0.0, soma = 0.0; // media e soma do tipo float já inicializando as variáveis

    // cálculos solicitados
}

int main() {

    int vetor[100];
    int i;

    srand(time(NULL));

    for (i = 0; i < 100; i++) {
        vetor[i] = rand() % 100; // aqui coloquei o valor 100 para gerar números do 0 ao 99, pode ser o valor q você quiser. 
    }

    calculos(vetor, 100); // aqui estou fazendo a chamada a função, já passando o vetor e o tamanho do mesmo 

    return 0;
}

Procure pelo menos tentar fazer o exercício.

Vou dar algumas dicas:

Para somar os valores na função você pode usar um for tal com esse q passei.

Para encontrar o menor e maior valor a dica que eu daria seria de TENTAR fazer. Não está conseguido? Aí sim pergunte!

Experimenta ver se consegue avançar no exercício com essa porção do código q passei.

Se surgir dúvidas fique a vontade para perguntar. Mas novamente vou frisar que é importante q você tente fazer os cálculos!

Se deu p ajudar maravilha!

Obs: Não vou passar o código pronto pois vejo q isso não te ajudaria em nada. Na verdade iria só atrapalhar no seu processo de aprendizagem

Link para o comentário
Compartilhar em outros sites

@giu_d Oi, obrigada pela ajuda.

Consegui fazer a média, mas ainda não o valor maior e menor.

Pensei em fazer Bubblesort e depois copiar a primeira e ultima posição do vetor, mas não sei se faço uma função isolada que efetua o bubblesort ou ponho junto com a função vetor_aleatorios. (tentei os dois jeitos e me perdi com os dois)

O código até agora

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void bubble (int vet1[], int n, int l){
int aux;
for (int k=0; k<n; k++){
    for ( l=k+1; l<n; l++){
        if (vet1[l]>vet1[l+1]){
            aux = vet1[l];
            vet1[l] = vet1[l+1];
            vet1[l+1] = aux;

        }
    }
}

}
void vetor_aleatorios (int vet[], int n){
	 srand (time(NULL));
int a, soma =0, vec[100];
float media;


     for ( int i = 0; i < n; i++){
            a = rand () %10;
     soma = soma + a;
     printf ("%d ", a);

	 }
	 printf ("\nSOMA: %d", soma);
	 media = soma/100.0;
	 printf ("\nMEDIA: %.4f", media);
	 bubble (vec[], 100, a);
 }



int main () {

	int vetor [100];
	vetor_aleatorios (vetor, 100);



	return 0;
}

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Giovanaf Maravilha. Agora tentou fazer. Nesse caso dá para ajudar mais.

A lógica que você usou para fazer o soma é essa mesmo, mas ao invés de usar  uma variável faça uso dos valores aleatórios incluídos no vetor.

Para preencher o vetor com os números aleatórios ( lembre que o enunciado do exercício pede isso):

for (i = 0; i < 100; i++) {
    vetor[i] = rand() % 100; // aqui cada posição do vetor recebe um número. Logo, esses números são "armazenados" no vetor
}

Procure entender essa parte do código acima. Veja o comentário que coloquei.

Seria isso:

vetor[0] = numero, vetor[1]  =  numero, vetor[2] = numero .... vetor[99] = numero.

O for começa do 0 e vai até o 99. Esses valores passam a ser as posições do vetor (índices). 0, 1, 2, 3, 4, ... 99

vetor[ i ] equivale a vetor [ 0 ]. Depois vetor[ 1 ], vetor[ 2 ] etc...

Agora que o vetor está armazenando os números aleatórios, você pode fazer a soma usando o vetor mesmo, que é o q o exercício pede. Seria isso:

for (i = 0; i < 100; i++) {
    soma = soma + vetor[i]; // perceba que estou usando o vetor na soma, que agora está populado com os números q precisamos
}

Vê se ajuda um pouco mais. Se surgir dúvidas pergunte mesmo. O importante aqui é entender o que está sendo feito

 

Seria até adequado agora esquecer a questão da função e procure fazer o código no main. Depois resolva a questão da função

Vamos lá:

Para procurar o menor e o maior valor do vetor vou passar o código, mas seria importante você entender o q está sendo feito.

A questão é q para mim aprender a respeito de como fazer esse cálculo, tive q olhar um código onde era feito isso.

Depois, a medida que fui praticando, ficou fácil entender

maior = vetor[0]; // o valor que está no índice 0 é atribuído a variável, para abaixo poderem ser feitas as comparações
menor = vetor[0];

for (i = 0; i < 100; i++) {
    if (vetor[i] > maior) { // aqui todas as posições do vetor são comparadas com a variável maior
        maior = vetor[i];
    }
    if (vetor[i] < menor) {
        menor = vetor[i];
    }
}

Agora já tem quase o código todo. Resta ajustar para q fique de acordo com o enunciado.

Você, pelo algoritmo q usou (bubble), demonstra já ter uma boa clareza do q está fazendo. Só que para a caso de calcular o menor e maior valor, é feito dessa forma acima.

Repito: O importante aqui é entender o que está sendo feito. Pode parecer estranho ou sem sentido até, a curto prazo, mas a medida que você for praticando as coisas vão "clareando"  e cada vez fica mais fácil resolver os desafios que surgem a nossa frente. Pode ter certeza disso! 

Fique a vontade para perguntar no caso de não ter entendido o que foi feito

Link para o comentário
Compartilhar em outros sites

Obs: Se alguém tiver alguma sugestão para ajudar a autora do tópico fique a vontade p postar

adicionado 30 minutos depois

@Giovanaf Olá. Apenas para q fique mais claro p você q os valores aleatórios ficam realmente armazenados no vetor após a operação abaixo, basta imprimir esses valores:

srand(time(NULL));

for (i = 0; i < 100; i++) {
    vetor[i] = rand() % 100;
    printf("Posicao [%d] = %d\n", i, vetor[i]);
}

E, para verificar o maior e menor número q está no vetor, o código está postado acima.

Você tentou procurar o maior e menor valor usando o bubble sort. Maravilha! É um passo bastante grande q você deu.

Isso demonstra q você tem atitude, e isso vale muito!

E outra: "Só erra quem faz". Lembre disso!

E o código p procurar a maior e menor valor no vetor seria esse:

maior = vetor[0]; 
menor = vetor[0];

for (i = 0; i < 100; i++) {
    if (vetor[i] > maior) {
        maior = vetor[i];
    }
    if (vetor[i] < menor) {
        menor = vetor[i];
    }
}

Caso ficou muito difícil p entender o q está sendo feito, recomendo fortemente dar uma olhada no vídeo do link q vou postar.

Nesse vídeo é mostrado um exemplo prático do Teste de Mesa. Usando esse recurso vai ficar fácil entender esse código. Tanto esse como qualquer outro q você queira entender. Segue o link:

http://www.softblue.com.br/blog/como-fazer-teste-de-mesa

 

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Olá.

 

@Giovanaf, a dica simples: se atente ao enunciado. Tente fazer o que ele pede.

 

 

1#

11 horas atrás, Giovanaf disse:

Enunciado: [1] Crie uma função que receba um vetor de 100 valores tipo int como parâmetro ([2] valores devem
ser gerados aleatoriamente pelo programa principal) e [3] retorne a média, valor máximo e o valor mínimo.

 

Dividi o enunciado em 3 partes. Com já sabido, o [2] deve ser implementado antes do [1]. E o [3] é apenas a característica/objetivo do [1].

 

 

 

2#

Sobre o [2] o @giu_d já sugeriu como poderia ficar:

10 horas atrás, giu_d disse:
11 horas atrás, Giovanaf disse:

(valores devem
ser gerados aleatoriamente pelo programa principal)

Qual é o programa principal? 

É o main. (main traduzindo para o português significa principal)

 

Ou seja, a parte de "gerar aleatoriamente", teoricamente, deveria ficar no main. Não deveria usar um método para isso. Pelo menos é isso que indica o enunciado... de qualquer sorte, a sugestão é tentar entender e seguir as sugestões de implementação, caso "discorde", explanar sobre a divergência... entende? Todos os envolvidos (professor/facilitador, aluno, colaboradores etc) devem ficar alinhados no que precisa ser feito. Quando ocorrem divergências de entendimento, é preciso antes alinhar! (ou fazer de forma divergente, mas justificando o não segmento da orientação).

 

Então, de certo modo talvez possa ser feito a geração do vetor por método e como quer fazer assim, para efeitos práticos, vamos seguir esse fluxo... Essa questão pode ser discutida posteriormente.

 

Apenas sugiro que não misture as coisas... ou seja, a parte de gerar o número [2] é uma, e a parte [1] (que inclui o [3]) é outra. Nisso não tem o que discutir, pois o enunciado é bem claro em relação às característica do [1]... (ou não, vá saber! rs)

 

Logo, a geração do números, poderia ficar com algo assim:

void gera_vetor(int vet[], int n) {
    int i;
    
    srand(time(NULL));
    for (i=0; i<n; i++) {
        vet[i]=rand()%100;
    }
}

obs.: devido as característica s do C (que eu não domino, mas tenho noção), esse vetor recebido por parâmetro está como se fosse por referência, ou seja, o que é alterado dentro do método, é também alterado no vetor original do main.

 

 

 

3#

Sobre o [1]. Ele pede «receba um vetor» e «retorne a média, valor máximo e o valor mínimo». Correto?

 

Mas perceba que no seu último código você está efetuando cálculos e imprimindo dentro de um próprio método... entretanto, como já enfatizado, devemos sempre* fazer o que o foi pedido no enunciado, que diz: RETORNE.

 

Ai entra a questão: o que é "retornar" e como posso fazer isso?

 

Supostamente retornar significa devolver para que invocou o método, ou seja, o programa principal irá receber a resposta retornada pelo método. Existem pelo menos 3 formas:

  1. variável global; (não desejável)
  2. por parâmetros do tipo referência*; (usando variáveis do parâmetro para receber os dados)
  3. através do retorno do método, ou seja, utilizando o return. (como o return só entrega uma coisa, teria que pensar em como devolver 3... poderia por exemplo utilizando struct ou "concatenando os dados e separando depois" etc).

Então... dessas 3, a mais simples para o contexto seria pelo 2. Ai seria algo como:

 

Pegando o gancho do código do @giu_d:

11 horas atrás, giu_d disse:

void calculos(int vet[], int n) {

    int menor, maior; // menor e maior valor
    float media = 0.0, soma = 0.0; // media e soma do tipo float já inicializando as variáveis

    // cálculos solicitados
}

 

Poderia ficar:

void calculos(int vet[], int n, int *maior, int *menor, int *media) {
    float soma = 0.0; 

    // cálculos solicitados

}

obs. 2: o * no parâmetro é para indicar que vai usar ponteiros... fazer que funcione como "parâmetro por referência" (persistir as alterações).

 

Entende? vet[] e n são os dados do vetor.. as outras variáveis são usadas para receber dados que precisa... Para exemplificar o funcionamento, veja:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

void bubble (int vet1[], int n, int l) {
    int aux;
    
    int k;
    for (k=0; k<n; k++) {
        for ( l=k+1; l<n; l++) {
            if (vet1[l]>vet1[l+1]){
                aux = vet1[l];
                vet1[l] = vet1[l+1];
                vet1[l+1] = aux;            
            }
        }
    }
}

void gera_vetor(int vet[], int n) {
    int i;
    
    srand(time(NULL));
    for (i=0; i<n; i++) {
        vet[i]=rand()%100;
    }
}


void calculos(int vet[], int n, int *media) { //deixei só a média, para facilitar o entendimento
    float soma = 0.0; 
    
    *media = 1234; //aqui um valor teste para ver se está retornando para o main()
    

}

int main () {
    int vet[100]; //vetor que conterá os númneros
    int media=0;
    int i;
    
    gera_vetor(vet,100); //gerar números aleatórios para cada posição do vetor
    calculos(vet,100,&media); //a variável meda está ai para receber uma resposta1
    
    printf ("\n\n%d ", media); //imprime a média que recebeu do métido calculos()
    
    return 0;
}

 

 

 

4#

Tente implementar. Por enquanto faça apenas o seguinte:

- gere os dados do vetor com o gera_vetor();

- em calculos() calcule apenas a média, retornando o valor em media;

- e no programa principal exiba o vetor e depois exiba a média dele.

- posta o código aqui.. depois vemos a parte da maior e menor (que será basicamente mesma coisa)

 

 

***

 

No aguardo.

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

:oops:Devo confessar q não considerei a lógica usada pela @Giovanaf na parte de usar o bubble sort para encontrar o maior e menor valor. Putz!!! Que vergonha. Sem mais comentários....

Daria para simplificar o código dessa forma:

void bubble (int vet[], int n, int l) {

    int aux;

    int k;
    for (k = 0; k < n; k++) {
        for (l = k + 1; l < n; l++) {
            if (vet[l] < vet[k]){
                aux = vet[l];
                vet[l] = vet[k];
                vet[k] = aux;
            }
        }
    }

    printf("Menor valor: %d\n", vet[0]);
    printf("Maior valor: %d\n", vet[99]);
}

Faz sentido e muito sentido essa lógica!

adicionado 23 minutos depois

Bubble sort

O q é?

Para q serve?

Onde mora?

Hoje... no globo repórter

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

@giu_d, sobre:

27 minutos atrás, giu_d disse:

:oops:Devo confessar q não considerei a lógica usada pela @Giovanaf na parte de usar o bubble sort para encontrar o maior e menor valor. Putz!!! Que vergonha. Sem mais comentários....

Daria para simplificar o código dessa forma:


void bubble (int vet[], int n, int l) {

    int aux;

    int k;
    for (k = 0; k < n; k++) {
        for (l = k + 1; l < n; l++) {
            if (vet[l] < vet[k]){
                aux = vet[l];
                vet[l] = vet[k];
                vet[k] = aux;
            }
        }
    }

    printf("Menor valor: %d\n", vet[0]);
    printf("Maior valor: %d\n", vet[99]);
}

Faz sentido e muito sentido essa lógica!

 

2 pontos:

- não tem porque a variável l vir por parâmetro, bastaria declarar junto do k.

- o "bubble" (Bubble Sort) é apenas relacionado a ordenação... "maior" e "menor" é outra. Não poderia ficar misturado, ou seja, o nome do método poderia se "maior_menor()" ou algo do tipo... este último poderia ter o Bubble Sort incorporado, mas o contrário não (Bubble Sort ter incorporado o maior e menor). Entende?

 

Outro ponto é que essa questão do maior e menor entra no item [3] da minha postagem anterior, ou seja, estaria "imprimindo" a resposta, em vez de "retornar".

adicionado 15 minutos depois

PS: @giu_d, outra coisa, perceba que você alterou a estrutura do método de ordenação... o que tecnicamente deixou de de ser Bubble Sort.... Já que uma das principais características do Bubble é comparar com o adjacente.. A estrutura foca na flutuação como uma bolha. O código da  @Giovanaf segue o padrão, veja:

 

11 horas atrás, Giovanaf disse:

if (vet1[l]>vet1[l+1]){ //vai comparação a posição com seu adjacente [OK]

 

 

No seu está:

37 minutos atrás, giu_d disse:

if (vet[l] < vet[k]){ //compara posição fixa com as posteriores a ela [Não é característica do Bubble Sort]

 

Pode aparentar ser parecido e ambos são eficazes, mas são lógicas distintas. A "bolha" deixa de existir... logo, não faz sentido chamar de Bubble. (pelo menos para mim)

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Bem dá hora! Só discordo do post #3: Não existe um porquê de modificar todo índice do vetor (pseudoaleatório) em busca de 3 valores que são (preferencialmente) localizados na busca indexada (escaneados).

 

Daí ressalto com isso a proposta de solução no post #4 onde a busca e feita pelos índices; por dois motivos; 

1- ordenação é apenas nos casos em que isso é solicitado ou de certa forma representa uma otimização para os processos posteriores: e não é este o caso, pelo contrário, o número de calculos para ordenação do vetor de elementos aleatórios é bem mais que os cálculos para busca dois ou três valores nele. Para processador, é um desperdício se comparada as soluções; post #3 e #4.

 

Dois- algoritmos de ordenação são famosas medidas prontas: complexos de + para um problema que solicita exclusivamente três dados e nada mais, inclusive esse dados bem sugestivos porque estão relacionados mesmo processo: escanear, e não ordenar valores -- escanear é; quando o programador percorre todos os valores ou índices de uma estrutura (bem mais o perfil do problema) em busca de alguma coisa. Nesse situação específica a coisa é: o maior, menor e a média dos valores.

E ordenação não é escanear? sim, e mais que isso; é escanear e modificar o objeto escaneando, daí o motivo dos desperdício.

 

 

 

Citação

Crie uma função que receba um vetor de 100 valores tipo int como parâmetro (valores devem ser gerados aleatoriamente pelo programa principal) e retorne a média, valor máximo e o valor mínimo.

Minha sugestão é que a função realmente nesse caso faça tudo, exceto a aparte da que cabe a principal.

 

Inclusive retorne um vetor dados.

 

Ps.: retorno pelo return rdados;

 

ATUALIZADO
float relatorio(int tamanho_lista, int lista[], int min_max[]);
numero * relatorio(int tamanho_lista, int lista[]);

numero ~ não é um estrutura e sim uma união (union).

Dúvidas, críticas ou sugestões?

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Simon Viegas  Diferente do que você propôs, fiz apenas uma função fora da main. Acredito que não seja problema.

Também foi solicitado o cálculo do desvio padrão das 100 posições.

 

@giu_d  Acredito que eu tenha conseguido, mais uma vez obrigada pela ajuda.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

void aleatorio (int v[], float n){
	int soma, aux=0;
	float desvio;
	
	srand (time(NULL));
	for (int i=0; i<n; i++){
		v[i]= rand () %50 +5;
		soma = soma + v[i];
		//printf ("%d ", v[i]);
     }
     
     float media;
     media = soma/n;
     //printf ("\nSoma: %d\n", soma);
     printf ("Media: %.4f\n", media);
     
     for (int k=0; k<n; k++){
		 aux = aux + (pow((v[k]-media),2));
	 }
	 
	 desvio = aux / 3;
	 desvio = sqrt (desvio);
	 printf ("Desvio: %.4f\n", desvio);
     
     int maior=v[0], menor=v[0];
     for (int j=0; j<n; j++){
          if (v[j]>maior){
			  maior = v [j];
		  }
		  if (v[j]<menor){
			  menor = v [j];
		  }
	
      } 
        printf ("Maior: %d\n", maior);
      	printf ("Menor: %d\n", menor);

}

int main(int argc, char **argv)
{
	int vet [100];
	aleatorio (vet, 100);
	return 0;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@AnsiC

Crie uma função que receba um vetorde 100 valores tipo int como parâmetro (valores devem ser gerados aleatoriamente

pelo programa principal) e retorne a média, valor máximo, valor mínimo e desvio padrão dos valores no vetor.

Média e desvio padrão devem ter 4 casas decimais.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Nesta caso mudou tudo, dividindo a tarefa 4 que não fazem parte da principal vai ajudar bastante:

  1. Um função para mínimo;
  2. Um função para máximo;
  3. Um função para média;
  4. Um função para desvio.

 

PS: Só para que o código fique mais legível porque para mim ficou "complicado".

Link para o comentário
Compartilhar em outros sites

Fiz um exemplo para ser estudado.

#include <stdio.h>  /*  ~incluir: printf */
#include <stdlib.h>  /* ~incluir: rand; srand */
#include <time.h>  /*   ~incluir: time */
#include <math.h>  /*   ~incluir: sqrt */

#define MAXVALOR  100
#define VETSIZ  100

/** typedef ~ real
 *    cria um novo tipo que permite escolher os tipos: float ou int para dados. 
 */
typedef union {
        float rfloat;
        int rint;
} real;

/** função maximo ~ retorna o maior valor */
int maximo (int tamanho, int vetor[]){
  int val = vetor[0];
    for (int i = 1; i  <  tamanho; i += 1){
        if (val  <  vetor[i]){
              val = vetor[i];
        }
    }
  return val;
}

/** função maximo ~ retorna o menor valor */
int minimo (int tamanho, int vetor[]){
  int val = vetor[0];
    for (int i = 1; i  <  tamanho; i += 1){
        if (val  >  vetor[i]){
              val = vetor[i];
        }
    }
  return val;
}

/** função media ~ retorna o media */
float media (int tamanho, int vetor[]){
  float soma = vetor[0];
    for (int i = 1; i  <  tamanho; i += 1){
        soma += vetor[i];
    }
  return soma/tamanho;
}

/** função desvio ~ retorna o desvio */
float desvio (int tamanho, int vetor[], float media){
  float var = 0;
  int dif = 0;
    for (int i = 0; i < tamanho; i += 1){
          dif = vetor[i] - media;
          var += (dif*dif);
    }
  return sqrt (var);
}

/** funcao relatorio ~ principal da tarefa  */
real * relatorio (int tamanho, int vetor[]){
  static real rdados[4];
    rdados[0].rint = minimo (tamanho, vetor);
    rdados[1].rint = maximo (tamanho, vetor);
    rdados[2].rfloat = media (tamanho, vetor);
    rdados[3].rfloat = desvio (tamanho, vetor, rdados[2].rfloat);
  return rdados;
}

/** funcao main ~ principal do programa  */
int main (void){
  int vetor[VETSIZ] = {0};
  real * dados;
    srand (time(0));
    printf ("Vetor Randomico\n");
    for (int i = 0; i < VETSIZ; i += 1){
          vetor[i] = rand()%MAXVALOR;
          printf ("%2d", vetor[i]);
          if ((i + 1)%10 == 0){
                printf ("\n");
          } else {
                printf (" ");
          }
    }
    printf ("\n");
    dados = relatorio (VETSIZ, vetor);
    printf ("#Relatorio\n");
    printf ("1. Minimo: %d\n", dados[0].rint);
    printf ("2. Maximo: %d\n", dados[1].rint);
    printf ("3. Media:  %.4f\n", dados[2].rfloat);
    printf ("4. Desvio: %.4f\n", dados[3].rfloat);
    printf ("\n");
  return 0;
}

Dúvidas, sugestões ?

Ps.: Achei difícil para novato entender! 

 

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@AnsiC Gostei da função relatorio, onde você cria um vetor, popula o mesmo com os resultados q são solicitados no exercício e retorna esse vetor sem precisar usar alocação dinâmica d memória p isso. 

Esse recurso inda estou começando a estudar, mas usando uma union é algo novo p mim. Até então estudei a respeito disso usando uma struct :)

Link para o comentário
Compartilhar em outros sites

@AnsiC Maravilha! E já tenho uma pergunta: Por que na função relatorio mesmo mudando o tamanho do vetor rdados de 4 p 1 o código da função funciona do mesmo modo e tbém o restante do código?

Por ser uma union já vi q não é, pois o mesmo ocorre com uma struct

Link para o comentário
Compartilhar em outros sites

Isso é um erro lógico: pode ou não pode resultar em erros fatais: tipos de erros que finalizam os programas, e fazer ou não o inesperado. Quando atribui em vetores um tamanho sempre podemos ir além dele, pois a linguagem permite isso, entretanto, se acessar locais da memória já reservados vai resultar em erro em tempo de execução termina o programa e sair; esse é um erro bem comum no C. Contudo, existe um mínimo padrão de memória reservada para todo programa, quem reserva essa memória é o sistema operacional, pois bem é essa mídia chamada de Stack (pilha): ambiente na memória onde reside as variáveis temporárias, funções acionadas etc, você está livre para acessar, desde que, não ultrapasse seu limite, o limite se espante até o limite de memória sequência na heap: mídia da memória local do computador livre e progressiva em geral dinâmica, nos casos em que isso é implemento, porém definir um tamanho e acessar outro maior põem em risco toda lógica, o que significa dizer que vai funcionar: quando acessa um limite livre e reservado no arranque do programa, ou não vai funcionar: dependendo do quantitativo acessado extrapolou o limite ou alterou dados somente leitura, ou reservados.

 

Entendeu?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Static permite que a variável seja lembrada e permaneça reservada na memória para uso até o fim do programa, o mesmos você poderia fazer sem definir static, porém correria riscos, pois a variável estaria sujeita a ser reutilizada com término da função relatorio, isso de fato é outra pergunta.

 

Ps.: static é muito útil para implemento alloc: uma implementação local de controle de memória análogo a malloc só que no código, em geral definida no escopo global.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Olá.

 

1#

Sobre:

13 horas atrás, Giovanaf disse:

@Simon Viegas  Diferente do que você propôs, fiz apenas uma função fora da main. Acredito que não seja problema.

 

OK. Em relação ao fazer "fora do main()" vai da interpretação de cada um... mas veja:

13 horas atrás, Giovanaf disse:

Crie uma função que receba um vetor de 100 valores tipo int como parâmetro (valores devem ser gerados aleatoriamente pelo programa principal) e retorne a média, valor máximo, valor mínimo e desvio padrão dos valores no vetor. Média e desvio padrão devem ter 4 casas decimais.

 

De um modo geral, a minha interpretação (assim como, a princípio, do @giu_d e @AnsiC) é que o enunciado indica que deve ser feito dentro do main(). Mas esse não é o principal problema... (vide o 2#).

 

 

 

2#

Então, NO MÍNIMO, a parte que gera os números deve ficar separada da parte que função que foi solicitada... caso contrário, não fará o menor sentido a frase que está em negrito na citação acima!. Quem fez o enunciado pode pensar: "ué! ainda deixei entre parênteses para frisar o que eu quero e mesmo assim fui ignorado!".

 

O enunciado é a base de tudo..

 

Logo, poderá fazer:

- uma função (método) para gerar os aleatórios (ou deixa no main(), como sugerimos);

- outra função para retornar o relatório.

 

 

3#

Outro ponto que julgo muito importante é a "coerência entre as nomenclaturas", veja:

13 horas atrás, Giovanaf disse:

void aleatorio (int v[], float n){

 

Vamos supor que pode deixar tudo junto num método só... Você chamou a função de aleatorio, mas esta está "gerando número aleatórios", "efetuando cálculos", "exibindo resultados" etc... ou seja, "tudo isso" não pode ser chamado de simplesmente de "aleatorio", sacou? poderia chamar, por exemplo, de relatorio, como sugerido por @AnsiC.

 

É análogo ao citado para @giu_d

22 horas atrás, Simon Viegas disse:

PS: @giu_d, outra coisa, perceba que você alterou a estrutura do método de ordenação... o que tecnicamente deixou de de ser Bubble Sort.... Já que uma das principais características do Bubble é comparar com o adjacente.. A estrutura foca na flutuação como uma bolha. O código da  @Giovanaf segue o padrão, veja:

Ou seja, não é "proibido" alterar o método de ordenação, o que fica "estranho" é continuar usando o mesmo nome!! Não é uma questão de ser um algoritmo melhor ou pior, apenas que "não é mesma coisa"...  Outro exemplo... seria como em vez de usar menor e maior para receber o maior e menor respectivamente, usasse a nomenclatura nome e CPF para os mesmos fins... vai funciona? vai! mas fica incoerente... o que quero sugerir é que "quanto mais próximo do que representa, melhor".

 

 

 

4#

Outro ponto que comentei é que essa função deve servir para retornar uma resposta, o não "imprimir uma resposta dentro dela". No caso, umas das 3 formas de retornar seriam essas:

 

Em 23/07/2018 às 11:18, Simon Viegas disse:
  1. variável global; (não desejável)
  2. por parâmetros do tipo referência*; (usando variáveis do parâmetro para receber os dados)
  3. através do retorno do método, ou seja, utilizando o return. (como o return só entrega uma coisa, teria que pensar em como devolver 3... poderia por exemplo utilizando struct ou "concatenando os dados e separando depois" etc).

 

No exemplo, o @AnsiC usou opção 3... para isso, utilizou de um vetor de 4 posições para retornar os dados, ou seja, cada posição do vetor é uma das informações perdidas, veja:

 

obs.: inserir comentários sobre como está funcionando o trecho, mas precisa da confirmação do @AnsiC, rs

12 horas atrás, AnsiC disse:

real * relatorio (int tamanho, int vetor[]) {
    static real rdados[4]; //em outras palavras, o tipo real possibilita usar int OU usar float... depende de qual escolher na hora
    
    rdados[0].rint = minimo (tamanho, vetor);  //aqui vai usar a posição do vetor (da memória) como sendo um int
    rdados[1].rint = maximo (tamanho, vetor);
    rdados[2].rfloat = media (tamanho, vetor); //aqui vai usar a posição do vetor (da memória) como se fosse um float
    rdados[3].rfloat = desvio (tamanho, vetor, rdados[2].rfloat);
    return rdados; //ou seja, rdados tem valores int em algumas posições, e tem float outras
                   //se usar struck em vez de union, cada posição terá as duas coisas! (vai ocupar o dobre de espaço na memória)
}

 

O único detalhe que pode parecer um pouco mais estranho é que usou um tal de union (eu não conhecia.. no código tb tentei expor em comentários do que eu entendi dele), mas pelo que eu vi, nada mais é que uma forma de "economizar memória", ou seja, rint e rfloat utilizam o mesmo espaço de memória, daí usar um OU outro serve apenas para indicar qual tipo quer usar...

 

RESUMINDO: cada posição desse vetor só recebe um dado... no caso ou um int ou um float. Tipo, se fosse tudo float... usaria simplesmente o tradicional float*.

 

 

 

5#

Uma outro forma de retornar seria com struct, ex.:

typedef struct {
    int   minimo;
    int   maximo;
    float media;
    float desvio;
} Dados;

Daí, em vez de usar um vetor (sendo cada posição um dado), poderia usar um "registro"... ou seja, cada campo da struct seria um dado que precisa.

 

 

 

6#

Abaixo alterei (tentei alterar) o código para usar uma struct, em vez de um vetor. Segue:

#include <stdio.h>  /*  ~incluir: printf */
#include <stdlib.h>  /* ~incluir: rand; srand */
#include <time.h>  /*   ~incluir: time */
#include <math.h>  /*   ~incluir: sqrt */

#define MAXVALOR  100
#define VETSIZ  100

/** typedef ~ Dados
*    cria o tipo armazenada cada um dos dados necessários. 
*/
typedef struct {
    int   minimo;
    int   maximo;
    float media;
    float desvio;
} Dados; //cada item da struck é um dos dados necessários [Simon.Viegas]

/** função maximo ~ retorna o maior valor */
int maximo (int tamanho, int vetor[]) {
    int val = vetor[0];
    
    for (int i = 1; i  <  tamanho; i += 1) {
        if (val  <  vetor[i]){
            val = vetor[i];
        }
    }
    return val;
}

/** função maximo ~ retorna o menor valor */
int minimo (int tamanho, int vetor[]) {
    int val = vetor[0];
    
    for (int i = 1; i  <  tamanho; i += 1) {
        if (val  >  vetor[i]) {
            val = vetor[i];
        }
    }
    return val;
}

/** função media ~ retorna o media */
float media (int tamanho, int vetor[]) {
    float soma = vetor[0];
    
    for (int i = 1; i  <  tamanho; i += 1) {
        soma += vetor[i];
    }
    return soma/tamanho;
}

/** função desvio ~ retorna o desvio */
float desvio (int tamanho, int vetor[], float media) {
    float var = 0;
    int   dif = 0;
    
    for (int i = 0; i < tamanho; i += 1) {
        dif = vetor[i] - media;
        var += (dif*dif);
    }
    return sqrt (var);
}

/** funcao relatorio ~ principal da tarefa  */
Dados relatorio (int tamanho, int vetor[]) {
    static Dados rdados;
    
    rdados.minimo = minimo(tamanho, vetor);
    rdados.maximo = maximo(tamanho, vetor);
    rdados.media  = media (tamanho, vetor);
    rdados.desvio = desvio(tamanho, vetor, rdados.media);
    return rdados;
}

/** funcao main ~ principal do programa  */
int main (void) {
    int vetor[VETSIZ] = {0};
    Dados dados;
    
    srand (time(0));
    printf ("Vetor Randomico\n");
    for (int i = 0; i < VETSIZ; i += 1) {
        vetor[i] = rand()%MAXVALOR;
        printf ("%2d", vetor[i]);
        if ((i + 1)%10 == 0)
            printf ("\n");
        else
            printf (" ");
    }
    printf ("\n");
    dados = relatorio (VETSIZ, vetor);
    printf ("#Relatorio\n");
    printf ("1. Minimo: %d\n"  , dados.minimo);
    printf ("2. Maximo: %d\n"  , dados.maximo);
    printf ("3. Media : %.4f\n", dados.media );
    printf ("4. Desvio: %.4f\n", dados.desvio);
    printf ("\n");
    return 0;
}

obs.: não garanto que a sintaxe está correta, mas aqui funcionou. :)

 

 

***

 

Por favor, corrijam onde errei e/ou complementem...

 

adicionado 11 minutos depois

 

 

Sobre:

49 minutos atrás, AnsiC disse:

Static permite que a variável seja lembrada e permaneça reservada na memória para uso na função mainha até o fim do programa, o mesmos você poderia fazer sem definir static, porém correria riscos, pois a variável estaria sujeita a ser reutilizada com término da função, isso de fato é outra pergunta.

 

Tenho dúvidas também sobre essa questão do static... mas no caso, os dados não estarão em dados (em vez de rdados)? daria para exemplificar melhor os possíveis problemas caso não usar o static.  No código que postei em 6#, seria necessário também esse static?

 

 

Link para o comentário
Compartilhar em outros sites

53 minutos atrás, Simon Viegas disse:

Tenho dúvidas também sobre essa questão do static... mas no caso, os dados não estarão em dados (em vez de rdados)? daria para exemplificar melhor os possíveis problemas caso não usar o static.  No código que postei em 6#, seria necessário também esse static?

As variáveis quando declaradas com static permanecem em local especial na memoria para esse tipo, ou classe de variável. Essa memória é definida no arranque do programa: quando clicamos em um programa e ele é carregado pelo sistema, esse por sua vez vai dedicar memória para esse tipo de variável, que permanecerá lá pelo tempo vital do programa. A função relatório retorna o local onde o "relatorio" foi salvo, retornando esse local especial.

 

O Códio 6# não faz a mesma coisa, pois existe uma cópia entre dois locais de dados diferentes: o retorno da função relatorio gera um local, a variável na ponta dentro da função main gera outro novo local, os dois locais tem o mesmo tamanho, assim como um carimbo o "retorno de relatorio da uma carimbada" no local da memoria da variável em main e depois disso se destrói.

Nesse (6#) caso foi um retorno envolvendo copia de dados, no outro com static foi um retorno envolvendo compartilhadamente de dados.

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!