Ir ao conteúdo
  • Cadastre-se
johnsigma

C Erro na execução de um algoritmo em C com ponteiros

Recommended Posts

Tenho esse algoritmo pra fazer:

Codifique, compile e execute um programa em C que declare na função principal uma estrutura
para o cadastro de alunos de uma academia. a) Para cada aluno armazenar: nome, sobrenome (apenas um), ano de nascimento e um vetor de 6
posições indicando quais dias da semana o aluno frequenta a academia. Lembrando que a
academia funciona de segunda a sábado;
b) Ao iniciar o programa, o usuário deverá informar o número de alunos que serão armazenados;
c) O programa deverá alocar dinamicamente a quantidade necessária de memória para armazenar
os registros dos alunos;
d) O programa deverá pedir ao usuário que entre com as informações dos alunos;
e) Ao final, o programa deve exibir na tela os dados armazenados e liberar a memória alocada. Não esqueça de usar funções para estruturar o seu código.

Consegui fazê-lo rodar mas sem o uso de ponteiro e creio que estou confundindo o conceito de ponteiro e alocação dinâmica. Então gostaria que avaliassem meu código e dissessem o que estou fazendo de errado.

Código:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <math.h>

int main(){

setlocale(LC_ALL, "Portuguese_Brazil");

    struct cadastro{
        char nome[20];
        char sobrenome[30];
        char ano[10];
        int dias[6];
    };

    int n,i,j,*p;

    printf("Digite quantos alunos cadastrar: ");
    scanf("%d",&n);
    setbuf(stdin,NULL);
    printf("\n");

    p=(int *) malloc(n*sizeof(int));

    struct cadastro c[*p];

    for(i=0;i<n;i++){
        printf("%dº aluno para cadastrar:\n\n",i+1);
        printf("Nome: ");
        fgets(c[p[i]].nome,20,stdin);
        setbuf(stdin,NULL);
        printf("Sobrenome (apenas um): ");
        gets(c[p[i]].sobrenome);
        setbuf(stdin,NULL);
        printf("Ano de nascimento: ");
        gets(c[p[i]].ano);
        setbuf(stdin,NULL);
        printf("\nDias na semana que frequenta a academia (0 para não; 1 para sim):\n");
        setbuf(stdin,NULL);
        for(j=0;j<6;j++){
            printf("Dia %d: ",j+1);
            scanf("%d",&c[p[i]].dias[j]);
            setbuf(stdin,NULL);
        }
        printf("\n\n");
    }

    printf("\n\nDados cadastrados dos alunos: \n\n");

    for(i=0;i<n;i++){
        printf("%dº aluno: \n",i+1);
        printf("Nome: %s",c[p[i]].nome);
        printf("Sobrenome: %s\n",c[p[i]].sobrenome);
        printf("Ano de nascimento: %s\n",c[p[i]].ano);
        printf("O aluno foi na academia nos seguintes dias:\n");
            if(c[p[i]].dias[0]==1)
                printf("Segunda, ");
            if(c[p[i]].dias[1]==1)
                printf("Terça, ");
            if(c[p[i]].dias[2]==1)
                printf("Quarta, ");
            if(c[p[i]].dias[3]==1)
                printf("Quinta, ");
            if(c[p[i]].dias[4]==1)
                printf("Sexta, ");
            if(c[p[i]].dias[5]==1)
                printf("Sábado");
        printf("\n\n\n");
    }
  
  free(p);

    return 0;
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Para que você entenda mais ou menos, simplificando...
 

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

typedef struct Dados {
    char nome[20];
    char sobrenome[30];
    char ano[10];
    int dias[6];
} dados;

int main() {
    int n = 10; // numero de elementos a pedir por teclado
    
    dados *lista; //Ponteiro a dados
    
    lista = ( dados* ) malloc ( n * sizeof ( dados ) ); //vetor de dados
    
    //Exemplo de uso
    strcpy( lista[0].nome, "Leopoldo");
    lista[0].dias[0] = 1;
    
    printf("Nome: %s", lista[0].nome);
    
    free ( lista );//Liberando
    
    return 0;
}

 

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
20 minutos atrás, vangodp disse:

Para que você entenda mais ou menos, simplificando...
 


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

typedef struct Dados {
    char nome[20];
    char sobrenome[30];
    char ano[10];
    int dias[6];
} dados;

int main() {
    int n = 10; // numero de elementos a pedir por teclado
    
    dados *lista; //Ponteiro a dados
    
    lista = ( dados* ) malloc ( n * sizeof ( dados ) ); //vetor de dados
    
    //Exemplo de uso
    strcpy( lista[0].nome, "Leopoldo");
    lista[0].dias[0] = 1;
    
    printf("Nome: %s", lista[0].nome);
    
    free ( lista );//Liberando
    
    return 0;
}

 

 

valeu demais, deu certo aqui. Mas ali no caso quando eu criei o vetor de dados eu tive que colocar o nome do ponteiro da struct. Então no seu exemplo ficaria: lista=(dados*) malloc(n*sizeof(lista));

 

Outra dúvida: Tenho um exercício que tenho que criar uma função para exibir os funcionário de maior salário(se tiver mais de 1 funcionário com salários iguais e esses forem os maiores). Como eu faço pra fazer essa função e ela retornar os funcionários com os maiores salário independente de quantos funcionários tem? Consigo fazer apenas com um, e se houver mais de 1 funcionário com salário igual ao do maior ele exibe apenas 1 deles!

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 minuto atrás, johnsigma disse:

valeu demais, deu certo aqui. Mas ali no caso quando eu criei o vetor de dados eu tive que colocar o nome do ponteiro da struct. Então no seu exemplo ficaria: lista=(dados*) malloc(n*sizeof(lista));

Não entendi o que você quer dize... Essa é a forma correta de declarar o vetor de alunos.

 

 

4 minutos atrás, johnsigma disse:

Outra dúvida: Tenho um exercício que tenho que criar uma função para exibir os funcionário de maior salário(se tiver mais de 1 funcionário com salários iguais e esses forem os maiores). Como eu faço pra fazer essa função e ela retornar os funcionários com os maiores salário independente de quantos funcionários tem? Consigo fazer apenas com um, e se houver mais de 1 funcionário com salário igual ao do maior ele exibe apenas 1 deles!

Suponho que seu problema não é encontrar os tais valores e nem anotar quais são os assalariados agraciados. Da a entender que seu problema é somente retornar os valores. A solução seria ponteiros, ou retornar uma struct com tudo dentro.
 

Compartilhar este post


Link para o post
Compartilhar em outros sites
4 minutos atrás, vangodp disse:

Não entendi o que você quer dize... Essa é a forma correta de declarar o vetor de alunos.

É que o meu ficou assim:

struct cadastro *c;
 c=(struct cadastro*) malloc(n*sizeof(c));

E não assim: 

struct cadastro *c;
c=(struct cadastro*) malloc(n*sizeof(cadastro));

 

11 minutos atrás, vangodp disse:

Suponho que seu problema não é encontrar os tais valores e nem anotar quais são os assalariados agraciados. Da a entender que seu problema é somente retornar os valores. A solução seria ponteiros, ou retornar uma struct com tudo dentro.

O problema é mais simples ainda. Vou anexar um print do problema. Não estou conseguindo fazer a segunda função pois se 2(ou mais) funcionários tiverem o mesmo salário(e esse salário seja o máximo) eu tenho que exibir o nome dos dois. Eu sei fazer apenas com 1, e nesse caso o programa iria ignorar um(ou mais) dos funcionários com maior salário!

2018024480_Semttulo.png.b7ca7a327251b4a167277b9ba14ad4fd.png 

Compartilhar este post


Link para o post
Compartilhar em outros sites
9 minutos atrás, johnsigma disse:

É que o meu ficou assim:

struct cadastro *c;
 c=(struct cadastro*) malloc(n*sizeof(c));

E não assim: 

struct cadastro *c;
c=(struct cadastro*) malloc(n*sizeof(cadastro));

c é um ponteiro, e você precisa passar o tamanho da estrutura, não do ponteiro. Note que no meu exemplo eu usei "dados", pois dados já foi declarado depois do } e antes do ;, pelo tanto já está na memória, tem um tamanho definido em bytes, e é isso que o malloc quer. faça um sizeof de c e de cadastro, imprima na tela e você vai ver a diferença.

 

 

