Archive for Outubro, 2007

Entendendo ponteiros e a função malloc

Bem, algum tempo atrás estava eu brincando com C criando uma função para retornar todos os números primos menores do que um determinado número, e eu queria que a função cria-se o vetor com os primos e passa-se para main, mas para fazer isso precisava entender um pouco melhor essa tecnologia estranha, malloc e conseqüentemente: ponteiros e a função free().

Vamos começar pelos ponteiros. Declarando ponteiros:

int *ponteiro;

Bem simples, só colocar um asterisco na frente do nome da variável e temos um ponteiro, próximo passo, entender como ele funciona.

Um ponteiro aponta, quem aponta, aponta para algo, um ponteiro aponta para uma variável, desse jeito:

ponteiro = &variavel;

Pronto, nosso ponteiro já tem para quem apontar(quando o ponteiro é iniciado ele aponta para algum lugar aleatório da memória) ou em outras palavras, o nosso ponteiro tem uma referência para a variavel:

ponteiro -> variavel

Mas agora, por que do “&”? Bem, uma variável armazena conteúdo, o conteúdo é armazenado na memória principal do computador(ram), e para se saber onde que esta armazenado o valor da variável na memória ram “nós”(o computador) temos que saber aonde que a variável esta na memória, para isso existe uma tabela, na própria memória ram, com o nome da variável e o endereço da mesma(rua, bairro, telefone, essas coisas assim =D), e em C, o endereço de uma variável é:

&variavel;

Depois que nós apontamos para a variável nós podemos modifica-la, mas não com essa sintaxe:

ponteiro = 5;

Afinal, o valor do ponteiro é o endereço na memória da variável para que ele esta apontando, se nós usarmos essa sintaxe acima, nós mudaremos para quem se aponta, não o valor de quem se aponta, aqui entra a segunda sintaxe:

*ponteiro = 5;

Pronto, problema resolvido, agora conseguimos modificar o valor para quem se aponta sem maiores problemas.

Uma revisãozinha antes de continuar, nós declaramos um ponteiro usando um asterisco na frente do nome do ponteiro(int *ponteiro;) o valor do ponteiro é um endereço de memória (ponteiro = &variavel;) e a partir do ponteiro nos conseguimos modificar o valor da variável para a qual se aponta(*ponteiro = 5;).

Aleluia, terminamos os ponteiros, agora podemos entender a função malloc:

#include <stdlib.h>
void *malloc(size_t size);

Bem, acima temos o protótipo da função e o include para a biblioteca que contem a função, o que para mim não faz nenhum sentido sem exemplo, então vamos para o exemplo:

ponteiro = (int *)malloc (sizeof(int)*5);

Ali nós tivemos que usar uma segunda função, sizeof() – ela passa o tamanho em bytes de um tipo de dados, no caso é um inteiro porque o nosso ponteiro é um ponteiro para inteiros (int *ponteiro;), para armazenar a quantidade correta de bytes , depois o valor de bytes é multiplicado por 5, que é o número de casas que eu quero para o vetor, a função vai alocar esse espaço na memória e passar o endereço da memória que é atribuído ao ponteiro, simples assim.

Agora algumas notas:
A parte no membro direito na frente da palavra malloc “(int *)” não é obrigatória para todos os compiladores, porem, mesmo se não for necessário no compilador que você usa é uma boa pratica coloca-lo no código aumentando a compatibilidade entre C e C++ e não irá resultar em erro em outros compiladores.
A função malloc não “oferece” uma variável do tamanho desejado, ela oferece um vetor do tamanho desejado(dentro de certos limites físicos[a memória ram]), tamanho que é igual ao número que está multiplicando(no caso 5), e ela não é infalível, infelizmente memória acaba, então é sempre uma boa pratica testar se o valor do ponteiro é diferente de NULL, afinal de contas, não queremos nenhum problema com os nossos programas:

intenger = (int *)malloc(sizeof(int)*5);
if(intenger == NULL){
exit(EXIT_FAILURE);
}

Outra nota importante, ponteiros apontam para variáveis, não para vetores, e isso trás uma importante implicação, o valor da memoria passado pela função malloc é o endereço do índice zero do vetor, então nós temos o seguinte:

ponteiro = vetor[0]
ponteiro + 1 = vetor[1]
ponteiro + 2 = vetor[2]
ponteiro + 3 = vetor[3]
ponteiro + 4 = vetor[4]

Assim quando você quiser modificar o próximo índice no vetor de usar a seguinte sintaxe:

*(ponteiro + 1) = 5;

Isso é chamada de aritimética de ponteiros, o compilador deve saber que o ponteiro é um inteiro, pela sua declaração, assim ele sabe qual é o tamanho em bites do seu inteiro – valor esse que eu não vou mencionar, pois é diferente de arquitetura para arquitetura – assim quando se adiciona 1 ao ponteiro, o compilador sabe que se deve pular o equivalente ao tamanho de um inteiro a partir do primeiro valor, chegando ao segundo:

——————————–V int + 1————
|0101110110110110|0111010101111011|
^ int————————————————

Isso trás algumas coisas a tona, cuidado com a aritimética de ponteiros, pois se você tiver um vetor de 3 casas, e somar 3 ao ponteiro, você ira tentar acessar memória, talvez, restrita e resultara em um erro, segundo ponto a se notar é que a memoria alocada pelo malloc é continua, por isso a aritmética de ponteiros funciona.

Bem, agora nós já sabemos como usar os ponteiros e a função malloc(), agora temos mais três passos, entender a função free(), entender passagem por referência e por fim, a minha função primos() no próximo post.

5 comments 9 Outubro 2007

Passa-tempo geek

resolver problemas com auxílio de programas(que voce vai desenvolver, claro):

www.projecteuler.net

divirta-se

1 comment 9 Outubro 2007

Ouvindo musica!

Já falei de como se descobrir novas bandas, agora precisamos de uma maneira para se ouvir, e é aqui que entra esse site:

http://www.seeqpod.com/

muito bom, voce procura por uma música ou banda ele exibe uma lista de resultados e você adiciona a uma playlist, bem simples, fácil e útil, mas precisa de flash.

achado em: http://www.produzindo.net/

Add comment 9 Outubro 2007

Groovle

Site interessante que permite colocar qualquer imagem de fundo na pagina de busca, com algumas interessantes opcoes

1 comment 5 Outubro 2007


 

Outubro 2007
S T Q Q S S D
« Jul   Dez »
1234567
891011121314
15161718192021
22232425262728
293031  

Principais mensagens

Tópicos recentes

Feeds