[CAPÍTULO 1] - [CAPÍTULO 2] - [CAPÍTULO 3]
[PARTE 1] - [PARTE 2] - [PARTE 3] - [PARTE 4] - [PARTE 5] - [PARTE 6] - [PARTE 7]
[PARTE 1] - [PARTE 2] - [PARTE 3] - [PARTE 4] - [PARTE 5] - [PARTE 6] - [PARTE 7]
Ponteiros
Conceito
Um PONTEIRO ou APONTADOR é uma variável usada para armazenar um endereço de memória.Normalmente, o endereço armazenado em um PONTEIRO é a posição de uma outra variável na memória. Se uma variável contém o endereço e uma outra, então a primeira variável é dita apontar para a segunda.
Declaração
De maneira geral, uma variável ponteiro de nomeID é declarada assim:ESPECIFICADORES * ID = INICIALIZADOR;onde, o
= INICIALIZADOR é opcional (como em toda declaração de variável).Operadores de Ponteiros
Existem dois operadores especiais para ponteiros: o* e o &.Operador &
Um operador unário que devolve o endereço na memória do seu operando.int m; int * p; p = &m; /* p recebe o endereço onde se localiza a var. m */ ...
Operador *
É o complemento de&. Quer dizer, devolve a variável localizada no endereço armazenado em um apontador.p = &m;
m = 3;
printf("%p", p); /* imprime o endereço de m */
printf("%d", *p); /* imprime 3 que é o conteúdo de m */
...
Ponteiros e Arranjos
Há uma estreita relação entre PONTEIROS e ARRANJOS (vetores, matrizes e strings).O nome de um ARRANJO (vetor, matriz ou string) é sempre um PONTEIRO para o primeiro elemento do ARRANJO.
char str[80], *pstr; pstr = str; /* pstr aponta para str[0] */
Assim, a décima posição de um ARRANJO (vetor, matriz ou string) pode ser acessada de duas maneiras:
pstr = str; /* pstr aponta para str[0] */
printf("%c", str[9] ); /* imprime o 10o elemento de str */
printf("%c",*(pstr + 9)); /* imprime o 10o elemento de str */
Aritmética de Ponteiros
Existem apenas duas operações aritméticas que podem ser usadas com ponteiros: adição e subtração.Cada vez que um ponteiro é incrementado, ele aponta para a posição de memória do próximo elementodo seu tipo base.
Cada vez que um ponteiro é decrementado, ele aponta para a posição de memória do elemento anterior.
Aplicações
O correto entendimento e uso de ponteiros é crítico para uma programação bem-sucedida em C. Há pelo menos três razões para isto:- ponteiros fornecem os meios pelos quais as funções podem modificar seus argumentos
- formam a base para a alocação dinâmica (variáveis no heap)
- aumenta a eficiência de certas rotinas
De agora em diante, até o final do curso, iremos explorar em variados graus de detalhes o conceito básico de ponteiros.
Atividade 1
Aplicando os conhecimentos adquiridos na última aula e nesta, iremos agora implementar uma primeira versão de uma lista de strings.Dado o código abaixo (que pode ser obtido como projeto Dev-Cpp neste link), complemente o código do arquivo
lista.c escrevendo as funções:-
list_rem() -
list_get() -
list_set()
main.c
/* main.c **/
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "xcpt.h"
int main(int argc, char *argv[])
{
while (1) {
char str[1024];
int pos;
const char * xc;
printf("\nAdicionar\n");
printf(" pos = "); scanf("%d",&pos);
printf(" str = "); gets(str); gets(str);
list_add(str,pos);
/*
TRY(list_add(str,pos));
CATCH(INDEX_OUT_OF_BOUNDS_XCPT,xc)
printf("\npos invalida!\n");
CATCH(LIST_FULL_XCPT,xc)
printf("\nlista cheia!\n");
CATCH(LINE_TOO_LONG_XCPT,xc)
printf("\nstr muito grande!\n");
*/
printf("\nLista\n");
list_print();
}
}
list.h, list.c
/* list.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #ifndef LIST_H #define LIST_H #define LIST_MAX_SIZE 99 #define LINE_MAX_SIZE 60 #define LIST_FULL_XCPT "list full" #define LINE_TOO_LONG_XCPT "line too long" unsigned short list_size(void); void list_add(const char * str, unsigned short pos); char * list_rem(unsigned short pos); void list_set(const char * str, unsigned short pos); char * list_get(unsigned short pos); void list_print(void); #endif
/* list.c, Rev. 1.1
(c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br>
Implements a list of strings.
**/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "list.h"
#include "xcpt.h"
/** private data */
static char list[LIST_MAX_SIZE][LINE_MAX_SIZE+1];
static unsigned short size = 0;
static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];
/** public functions */
unsigned short list_size(void) {
return size;
}
/*
Add a new element str in the list at a given position pos.
From pos to the end of the list, all existing elements are
shifted right.
Throws:
INDEX_OUT_OF_BOUNDS_XCPT when pos is invalid ( > size +1 )
LIST_FULL_XCPT when the list size equals LIST_MAX_SIZE
LINE_TOO_LONG_XCPT when str is greater than LINE_MAX_SIZE
**/
void list_add(const char * str, unsigned short pos) {
sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n",
__FILE__,__LINE__,str,pos);
if ( pos > size + 1 ) {
THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg);
return ;
}
if ( size + 1 > LIST_MAX_SIZE ) {
THROW(LIST_FULL_XCPT,xcpt_cmsg);
return ;
}
if ( strlen(str) > LINE_MAX_SIZE ) {
THROW(LINE_TOO_LONG_XCPT,xcpt_cmsg);
}
if ( pos == 0 ) {
strncpy(list[size],str,LINE_MAX_SIZE);
} else {
int i;
for ( i = size ; i >= pos; i-- )
strcpy(list[i],list[i-1]);
strncpy(list[i],str,LINE_MAX_SIZE);
}
size++;
}
char * list_rem(unsigned short pos) {
}
void list_set(const char * str, unsigned short pos) {
}
char * list_get(unsigned short pos) {
}
void list_print(void) {
int i;
for ( i=0; i < size; i++ )
printf("%2d: %s\n",i+1,list[i]);
}
xcpt.h, xcpt.c
/* xcpt.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #ifndef XCPT_H #define XCPT_H #define XCPT_NAME_MAX_SIZE 32 #define XCPT_CMSG_MAX_SIZE 1024 #define THROW(e,m) __throw((e),(m)) #define TRY(f) __begin_try();f;__end_try(); #define CATCH(e,m) if(m=__catch(e)) #define NULL_POINTER_XCPT "null pointer" #define INDEX_OUT_OF_BOUNDS_XCPT "index out of bounds" #define OVERFLOW_XCPT "overflow" #define UNDERFLOW_XCPT "underflow" #define ILLEGAL_ARGUMENT_XCPT "illegal argument" void __begin_try(void); void __end_try(void); const char * __catch(const char *name); void __throw(const char *name, const char *cmsg); #endif
/* xcpt.c, Rev. 1.1
(c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br>
Implements an exception handling mechanism inspired in Java.
**/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "xcpt.h"
static char xcpt_name[XCPT_NAME_MAX_SIZE + 1];
static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE + 1];
static int trying;
/*
Sets try_flag.
**/
void __begin_try(void) {
trying = 1;
}
/*
UnSets try_flag.
**/
void __end_try(void){
trying = 0;
}
/*
From exception name, gets the exception message thown by
__throw(n,m). Once cautch, the exception name is cleared .
**/
const char * __catch(const char * name) {
if ( strcmp(xcpt_name,name) == 0 ) {
xcpt_name[0] = '\0';
return xcpt_cmsg;
}
else
return NULL;
}
/*
Stores an exception contextual message.
When called outside a __begin_try(); ...; __end_try(); pair,
the exception message is also printed to the stderr stream .
**/
void __throw(const char * name,const char * cmsg) {
strncpy(xcpt_name,name,XCPT_NAME_MAX_SIZE);
strncpy(xcpt_cmsg,cmsg,XCPT_CMSG_MAX_SIZE);
if ( !trying )
fprintf(stderr,"exception: %s: %s\n",xcpt_name,xcpt_cmsg);
}
Leitura recomendada
- CCT Cap 5
Exercícios
Termine a atividade 1 acima, escrevendo as funções:-
list_rem() -
list_get() -
list_set()
Bibliografia e fonte:
- [CCT] Schildt, H. (1996) C, completo e total: 3a Ed.. São Paulo, Makron.
- LP, UFMA; Coutinho, Lucian. Linguagem de programação para ciencia da computação da ufma.http://www.deinf.ufma.br/~lrc/2009.1/LP/
- [K&R] KERNIGHAN, B. e RITCHIE, D. (1990) C, a linguagem de programação: padrão ANSI. Rio de Janeiro: Campus.
- DEITEL, H. M. (1999) Como programar em C. Rio de Janeiro: LTC.
- Módulo Consultoria e Informática (1989) Linguagem C: programação e aplicações. Rio de Janeiro: LTC.
Coloque aqui o seu email