Buscar

Ponteiros em C: um resumo básico

Prévia do material em texto

FUNDAÇÃO UNIVERSIDADE FEDERAL DO VALE DO SÃO FRANCISCO 
UNIVASF 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Ponteiros em C: um resumo básico 
 
 
 
 
 
 
 
 
 
 
 
Igor França 
Engenharia de Computação 
 
 
 
 
 
Juazeiro, BA 
Julho de 2013 
Fundação Universidade Federal do Vale do São Francisco 
 
 
3 
PONTEIROS 
 
1 Definição 
Ponteiros são variáveis — assim como int, char etc — que contêm endereços de memória — 
normalmente a posição de outra variável de mesmo tipo. 
 
2 Declaração 
tipo *nome; 
A variável nome irá conter um ponteiro de tipo base tipo. A variável só poderá designar para 
outras de seu mesmo tipo, de acordo com a aritmética de ponteiros¹. 
A imagem a seguir ilustra o uso de uma variável ponteiro 
 
 
Figura 1: variável apontando para outra 
 
3 Operadores 
Há duas operações básicas de ponteiros: * e &. O & devolve o endereço na memória 
de seu operando. Por exemplo 
x = &example; 
Põe, em x, o endereço de memória da variável que contém example. Então, se example 
está na posição 81 de memória e tem valor 10, x terá o valor 81. Já o operador * funciona para 
devolver o valor da variável localizada no endereço que ele aponta. Daí 
y = *x; 
Ponteiros em C 
 
 
 
4 
Logo, y receberá o valor 10, porque é o valor que está armazenado na posição 81, que 
x armazenava. 
 
4 Indireção Múltipla 
Pode-se ter um ponteiro apontando para outro ponteiro que aponta para o valor final. 
Vale ressaltar que indireção múltipla difere de lista ligada², pois são conceitos diferentes. 
A indireção múltipla pode ser levada a qualquer nível, porém, é complexa de seguir e 
sujeita a erros. Dificilmente é necessário uso de várias indireções. Para se declarar uma 
variável ponteiro para ponteiro deve ser declarada usando-se mais um * a frente do nome da 
variável, ou seja: 
tipo **nome; 
 Ou seja, a variável nome de como tipo básico tipo irá apontar para um ponteiro de 
ponteiro de mesmo tipo básico. Exemplo 
 
1. float x 
2. float *p; 
3. float **q; 
4. 
5. x = 10.0; 
6. p = &x; 
7. q = &p; 
8. 
9. printf(“&p = %d = p = %d”, &p, q); 
10.printf(“**p = %f = x = %f”, **p, x); 
 
No código acima, primeiramente, após as declarações, são feitas as atribuições de 
valores: x recebe 10.0 (float), p recebe o endereço de x e q recebe o endereço para que p 
aponta. Na tela será possível verificar que o endereço de p é igual à variável q – ponteiro para 
ponteiro, e que x tem o mesmo valor que q. 
 
5 Ponteiros para Funções 
Quando cada função é compilada, é criado um código-objeto a partir do código-fonte, e um é 
estabelecido um ponto de entrada. No momento que a função é chamada, é efetuada uma chamada ao 
ponto de entrada, ao tempo que o programa é executado. Logo, se um ponteiro contém esse valor de 
entrada da função, ele pode ser utilizado para chamar a função. 
Analise o código a seguir para melhor entendimento 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. #include <string.h> 
4. //-------------------------------------------------------------------------- 
5. void checar(char *a, char *b, int (*cmp)(const char *, const char *)); 
Fundação Universidade Federal do Vale do São Francisco 
 
 
5 
6. //-------------------------------------------------------------------------- 
7. void main() 
8. { 
9. char x1[80], x2[80]; 
10. int (*p)(); 
11. 
12. p = strcmp; // strcmp() é a função da biblioteca string.h 
13. // que compara dois strings 
14. gets(x1, x2); 
15. checar(x1, x2, p); 
16. } 
17. //-------------------------------------------------------------------------- 
18. void checar(char *a, char *b, int (*cmp)(const char *, const char *)) 
19. { 
20. printf("testando igualdade"); 
21. 
22. if(!(*cmp)(a, b)) printf("strings iguais"); 
23. else printf("strings diferentes"); 
24. } 
 
É necessário o uso de parênteses em (*cmp) para o entendimento do termo como 
função, do compilador. 
 