14 minutos atrás, johnsigma disse:

2018024480_Semttulo.png.b7ca7a327251b4a167277b9ba14ad4fd.png 

mande seu progresso para eu ter uma ideia onde você ta errando

adicionado 6 minutos depois
#include <stdio.h>


    struct cadastro{
        char nome[20];
        char sobrenome[30];
        char ano[10];
        int dias[6];
    };

int main() {
    struct cadastro *c;
    
    printf("sizeof de *c: %d\n", sizeof(c));
    printf("sizeof de cadastro: %d\n\n", sizeof(struct cadastro));
    
    return 0;
}

prove isso: no seu malloc você recebe 4 bytes somente, e deve receber a soma de char nome[20]+ char sobrenome[30]+ char ano[10]+ int dias[6]. Isso tudo sem incluir o alinhamento de bytes que é outro tema delicado.

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

O melhor seria:

c = malloc(n * sizeof *c);

ou

c = malloc(n * sizeof(*c));

Ou seja, o tamanho daquilo para o qual o ponteiro c aponta.

 

Em C nunca precisa dar casting no retorno de malloc.

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
c= ((struct cadastro *) malloc(n * (sizeof *c)));

Caso 0: Essa declaração tem sentido, o sentido a que me refiro é aquele que complemento literal da variável c, pois havendo esta pergunta quem é c? O casting imediatamente comunica é do tipo.

 

