Logo Hardware.com.br
palominha
palominha Membro Senior Registrado
246 Mensagens 0 Curtidas

Função Malloc

#1 Por palominha 18/03/2006 - 23:23
Tenho o exercício de alocação dinâmica abaixo, mas ñ compila, será que alguém pode me dar uma ajuda, eu já olhei e olhei e não encontro o problema.

#include <stdio.h>

#include <stdlib.h>

void

main()

{

float *v, n, i;

printf ("Entre com a quantidade de valores do vetor: &quot;

scanf("%d",&n);

v = (float*) malloc (n * sizeof(float));

for (i = 0; i < n; i++)

{

printf ("Valor %d: ", i + 1);

scanf("%f",&v[i]);

}

free(n);

system("PAUSE&quot;

return(0);
}
peczenyj
peczenyj Geek Registrado
3K Mensagens 75 Curtidas
#6 Por peczenyj
19/03/2006 - 10:17
warning: `float' used for argument 1 of `malloc(unsigned int)'

Em primeiro lugar isto é um warning, não necessariamente um erro. É uma mensagem de alerta do tipo "bah, cuidado q uma hora a coisa vai ficar feia!"

Em segundo lugar a função malloc foi definida como sendu uma função que tem como argumento um 'unsigned int'. Isto por que vc aloca um número inteiro e positivo de bytes. Vc não pode alocar 1/2 byte ou -5 bytes. Por via das dúvidas, defina n como um 'unsigned int' pois mesmo se vc fizer um cast explicito, ainda terá esta mensagem e teras um erro se alguem informar um numero negativo.

o unsigned é uma palavra chave que, sendo informado em uma declaração de variavel inteira, altera as propriedades da variavel inteira com relação aos seus valores maximos e minimos. Um inteiro vai de -32 mil e pouco até + 32 mil e pouco, mas um inteiro unsigned vai de 0 até 64 mil e tanto -- pois vc não usa um bit para informar se é positivo ou negatico mais, pode usar como numero mesmo...

Dê uma pesquisada sobre isso, vai achar interessante.
peczenyj
peczenyj Geek Registrado
3K Mensagens 75 Curtidas
#8 Por peczenyj
19/03/2006 - 10:24
substitua

scanf("%f",&v[i]); 


por

float temp; //definindo variavel temporária
...
scanf("%f",&temp);
v[i] = temp;


O erro acontece por causa de ponteiros... tem como contornar mas agora é mais rapido vc usar uma variavel temporária.

O que acontece é o seguinte: em C vc pode trabalhar com ponteiros para variaveis, que nada mais são que variaveis que guardam um endereço na memória para estas variaveis. É um atalho, por assim dizer.

por que vc faz scanf("...",&variavel); e não algo do tipo
variavel = scanf("...."); ?

Existem funções que retornam caracteres digitados pela segunda forma, entretanto se vc quiser ler mais de uma variavel, tens um problema. Muita gente se habitua a usar somente o scanf, assim como o printf, então usam da primeira forma e todo mundo vive feliz.

A forma como o scanf trabalha, vc informa como ARGUMENTO as variaveis que vc quer que recebam informações/valores. Entretanto vc vai ver no decorrer dos estudos de C algumas coisas interessantes.

Se vc tem uma função chamada 'triplo' e esta recebe um numero e imprime o seu resultado multiplicado por 3, por exemplo, e declara assim:

void triplo(int a){
a = a * 3; // ou notação compacta a *= 3;
printf("%d\n"a);
}


e fizer assim
  int a=4;
printf("%d\n"a);
triplo(a);
printf("%d\n"a);


isto imprime 4, 12, 4. Isto por que o fato de vc multiplicar o valor de a dentro da função triplo é irrelevante, a variavel a foi copiada para dentro da função, uma vez que 'triplo' termine, não tem mais referencia para esta variavel... ela não se comunica pra fora.

Mas em 2 casos vc pode fazer essa comunicação: ou vc declara 'a' como uma variavel global, declarando fora do main(), ou passa o ponteiro para a variavel a.

De posse do ponteiro para uma variavel, a variavel pode ser acessada de qq lugar, pode qq função, e ter o seu valor alterado em qq momento. É o que acontece dentro de scanf. Vc passa o endereço da variavel que vc quer que receba o valor e o scanf pega essa variavel , atraves do endereço, e altera o valor dela para o que vc quer. Vc passa o endereço atraves do operador unario &.

Quando vc trabalha com matrizes, o nome da matriz sem colchetes ja é um ponteiro, então vc não precisa (nem pode) fazer &matriz[indice].
matriz ja é um ponteiro.

Ponteiros não são nada obvios de se trabalhar -- a notação do C é muito ruim, são um recurso que pode acabar em varios problemas se o programador não sabe o que faz. Se vc quer aprender bem tem que praticar muito, mas muito mesmo. Um bom programador pratica, estuda, tenta, e erra bastante. Não da pra se contentar em fazer só 2 programinhas por semana e fazer apenas o que o professor manda fazer... tem que procurar mais, incrementar os programas, usar indentação, comentarios, nomes de variaveis bem sugestivos (pra que variaveis v, a, n ? depois de um tempo vc não sabe qual é qual...), isso se vc quiser aprender. Não desista, as recompensas são imensas !
peczenyj
peczenyj Geek Registrado
3K Mensagens 75 Curtidas
#12 Por peczenyj
19/03/2006 - 11:00
Ah , experimente declarar o seu main como

int main (void)

Pois vc colocou um return em uma função (o main é uma função) que não retorna 'nada'. A ideia do return no main é vc informar o sistema operacionar como o programa terminou. Existe uma convenção que 0 significa "eita, terminou q é uma beleza" e valores diferentes "tem algo errado". Vc coloca o return (0); no final pois, se o programa chega no final, então ocorreu tudo bem, mas se no meio deu alguma coisa errada, vc pode fazer um exit(x); onde x é o codigo de retorno.

Na pratica altera alguma coisa ? Não... mas se alguem dia vc quiser ver se o programa funcionou 100% ou aconteceu algum problema, vc pode ver no linux, por exemplo, o valor da variavel '$?' que mostra esse tipo de informação. Exemplo classico é usar funções que manipulam arquivos. Se o arquivo não existe, vc pode ter um ponteiro nulo para um arquivo potencialmente perigoso. Se vc aborta o programa caso não consiga ler um arquivo -- ele pode não existir -- podes fazer isso informando um codigo 1, por exemplo (ou criar o seu codigo, para o seu proprio uso).

Isso vale pra unix's... mas é uma boa pratica... programação se faz com boas praticas -- indentar o codigo e usar comentarios também!
peczenyj
peczenyj Geek Registrado
3K Mensagens 75 Curtidas
#14 Por peczenyj
19/03/2006 - 13:01
Antigamente eu escrevi:
é que vc não pode fazer &v[i], pois v é uma matriz.

Errado, pode fazer.... confundi com strings...

Agora v é uma matriz sim, um vetor é uma matriz unidimensional. E não é dinamico, pois vc aloca um tamanho para ela em um dado momento (com as funções de alocação dinâmica). No meu entendimento uma matriz dinâmica altera o seu tamanho conforme a necessidade, como em linguagens scripts como Perl, Ruby, *nix Shell.

Em C algumas vezes é dito que a Matriz é dinâmica mas é referencia ao fato ela ter sido alocada dinamicamente em algum momento, por um comando específico. IMHO são conceitos diferentes.

http://www.mtm.ufsc.br/~azeredo/cursoC/aulas/ca70.html

Respondendo o por que desse erro: vc não pode usar uma variavel não inteira como indice de uma matriz. Só serve inteiros, no seu codigo isso não acontece, veja depois um codigo q funciona.
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal