Ir ao conteúdo
  • Cadastre-se
Entre para seguir isso  
nexus.tecinfo

Exercicio struct

Recommended Posts

ajuda com exercicios

fazer um struct p/ cadastro de 10 alunos, contendo nome, numero da matricula, 3 notas e frequencia, 1 função p média outra p ver se passou ou não pelas faltas, a julgar q o limite de faltas seja de 40 e a media é 7.

onde está ou estão os erros?


#include <stdio.h>
#include <stdlib.h>
#define N 10

typedef struct {
int numero_matricula, freq;
char nome;
float n1,n2,n3;
} cadastro;

int frequencia (int freq);
float medias(float n1,float n2,float n3);

int main(void){

int i,media, rfreq;

for(i=1;i<=N;i++){
printf("Digite seu nome:\n");
scanf("%s",cadastro.nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&cadastro.nmat);
printf("Digite nota 1:\n");
scanf("%f",&cadastro.n1);
printf("Digite nota 2:\n");
scanf("%f",&cadastro.n2);
printf("Digite nota 3:\n");
scanf("%f",&cadastro.n3);
printf("Digite a frequencia:\n");
scanf("%d",&cadastro.freq);

media=medias(float n1,float n2,float n3);
rfreq=requencia (int freq);
return 0;

if((media==7)&&(rfreq==1))
printf("Aprovado, media %f e frequencia %d", media, freq);

else
printf("Reprovado, media %f e frequencia %d", media, freq);
}
float medias(float n1,float n2,float n3){
float nt1,nt2,nt3;
media=nt1,nt2,nt3/3;
return media;
}

int frequencia(int freq){
int faltas, rfreq;
if (faltas<=40)
rfreq=1;
else
rfreq=0;
system("pause");
return rfreq;
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Primeiramente, você não precisa colocar int main (void). Esse VOID, não precisa colocar não...Segundo, no seu primeiro for você não vai pegar o cadastro de 10 alunos ali, só de 1, dez vezes!!

Para você pegar 10 cadastros você precisa fazer assim no main:


int main ()
{
int i;
cadastro c[9];
for (i=0;i<N;i++)
{
printf ("Digite seu nome: ");
gets(c[0].nome);
...

Lembrando, que na sua STRUCT você fez uma variável de caractere NOME, mas isso não vai armazenar uma string, e sim só UM CARACTERE!!!! Então, na sua struct no lugar de:


...
char nome;
...

Coloque:


...
char* nome;
...

ou


...
char nome[30];
...

Eu prefiro a primeira opção, que cria um ponteiro que vai servir como string...Também há erros na sua função FREQUENCIA e MEDIA. Agora eu tenho que sair amigo, desculpe!! Depois eu volto e continuo a te ajudar =D

Compartilhar este post


Link para o post
Compartilhar em outros sites

#include <stdio.h>
#include <stdlib.h>
#define N 10

typedef struct {
int numero_matricula, freq;
char *nome;
float n1,n2,n3;
} cadastro;

int frequencia (int freq);
float medias(float n1,float n2,float n3);

int main ()
{
int i;
cadastro c[9];
for (i=0;i<N;i++)
{
printf ("Digite seu nome: ");
gets(c[0].nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&cadastro[0].nmat);
printf("Digite nota 1:\n");
scanf("%f",&cadastro[0].n1);
printf("Digite nota 2:\n");
scanf("%f",&cadastro[0].n2);
printf("Digite nota 3:\n");
scanf("%f",&cadastro[0].n3);
printf("Digite a frequencia:\n");
scanf("%d",&cadastro[0].freq);

media=medias(float n1,float n2,float n3);
rfreq=requencia (int freq);
return 0;

if((media==7)&&(rfreq==1))
printf("Aprovado, media %f e frequencia %d", media, freq);

else
printf("Reprovado, media %f e frequencia %d", media, freq);
}
float medias(float n1,float n2,float n3){
float nt1,nt2,nt3;
media=nt1,nt2,nt3/3;
return media;
}

int frequencia(int freq){
int faltas, rfreq;
if (faltas<=40)
rfreq=1;
else
rfreq=0;
system("pause");
return rfreq;
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Vamo la amigo!

Tente realmente entender o que vou explicar, e não só copiar e colar, isso vai te ajudar muito! =D

Vamos por partes, primeiro os erros:

No sua função principal, MAIN, você declarou 10 estruturas para CADASTRO, isso como:

c[9]

Então no seu for você não vai ler nenhum cadastro[0] e sim c[0], c[1], c[2]

Concertando ficaria assim:


for (i=0;i<N;i++)
{
printf ("Digite seu nome: ");
gets(c[0].nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&c[0].nmat);
printf("Digite nota 1:\n");
scanf("%f",&c[0].n1);
printf("Digite nota 2:\n");
scanf("%f",&c[0].n2);
printf("Digite nota 3:\n");
scanf("%f",&c[0].n3);
printf("Digite a frequencia:\n");
scanf("%d",&c[0].freq);
...

Agora para o segundo erro, nesse for você colocou TODOS como c[0]. Isso está errado, se não ele vai ler 10x a estrutura c[0], ou seja de 1 só aluno! O certo seria você colocar c. Então no for toda vez ele vai aumentando 1, e você terá os 10 alunos, ou seja o certo seria assim:


for (i=0;i<9;i++)
{
printf ("Digite seu nome: ");
gets(c[i].nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&c[i].nmat);
printf("Digite nota 1:\n");
scanf("%f",&c[i].n1);
printf("Digite nota 2:\n");
scanf("%f",&c[i].n2);
printf("Digite nota 3:\n");
scanf("%f",&c[i].n3);
printf("Digite a frequencia:\n");
scanf("%d",&c[i].freq);
...

Vamos para mais um erro:


if((media==7)&&(rfreq==1))
printf("Aprovado, media %f e frequencia %d", media, freq);

Esse IF quer dizer que, ele só será aprovado se a MÉDIA for igual a 7 e a RFREQ = 1. Então se a média for maior que 7 ele não será aprovado. Então você poderia deixar assim:

if((media=>7)&&(rfreq==1))
printf("Aprovado, media %f e frequencia %d", media, freq);

Próximo erro, quando você chama as funções que criou no main:

 media=medias(float n1,float n2,float n3);
rfreq=requencia (int freq);

Bem, isso está muito errado! ja que você vai chamar a função, você colocou nos parâmetros variáveis que não existem no seu código, e ainda você está declarando variáveis!! Se houvessem as variáveis : n1,n2,n3,freq no seu código você poderia fazer assim:

media=medias(n1,n2,n3);
rfreq=frequencia (freq);

Mas pelo o que eu vi esses valores dos parâmetros seriam os da ESTRUTURA, não?

Próximo erro, as funções!


float medias(float n1,float n2,float n3){
float nt1,nt2,nt3;
media=nt1,nt2,nt3/3;
return media;
}

Isso está completamente errado x.x'. A parte float medias(float n1,float n2,float n3) está certa, mas eu queria saber o que você quis fazer ali! Porque você criou 3 variáveis do tipo FLOAT (nt1, nt2 e nt3) e MEDIA algo que você nem ao menos declarou está fazendo alguma coisa com as 3, que ninguém sabe porque tem vírgulas no meio O.o. Se nessa função medias você queria simplesmente pegar o valor das 3 notas somadas e dividas por 3 você pode simplesmente fazer assim:


float medias(float n1,float n2,float n3)
{
return ((n1 + n2 + n3) /3);
}

Agora vamos a outra função:


int frequencia(int freq){
int faltas, rfreq;
if (faltas<=40)
rfreq=1;
else
rfreq=0;
system("pause");
return rfreq;
}

Você colocou o system("pause"); acho que no lugar errado, acho que você queria colocar no final do programa! Então tire isso daí e coloque no fim da sua função MAIN!

Agora à função FREQUENCIA. Você declarou 2 variáveis, e depois você fez um if (faltas<=40). Como você faz isso? Faltas não tem ao menos um valor! Acho que o mais certo seria fazer:


int frequencia(int freq){
if(freq <= 40)
return 0;
else
return 1;
}

Ah! E mais um erro, o seu return 0; na função MAIN, tem que ser usado no final dela, e não no meio como você colocou!

Agora vamos ao concerto do seu programa \O/. Se você quiser guardar o valor das medias e da frequencia, pode usar um vetor para as medias. Você precisa declarar uma variável do tipo int chamada rfreq, ou o nome que você quiser! E outra chamada media do tipo float, após ler os valores da estrutura você tem que colocar assim:


...
media=medias(c[i].n1,c[i].n2,c[i].n3);
rfreq=frequencia (c[i].freq);
...

Você tem que apagar esse return 0; que vem em seguida...

E agora o IF vai ficar assim:

 if((media=>7)&&(rfreq==1))
printf("Aprovado, media %f e frequencia %d", media, c[i].freq);
else
printf("Reprovado, media %f e frequencia %d", media, c[i].freq);

E como a função MAIN acaba ai, abaixo disso você coloca o return 0;

Uffa! Acho que é isso ai amigo :P. Como eu disse LEIA BEM! NÃO COPIE, TENTE ENTENDER!

Compartilhar este post


Link para o post
Compartilhar em outros sites

amigo, entendi sim a estrutura só que na hora de colocar esta dando uns erros, comentei para dar uma melhorada e poder compreender melhor ;)



#include <stdio.h>
#include <stdlib.h>
#define N 10

// nesta sessão será o protótipo

typedef struct {
int numero_matricula, freq;
char *nome;
float n1,n2,n3;
} cadastro;

int frequencia (int freq);
float medias(float n1,float n2,float n3);

int main ()
{
int i;
cadastro c[9];
int rfreq;
int media;
// neste será onde irá fazer o cadastro dos 10 alunos, suas notas e //frequencias

for (i=0;i<9;i++)
{
printf ("Digite seu nome: ");
gets(c[i].nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&c[i].numero_matricula);
printf("Digite nota 1:\n");
scanf("%f",&c[i].n1);
printf("Digite nota 2:\n");
scanf("%f",&c[i].n2);
printf("Digite nota 3:\n");
scanf("%f",&c[i].n3);
printf("Digite a frequencia:\n");
scanf("%d",&c[i].freq);

//aqui sera armazenado as notas e suas respectivas medias e frequencia
media=medias(c[i].n1,c[i].n2,c[i].n3); // da este erro nesta linha //[Warning] converting to `int' from `float'
rfreq=frequencia (c[i].freq);
return 0;
// nesta ira verificar se passou ou não
if((media=>7)&&(rfreq==1))
printf("Aprovado, media %f e frequencia %d", media, c[i].freq);
else
printf("Reprovado, media %f e frequencia %d", media, c[i].freq);
float medias(float n1,float n2,float n3)
{
return ((n1 + n2 + n3) /3); // não entendi este return
}
}


int frequencia(int freq){
if(freq <= 40)
return 0;
else
return 1;
}
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara, tira esse RETURN 0; do meio do MAIN e coloca no FINAL!!! E porque você não fechou as chaves do MAIN e do FOR??? e você declarou a variável MEDIA, no main, como inteiro,e não como FLOAT como eu disse...Ja sobre o RETURN da função MEDIAS:

Primeiro: Você vai pegar as 3 notas do aluno, certo?

Segundo: Para a variável MEDIA você quer o valor das 3 notas somadas e dividas por 3, certo?

Terceiro: A função MEDIAS vai pegar esses 3 valores e vai retornar, os 3 somados e depois divididos

Quarto: no caso

media=medias(c[i].n1,c[i].n2,c[i].n3);

Ai a função MEDIAS vai RETORNAR e ATRIBUIR à variavel MEDIA o valor de c.n1 + c.n2 + c.n3, dessa soma divido por 3!

Compartilhar este post


Link para o post
Compartilhar em outros sites

fiz as mudanças, tirei o

return 0; 

do meio e declarei as variaveis

 float n1,n2,n3;

os erros agora da na parte de baixo nas medias...


#include <stdio.h>
#include <stdlib.h>
#define N 10

typedef struct {
int numero_matricula, freq;
char *nome;
float n1,n2,n3;
} cadastro;

int frequencia (int freq);
float medias(float n1,float n2,float n3);

int main () {
int i;
cadastro c[9];
int rfreq;
float media;

for (i=0;i<9;i++)
{
printf ("Digite seu nome: ");
gets(c[i].nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&c[i].numero_matricula);
printf("Digite nota 1:\n");
scanf("%f",&c[i].n1);
printf("Digite nota 2:\n");
scanf("%f",&c[i].n2);
printf("Digite nota 3:\n");
scanf("%f",&c[i].n3);
printf("Digite a frequencia:\n");
scanf("%d",&c[i].freq);
}

media=medias(c[i].n1,c[i].n2,c[i].n3);
rfreq=frequencia (c[i].freq);


if((media>=7)&&(rfreq==1))
printf("Aprovado, media %f e frequencia %d", media, c[i].freq);

else
printf("Reprovado, media %f e frequencia %d", media, c[i].freq);
}
//erros desta parte para baixo
float medias(float n1 ,float n2 ,float n3);{
return ((n1 + n2 + n3) /3);
}
int frequencia(int freq);
{
if(freq <= 40)
return 0;
else
return 1;

system("pause");
return 0;
}

Editado por nexus.tecinfo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Amigo é porque você colocou o ponto e vírgula (;) ao definir as funções, você so usa isso no protótipo delas! E também, me explique por que você colocou isso:


system("pause");
return 0;

No final da função frequencia?? Isso vai deixar sua função errada!! Coloque isso no FINAL DA FUNÇÃO MAIN. A função frequencia, apesar de você tê-la definido por ultimo, ela não é sua ultima função! A única função que o seu pc vai rodar é a MAIN! Então se você quiser um PAUSE no final do programa coloque o "system("pause")" NO FINAL DO MAIN! O return 0; também é no final do MAIN!

Compartilhar este post


Link para o post
Compartilhar em outros sites

....

Arrumei...

#include <stdio.h>

#define N 10

struct cadastro
{
int numero_matricula, freq;
char nome[21];
float n1,n2,n3;
};

typedef struct cadastro Cadastro;

/* Prototipos das funcoes: */
int frequencia (int freq);
float medias(float n1,float n2,float n3);

/* Tem problema nenhum colocar void aqui... */
int main(void)
{
int i;
Cadastro c[N];
int rfreq;
float media;

for (i=0;i<N;i++)
{
printf ("Digite seu nome: ");
gets(c[i].nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&c[i].numero_matricula);
getchar();
printf("Digite nota 1:\n");
scanf("%f",&c[i].n1);
getchar();
printf("Digite nota 2:\n");
scanf("%f",&c[i].n2);
getchar();
printf("Digite nota 3:\n");
scanf("%f",&c[i].n3);
getchar();
printf("Digite a frequencia:\n");
scanf("%d",&c[i].freq);
getchar();
}

printf("\n\n");

for(i=0;i<N;i++)
{
media=medias(c[i].n1,c[i].n2,c[i].n3);
rfreq=frequencia (c[i].freq);

if((media>=7)&&(rfreq==1))
{
printf("Aprovado, ");
}
else
{
printf("Reprovado, ");
}

printf("media %.2f e frequencia %d\n", media, c[i].freq);
}

printf("\nFIM!");
getchar();
return 0;
}

float medias(float n1 ,float n2 ,float n3)
{
return ((n1 + n2 + n3) /3);
}

int frequencia(int freq)
{
if(freq <= 40)
return 0;
else
return 1;
}

GENTE, PELO AMOR DE DEUS!!!!

Vetores se declaram usando o TAMANHO DO VETOR e não pela posição final...

Quer dez inteiros???

    int vetor[10]; /* Vai de vetor[0] a vetor[9]...*/

Quer dez floats???

    int vetor[10]; /* Vai de vetor[0] a vetor[9]...*/

Quer uma string para palavras de no máx 9 caracteres?

    char palavra[10]; /* Vai de palavra[0] a palavra[9]...Lembrando que palavra[9]='\0'... */

Dez structs?

    struct coisas lista[10];

==========================================================

Outra: declarar uma STRING difere em muito de declarar um PONTEIRO PARA CARACTER....

Declarações válidas de string:


Normal 1:
char string1[]="teste1";
Normal 2:
char string2[30]="teste2";
Usando ponteiros 1:
char *string3="teste3";
Usando ponteiros 2:
char *string4;
string4=malloc(10*sizeof(char));
strcpy(string4,"teste4");

==========================================================

Outra coisa, não se coloca ponto-e-vírgula na definição de uma função.

Função são definidas por um par de chaves SÓ.

-

Compartilhar este post


Link para o post
Compartilhar em outros sites
....

Arrumei...

#include <stdio.h>

#define N 10

struct cadastro
{
int numero_matricula, freq;
char nome[21];
float n1,n2,n3;
};

typedef struct cadastro Cadastro;

/* Prototipos das funcoes: */
int frequencia (int freq);
float medias(float n1,float n2,float n3);

/* Tem problema nenhum colocar void aqui... */
int main(void)
{
int i;
Cadastro c[N];
int rfreq;
float media;

for (i=0;i<N;i++)
{
printf ("Digite seu nome: ");
gets(c[i].nome);
printf("Digite o numero da matricula:\n");
scanf("%d",&c[i].numero_matricula);
getchar();
printf("Digite nota 1:\n");
scanf("%f",&c[i].n1);
getchar();
printf("Digite nota 2:\n");
scanf("%f",&c[i].n2);
getchar();
printf("Digite nota 3:\n");
scanf("%f",&c[i].n3);
getchar();
printf("Digite a frequencia:\n");
scanf("%d",&c[i].freq);
getchar();
}

printf("\n\n");

for(i=0;i<N;i++)
{
media=medias(c[i].n1,c[i].n2,c[i].n3);
rfreq=frequencia (c[i].freq);

if((media>=7)&&(rfreq==1))
{
printf("Aprovado, ");
}
else
{
printf("Reprovado, ");
}

printf("media %.2f e frequencia %d\n", media, c[i].freq);
}

printf("\nFIM!");
getchar();
return 0;
}

float medias(float n1 ,float n2 ,float n3)
{
return ((n1 + n2 + n3) /3);
}

int frequencia(int freq)
{
if(freq <= 40)
return 0;
else
return 1;
}

GENTE, PELO AMOR DE DEUS!!!!

Vetores se declaram usando o TAMANHO DO VETOR e não pela posição final...

Quer dez inteiros???

    int vetor[10]; /* Vai de vetor[0] a vetor[9]...*/

Quer dez floats???

    int vetor[10]; /* Vai de vetor[0] a vetor[9]...*/

Quer uma string para palavras de no máx 9 caracteres?

    char palavra[10]; /* Vai de palavra[0] a palavra[9]...Lembrando que palavra[9]='\0'... */

Dez structs?

    struct coisas lista[10];

==========================================================

Outra: declarar uma STRING difere em muito de declarar um PONTEIRO PARA CARACTER....

Declarações válidas de string:


Normal 1:
char string1[]="teste1";
Normal 2:
char string2[30]="teste2";
Usando ponteiros 1:
char *string3="teste3";
Usando ponteiros 2:
char *string4;
string4=malloc(10*sizeof(char));
strcpy(string4,"teste4");

==========================================================

Outra coisa, não se coloca ponto-e-vírgula na definição de uma função.

Função são definidas por um par de chaves SÓ.

-

Não entendi o que quis dizer sobre a parada dos vetores O.O.Foi porque eu coloquei pra fazer 9 vetores ?? Isso foi lerdeza pura :P coloquei o número errado...Sobre o ponteiro para caractere, como eu disse a uns tópicos atrás eu sou muito ruim com alocação dinamica D=. Pra mim


char* string = "teste";

e


char string[10] = "teste";

Poderiam ser usados do mesmo modo '-'

Compartilhar este post


Link para o post
Compartilhar em outros sites
Não entendi o que quis dizer sobre a parada dos vetores O.O.Foi porque eu coloquei pra fazer 9 vetores ?? Isso foi lerdeza pura :P coloquei o número errado...Sobre o ponteiro para caractere, como eu disse a uns tópicos atrás eu sou muito ruim com alocação dinamica D=. Pra mim


char* string = "teste";

e


char string[10] = "teste";

Poderiam ser usados do mesmo modo '-'

Rode este programa:



int main(void)
{
char* string1 = "teste1";
char string2[10] = "teste2";

printf("Tamanho de 1 caracter: %d byte(s)\n",sizeof(char));
printf("Tamanho de um ponteiro para caracter: %d byte(s)\n",sizeof(char *));
printf("Tamanho de string1: %d byte(s)\n",sizeof(string1));
printf("Tamanho de string2: %d byte(s)\n",sizeof(string2));
printf("String1: [%s]\nString2: [%s]\n",string1,string2);

printf("\nFIM!");
getchar();
return 0;
}
#include <stdio.h>

Talvez dê para ver o que quero dizer.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Não entendi o que quis dizer sobre a parada dos vetores O.O.Foi porque eu coloquei pra fazer 9 vetores ?? Isso foi lerdeza pura :P coloquei o número errado...Sobre o ponteiro para caractere, como eu disse a uns tópicos atrás eu sou muito ruim com alocação dinamica D=. Pra mim


char* string = "teste";

e


char string[10] = "teste";

Poderiam ser usados do mesmo modo '-'

Rode este programa:



int main(void)
{
char* string1 = "teste1";
char string2[10] = "teste2";

printf("Tamanho de 1 caracter: %d byte(s)\n",sizeof(char));
printf("Tamanho de um ponteiro para caracter: %d byte(s)\n",sizeof(char *));
printf("Tamanho de string1: %d byte(s)\n",sizeof(string1));
printf("Tamanho de string2: %d byte(s)\n",sizeof(string2));
printf("String1: [%s]\nString2: [%s]\n",string1,string2);

printf("\nFIM!");
getchar();
return 0;
}
#include <stdio.h>

Talvez dê para ver o que quero dizer.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Rode este programa:



int main(void)
{
char* string1 = "teste1";
char string2[10] = "teste2";

printf("Tamanho de 1 caracter: %d byte(s)\n",sizeof(char));
printf("Tamanho de um ponteiro para caracter: %d byte(s)\n",sizeof(char *));
printf("Tamanho de string1: %d byte(s)\n",sizeof(string1));
printf("Tamanho de string2: %d byte(s)\n",sizeof(string2));
printf("String1: [%s]\nString2: [%s]\n",string1,string2);

printf("\nFIM!");
getchar();
return 0;
}
#include <stdio.h>

Talvez dê para ver o que quero dizer.

Ainda não entendi Friend T_T. Só se for que o tamanho de uma cadeia de caracteres vai ser seu tamanho em bytes, porque cada caractere é 1 byte?? E já um ponteiro para caractere é 4 bytes, independente do tanto de caracteres nesse ponteiro vai ser sempre 4 bytes? O.O Era isso o que você quis dizer?

Edit:

Pergunta:

string4=malloc(10*sizeof(char));

Nessa parte você alocou para o ponteiro de caractere string4 o tamanho de um caractere * 10?? Ou seja, é como se abrisse espaço para uma string de 10 caracteres nele? Pois você alocou 10 bytes ali né?

Editado por cuccate

Compartilhar este post


Link para o post
Compartilhar em outros sites
Ainda não entendi Friend T_T. Só se for que o tamanho de uma cadeia de caracteres vai ser seu tamanho em bytes, porque cada caractere é 1 byte?? E já um ponteiro para caractere é 4 bytes, independente do tanto de caracteres nesse ponteiro vai ser sempre 4 bytes? O.O Era isso o que você quis dizer?

Sim, UM caracter ocupa UM byte na memória. (ASCII)

Um vetor de caractere ocupará tantos bytes quanto for a quantidade de caracteres que deve armazenar.

Um ponteiro simplesmente armazena endereços de memória...

Quando se declara:

char *nome;

Você simplesmente declarou um ponteiro que armazenará o endereço de UM caracter.

(O conceito de string é array de caracteres, então só se precisa saber onde está o primeiro)

Note que esse ponteiro contém lixo de memória já que você não o inicializou, se você mandar gravar algo nesse endereço, você simplesmente corre o risco de acessar trechos de memória não permitidos ou vai acabar sobreescrevendo trechos de memória de outras variáveis ou se outro programa...

Sem falar que seu ponteiro não é constante, uma vez alterado seu valor você não sabe mais voltar a apontar para a string anterior...

Use este programa para ver isso:


{
char *teste1="teste";

printf("String antes: [%s]\n",teste1);
printf("Endereco antes: [%p]\n",teste1);

teste1=malloc(20*sizeof(char));
strcpy(teste1,"palavra maior");

printf("String depois: [%s]\n",teste1);
printf("Endereco depois: [%p]\n",teste1);

free(teste1);
getchar();
return 0;
}
int main()

Sim, ponteiro declarados como char nome[]="blabla"; e char nome2[30]; são constantes, tente alterar o endereço deles que você vai ver o compilador não deixar.

Edit:

Pergunta:

string4=malloc(10*sizeof(char));

Nessa parte você alocou para o ponteiro de caractere string4 o tamanho de um caractere * 10?? Ou seja, é como se abrisse espaço para uma string de 10 caracteres nele? Pois você alocou 10 bytes ali né?

Sim, cabem 10 caracteres. =]

O funcionamento de malloc é o seguinte (de maneira simples):

[B]nome[/B]=[COLOR="Red"]malloc[/COLOR](10*sizeof(char));

Funcionamento:

malloc: "-Sistema, tem 10 bytes contínuos de memória aí???"

sistema: "-Tem, reservei já para você, toma aqui o endereço do primeiro elemento"

malloc: "-beleza, valeu aê amigo! Nome, esse é o endereço do primeiro elemento"

nome: "-Opa! beleza, gravei aqui."

Lembrando que tem que liberar a memória quando não precisar mais, usando free(nome);

Editado por SharaMoustache

Compartilhar este post


Link para o post
Compartilhar em outros sites

SharaMoustache e cuccate, obrigado pela ajuda e pela aula de programação, com este debate de vocês deu para ter um pouco mais de noção a respeito. Bom começo de semana para vocês e Obrigado

Compartilhar este post


Link para o post
Compartilhar em outros sites
Sim, UM caracter ocupa UM byte na memória. (ASCII)

Um vetor de caractere ocupará tantos bytes quanto for a quantidade de caracteres que deve armazenar.

Um ponteiro simplesmente armazena endereços de memória...

Quando se declara:

char *nome;

Você simplesmente declarou um ponteiro que armazenará o endereço de UM caracter.

(O conceito de string é array de caracteres, então só se precisa saber onde está o primeiro)

Note que esse ponteiro contém lixo de memória já que você não o inicializou, se você mandar gravar algo nesse endereço, você simplesmente corre o risco de acessar trechos de memória não permitidos ou vai acabar sobreescrevendo trechos de memória de outras variáveis ou se outro programa...

Sem falar que seu ponteiro não é constante, uma vez alterado seu valor você não sabe mais voltar a apontar para a string anterior...

Use este programa para ver isso:


{
char *teste1="teste";

printf("String antes: [%s]\n",teste1);
printf("Endereco antes: [%p]\n",teste1);

teste1=malloc(20*sizeof(char));
strcpy(teste1,"palavra maior");

printf("String depois: [%s]\n",teste1);
printf("Endereco depois: [%p]\n",teste1);

free(teste1);
getchar();
return 0;
}
int main()

Sim, ponteiro declarados como char nome[]="blabla"; e char nome2[30]; são constantes, tente alterar o endereço deles que você vai ver o compilador não deixar.

Sim, cabem 10 caracteres. =]

O funcionamento de malloc é o seguinte (de maneira simples):

[B]nome[/B]=[COLOR="Red"]malloc[/COLOR](10*sizeof(char));

Funcionamento:

malloc: "-Sistema, tem 10 bytes contínuos de memória aí???"

sistema: "-Tem, reservei já para você, toma aqui o endereço do primeiro elemento"

malloc: "-beleza, valeu aê amigo! Nome, esse é o endereço do primeiro elemento"

nome: "-Opa! beleza, gravei aqui."

Lembrando que tem que liberar a memória quando não precisar mais, usando free(nome);

Man, o que é esse "lixo"?

No programa deu erro mesmo =D.

Uma pergunta, algo vai mudar o endereço do ponteiro??Tipo o malloc pode mudar o endereço ou simplesmente vai liberar + espaço para ele?? E mais uma coisa, essas funções de alocação dinâmica, quais são os usos? Eu só uso elas com ponteiro??

E ainda, MUITO OBRIGADO pela atenção ai cara =D

Compartilhar este post


Link para o post
Compartilhar em outros sites
Man, o que é esse "lixo"?

No programa deu erro mesmo =D.

O esquema do lixo se deve a questões de performance e de gasto energético da memória.

Quando um programa fecha, a memória utilizada por ele sai direto de "reservada para o programa x" para "memória disponível", ou seja, o sistema não apaga os valores contidos naqueles trechos de memória, eles continuam lá mesmo após fechar o programa.

Afinal, tirando questões de segurança de dados extrema, não tem porque gastar energia nem perder tempo apagando todos os valores e tal...

Quando você declara uma variável assim:

int x;

Você só reservou um espaço de memória para ela, mas não atribuiu nenhum valor!

Se você mandar imprimir você vai ver que vai aparecer algum lixo na tela.

Que tanto pode ser resquício de outro programa quanto valores aleatórios surgidos na ativação do chip de memória.

Por isso que em ponteiros é um problema pior...

Primeiro que, se você não o inicializou, você nem sabe para onde ele está apontando. Se for um endereço inválido, provavelmente só fai dar um erro e fechar. Mas se o endereço for válido, você vai correr o risco de mudar valores de outras variáveis ou comprometer o funcionamento de outros programas que estejam utilizando, nenhuma das duas opções é boa! aoheoaehoa xD

Uma pergunta, algo vai mudar o endereço do ponteiro??Tipo o malloc pode mudar o endereço ou simplesmente vai liberar + espaço para ele??

1- Endereço DO ponteiro é um só... Afinal ele também é uma variável e tem um espaço próprio na memória.

Agora o endereço CONTIDO pelo ponteiro, esse sim, pode mudar.

Malloc só retorna um NOVO endereço que corresponde ao primeiro byte do total que você mandou reservar.

Se você atribui o resultado de malloc a um ponteiro, o endereço contido por ele é simplesmente sobreescrito e você perde a referência para o endereço que ele continha antes.

Na verdade não se "libera mais espaço para um ponteiro"...

Mas para explicar direito eu precisaria de mais tempo (to saindo para uma aula =P)

Mas enfim tem como aumentar o trecho de memória apontado sim, mas a função que faz isso é realloc.

Exemplo:

int *vetor=NULL;
vetor=realloc(vetor,10*sizeof(int));
/* Temos aqui um vetor de vai de vetor[0] a vetor[9] =]
"Ahh, mas agora eu preciso de 20! */
vetor=realloc(vetor,20*sizeof(int));
/* Pronto, agora temos de vetor[0] a vetor[19]! */

Realloc faz o seguinte:

Ela verifica se tem espaço livre para mais 10 inteiros após o vetor[9]

Se tiver, ela só reserva e retorna o mesmo endereço.

Se não tiver, ela acha na memória um trecho contínuo onde caibam 20 inteiros, copia os 10 anteriores para os novos endereços, libera a memória que estavam usando antes e retorna o novo endereço do primeiro elemento.

Ou seja, usando realloc para aumentar o vetor, você nunca perde dados!

Agora se usar para reduzir, vai perder...

E mais uma coisa, essas funções de alocação dinâmica, quais são os usos? Eu só uso elas com ponteiro??

E ainda, MUITO OBRIGADO pela atenção ai cara =D

Alocação dinâmica é sempre com ponteiro!

Mas como falei tenho que sair agora, se der tempo no meio da aula eu posto os usos, se não fica para depois.

Abraço

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ok, brigadão mesmo cara =D

Edit:

Tentei fazer um código ai, pra ver essas coisas de malloc e realloc, tentei fazer em C++ deu uns erros ai "invalid conversion from void* to int*" O.O, em C foi =D



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

int main()
{

int* v;
v=malloc(10*sizeof(int));
v[0] = 1;
printf ("vetor[0] = %d", v[0]);
v=malloc(5*sizeof(int));
printf ("\nvetor[0] = %d", v[0]);
v[0] = 1;
printf ("\nvetor[0] = %d", v[0]);
v=realloc(v,5*sizeof(int));
printf ("\nvetor[0] = %d", v[0]);
free(v);
getch();
return 0;
}

Olha...Isso ai que eu fiz:

1 - Declarei ponteiro para um inteiro.

2 - Com o malloc, reservei 10*sizeof(int) bytes de memoria pra ele, é isso?Como se tivesse feito um vetor[10] de inteiro?

3 - Ao v[0] coloquei o valor de 1.

4 - Fiz o malloc de novo, agora uma dúvida ele pegou um novo endereço na memória e v[0] mostrou um valor totalmente diferente, mas ele reservou MAIS 5*sizeof(int), como se ele fosse agora v[15] ou agora ele apagou o que reservei antes e agora o meu ponteiro, é como se fosse um v[5]??

5 - Dei a o v[0] o valor de 1.

6 - Fiz o realloc e continou o valor de 1 \O/

7 - O que esse realloc fez? O.O

Editado por cuccate

Compartilhar este post


Link para o post
Compartilhar em outros sites
Ok, brigadão mesmo cara =D

Edit:

Tentei fazer um código ai, pra ver essas coisas de malloc e realloc, tentei fazer em C++ deu uns erros ai "invalid conversion from void* to int*" O.O, em C foi =D

Em C++ é new que aloca memória e delete libera...

Esse warning (não é erro, pelo menos não deveria ser) do void é porque por definição malloc retorna um ponteiro para qualquer coisa, ou seja, void *.

Nunca vi necessidade real de se fazer o cast (int *), mas se você colocar o erro provavelmente some.


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

int main()
{

int* v;
v=malloc(10*sizeof(int)); [B][COLOR="Red"]/* Suponha que malloc retornou o endereço E1 aqui */[/COLOR][/B]
v[0] = 1;
printf ("vetor[0] = %d", v[0]);
v=malloc(5*sizeof(int)); [B][COLOR="Red"]/* Suponha que malloc retornou o endereço E2 aqui */[/COLOR][/B]
printf ("\nvetor[0] = %d", v[0]);
v[0] = 1;
printf ("\nvetor[0] = %d", v[0]);
v=realloc(v,5*sizeof(int)); [B][COLOR="Red"]/* Suponha que realloc retornou o endereço E3 aqui */[/COLOR][/B]
printf ("\nvetor[0] = %d", v[0]);
free(v);
getch();
return 0;
}

Olha...Isso ai que eu fiz:

1 - Declarei ponteiro para um inteiro.

Beleza.

2 - Com o malloc, reservei 10*sizeof(int) bytes de memoria pra ele, é isso?Como se tivesse feito um vetor[10] de inteiro?

Sim, é exatamente isso.

3 - Ao v[0] coloquei o valor de 1.

4 - Fiz o malloc de novo, agora uma dúvida ele pegou um novo endereço na memória e v[0] mostrou um valor totalmente diferente, mas ele reservou MAIS 5*sizeof(int), como se ele fosse agora v[15] ou agora ele apagou o que reservei antes e agora o meu ponteiro, é como se fosse um v[5]??

você chamou malloc a primeira vez e obteve E1, e gravou 1 na primeira posição.

Quando você chama malloc a segunda vez, voce sobreescreveu E1 com E2, ou seja, você não tem como mais liberar o trecho de memória cujo início é apontado por E1... E agora você tem um vetor de v[0] a v[4]...

5 - Dei a o v[0] o valor de 1.

6 - Fiz o realloc e continou o valor de 1 \O/

7 - O que esse realloc fez? O.O

Fez isso:

Como você mandou realocar para a mesma quantidade, é bem provável que E3 seja igual a E2, ou seja, não fez nada...

Mas se tivesse tentado alocar para mais de 5 ele iria verificar se existem bytes livres suficientes após v[4], se existirem, ele só reserva e retorna o mesmo endereço.

Se não existirem, ele vai procurar outro trecho de memória que tenha uma quantidade contínua de bytes que você pediu, reservar esse espaço, copiar para o novo trecho de memória todos os valores que estavam salvos no trecho antigo, liberar a memória do trecho antigo e retornar o novo endereço do primeiro elemento.

Editado por SharaMoustache

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então o MALLOC sempre vai dar o mesmo endereço, e no caso do realloc ele vai copiar os VALORES do E2 para o E3, por exemplo se fosse:


...
v=realloc(v,10*sizeof(int));
...

Esse que era de v[0] a v[4], agora ele vai ser quanto?? Agora vai ser v[0] a v[9]?? E nesse caso ele copia os endereços do E2 pro E3 e não sobreescreve o E3 no E2, certo??

Em C++, só vai ser esses 2 só? new e delete e como seriam os usos dele, e dos outros, malloc, realloc??

Compartilhar este post


Link para o post
Compartilhar em outros sites
Então o MALLOC sempre vai dar o mesmo endereço,

Não... Cada malloc vai retornar um endereço diferente.

O que eu falei é que v era de 5 inteiros e você usou realloc para 5, ou seja, a mesma quantidade, nesse caso, realloc retornaria o mesmo endereço, pois nenhuma mudança precisa ser feita.

e no caso do realloc ele vai copiar os VALORES do E2 para o E3, por exemplo se fosse:


...
v=realloc(v,10*sizeof(int));
...

Esse que era de v[0] a v[4], agora ele vai ser quanto?? Agora vai ser v[0] a v[9]?? E nesse caso ele copia os endereços do E2 pro E3 e não sobreescreve o E3 no E2, certo??

Sim, v vai de 0 a 9 agora.

Cara, qualquer atribuição é uma sobrescrita...

int i=10;
i=5; /* Sobreescrevi 10 com 5! */

O que eu falei de sobreescrever é o seguinte:

v=malloc(10*sizeof(int));
/* Neste ponto v=E1 */
(...)

v=malloc(5*sizeof(int)); /* Aqui você sobreescreveu E1 com E2 sem liberar E1...*/
/* Neste ponto v=E2 */

(...)

v=realloc(v,10*sizeof(int)); /* Aqui você sobreescreveu E2 com E3, mas realloc liberou a memória utilizada por E2, então não tem problema! =] */
/* Neste ponto v=E3 */

Em C++, só vai ser esses 2 só? new e delete e como seriam os usos dele, e dos outros, malloc, realloc??

Ainda não vi o equivalente a realloc...

Só o new e o delete que são bem parecidos com malloc e free...

Ó: http://www.cplusplus.com/reference/std/new/

-

Editado por SharaMoustache

Compartilhar este post


Link para o post
Compartilhar em outros sites
Não... Cada malloc vai retornar um endereço diferente.

O que eu falei é que v era de 5 inteiros e você usou realloc para 5, ou seja, a mesma quantidade, nesse caso, realloc retornaria o mesmo endereço, pois nenhuma mudança precisa ser feita.

Sim, v vai de 0 a 9 agora.

Cara, qualquer atribuição é uma sobrescrita...

int i=10;
i=5; /* Sobreescrevi 10 com 5! */

O que eu falei de sobreescrever é o seguinte:

v=malloc(10*sizeof(int));
/* Neste ponto v=E1 */
(...)

v=malloc(5*sizeof(int)); /* Aqui você sobreescreveu E1 com E2 sem liberar E1...*/
/* Neste ponto v=E2 */

(...)

v=realloc(v,10*sizeof(int)); /* Aqui você sobreescreveu E2 com E3, mas realloc liberou a memória utilizada por E2, então não tem problema! =] */
/* Neste ponto v=E3 */

Ainda não vi o equivalente a realloc...

Só o new e o delete que são bem parecidos com malloc e free...

Ó: http://www.cplusplus.com/reference/std/new/

-

Sobre o MALLOC, eu que digitei errado, não era pra sair "mesmo endereço" :P. Cara, sério...Muito obrigado pela sua atenção e tempo ai...Desculpe o incômodo =D

Compartilhar este post


Link para o post
Compartilhar em outros sites

Tivemos uma aula muito boa sobre malloc, realloc.... agradeço ao cuccate e a SharaMoustache por nos proporcionar isto, alem da ajuda num todo.

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
Entre para seguir isso  





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

×