6 Alocação Dinâmica 
Para o uso de alocação de memória em tempo de execução, quando a quantidade de 
espaço utilizado é desconhecida, é necessário que o programa efetue funções de operações 
dinâmicas, e aí onde entram as funções de alocação dinâmica. 
A memória de alocação é obtida do heap da máquina, e é desconhecido seu real 
tamanho. As principais funções para alocação em C são malloc( ) e free( ). Enquanto 
malloc() cria um espaço de memória para armazenamento dos parâmetros do código, free( ) 
libera. Para o uso dessas funções é necessário o uso da biblioteca stdlib.h. 
A declaração de malloc( ) é da forma 
void *malloc(size_t num_de_bytes); 
 
A função devolverá um ponteiro de tipo void, que assim, será possível ser utilizada 
qualquer espécie de ponteiro. Demos como exemplo 
 
1. char *p; 
2. p = malloc(100); 
 
Ponteiros em C 
 
 
 
6 
Logo, p apontará para os primeiros 100 bytes de memória livre. 
Ainda é possível usar sizeof para garantir a portabilidade 
1. int *p; 
2. p = malloc(10*sizeof(int)); 
 
Já a função free( ) pode ser usada, a partir da alocação de malloc( ), em uma 
declaração geral 
void free(void *p); 
 
Onde p é o ponteiro para a memória alocada anteriormente. 
Dado isso, podemos exemplificar com um código, tratando das duas funções: 
primeiramente, será alocado um valor, e, em seguida, ele será liberado. Segue 
1. #include <stdlib.h> 
2. #include <stdio.h> 
3. #define X 10 
4. //--------------------------------------------------- 
5. void alocar(int *p); 
6. void liberar(int *p); 
7. //--------------------------------------------------- 
8. int main() 
9. { 
10. int *p; 
11. 
12. alocar(p); 
13. liberar(p); 
14. return 0; 
15. } 
16. //--------------------------------------------------- 
17. void alocar(int *p) 
18. { 
19. p = malloc(sizeof(X)); 
20. 
21. if(p == NULL) printf("sem memoria\n"); 
22. else printf("alocado\n"); 
23. } 
24. //--------------------------------------------------- 
25. void liberar(int *p) 
26. { 
27. if(p != NULL) { 
28. free(p); 
29. printf("liberado\n"); 
30. } 
31. } 
Fundação Universidade Federal do Vale do São Francisco 
 
 
7 
6 Problemas com Ponteiros 
A medida que os ponteiros são de grande atribuição na linguagem, sua valia é imensa. 
Mas há problemas que comumente acontecem. O principal é o ponteiro selvagem. Quando 
não se é iniciado um ponteiro, ao iniciar a execução no programa, pode haver uma 
referenciação com uma variável contendo lixo. Isso pode ser imperceptível. É aí que está o 
problema: encontrar um erro em um ponteiro, sendo que talvez nem seja ele, em si, o erro, e 
sim, a forma que foi inicializada – ou não. 
Analise o código a seguir 
 
1. #include <stdio.h> 
2. #include <stdlib.h> 
3. //--------------------------------------------------- 
4. int main() 
5. { 
6. char *p; 
7. char s[50]; 
8. 
9. p = s; 
10. do{ 
11. gets(s); 
12. while(*p) printf(" %i", *p++); // imprime o valor ASCII para 
13. // cada caractere
14. } while(strcmp(s, "done")); 
15. } 
 
Nesse programa, p é utilizado para apresentar os valores ASCII para cada letra da 
palavra de entrada. Mas há um erro: p recebe somente o primeiro valor de s, logo, após o 
primeiro laço, serão apresentados valores quaisquer, já contidos em memória.Ponteiros em C 
 
 
 
8 
REFERENCIAÇÃO 
 
¹ Em ponteiros só podem ser feitas somas e subtrações; 
² Para maiores informações sobre lista ligada, consulte o livro 
CORMEN, Thomas H.. Algoritmos: teoria e prática. Rio de Janeiro: Campus, 2002 
e os endereços: 
 http://pt.wikipedia.org/wiki/Lista_ligada 
 http://www.ime.usp.br/~pf/algoritmos/aulas/lista.html 
 http://www.lis.ic.unicamp.br/~mc102/files/lista-ligada-exercicio.pdf 
 
BIBLIOGRAFIA 
 
SCHILDT, Herbert. C Completo e Total. 3 ed. São Paulo, Pearson Makron Books. 
http://www.cplusplus.com/

Continue navegando