c= malloc( sizeof (struct cadastro[ n ]) );
/*: Alocar memória de n-cadastros */

Caso 1: Outra maneira que acredito ser interessante. Tem a mesma função que a anterior que deixa também claro que tipo é o tipo c.

 

Caso 2: Agora um contra exemplo a tudo isso, observe:

struct cadastro *	c= (struct cadastro *) malloc( n * sizeof(struct cadastro) );

Temos o exagero da declaração. Quando no caso 1 o tipo aparece didaticamente um vez, aqui ele aprece todas as vezes. Se adequarmos, fica semelhante ao que propõe os colegas.

struct cadastro *	c= malloc( n * (sizeof *c) );

Fica suficientemente claro.

 

Obrigado.

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 08/12/2018 às 18:29, vangodp disse:

mande seu progresso para eu ter uma ideia onde você ta errando

adicionado 6 minutos depois

 

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <math.h>

struct endereco{
    char rua[20];
    char num[6];
    char bairro[20];
    char cep[15];
    char cidade[20];
    char estado[35];
};

struct data{
    char dia[3];
    char mes[25];
    char ano[5];
};

struct funcionario{
    char nome[50];
    struct data d;
    struct endereco e;
    float salario;
};

void dados(int *x, struct funcionario *j){
    int i;
    for(i=0;i<*x;i++){
        printf("%dº funcionário:\n",i+1);
        printf("Nome: ");
        gets(j[i].nome);
        setbuf(stdin,NULL);
        printf("Dia do nascimento: ");
        gets(j[i].d.dia);
        setbuf(stdin,NULL);
        printf("Mês do nascimento: ");
        gets(j[i].d.mes);
        setbuf(stdin,NULL);
        printf("Ano do nascimento: ");
        gets(j[i].d.ano);
        setbuf(stdin,NULL);
        printf("Rua: ");
        fgets(j[i].e.rua,20,stdin);
        setbuf(stdin,NULL);
        printf("Número: ");
        fgets(j[i].e.num,6,stdin);
        setbuf(stdin,NULL);
        printf("Bairro: ");
        fgets(j[i].e.bairro,20,stdin);
        printf("CEP: ");
        fgets(j[i].e.cep,15,stdin);
        printf("Cidade: ");
        fgets(j[i].e.cidade,20,stdin);
        printf("Estado: ");
        fgets(j[i].e.estado,35,stdin);
        printf("Salário: ");
        scanf("%f",&j[i].salario);
        setbuf(stdin,NULL);
        printf("\n");
    }
}

void compara_salario(int *x, struct funcionario *j){
    int i;
    float *ms;
    char nomem[50];
    for(i=0;i<*x;i++){
        if(i==0){
            ms=&j[i].salario;
            strcpy(nomem,j[i].nome);
        }
        else{
            if(*ms<j[i].salario){
                ms=&j[i].salario;
                strcpy(nomem,j[i].nome);
            }
        }
    }
    printf("Funcionário com o maior salário: %s",nomem);
}

int main(){

setlocale(LC_ALL, "Portuguese_Brazil");

    int n,i,*k;

    printf("Digite a quantidade de funcionários: ");
    scanf("%d",&n);
    printf("\n");
    setbuf(stdin,NULL);

    struct funcionario *f;
    f=(struct funcionario*) malloc(n*sizeof(f));
    k=&n;

    dados(k,f);
    compara_salario(k,f);

    return 0;
}

Esse é o código, tá funcionando, mas ele exibe apenas um nome pois não sei como fazer para aparecer mais de um se os os funcionário tiverem o mesmo salário e esse salário seja o máximo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro 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 publicações 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

×