22
1

Aula 2 - Ponteiros e Alocação Estática

Embed Size (px)

DESCRIPTION

o

Citation preview

Page 1: Aula 2 - Ponteiros e Alocação Estática

1

Page 2: Aula 2 - Ponteiros e Alocação Estática

Ponteiros e Alocação Estática

Prof. Maurício Scoton

[email protected]

Page 3: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• A linguagem C permite que o programador referencie a posição de objetos bem como os próprios objetos (isto é, o conteúdo de suas posições).

• Por exemplo, se x for declarado como um inteiro, &x se referirá à posição reservada para conter x. &x é chamado ponteiro.

Page 4: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• É possível declarar uma variável cujo tipo de dado seja um ponteiro e cujos possíveis valores sejam posições de memória. Por exemplo, as declarações:

– int *pi;

– float *pf;

– char *pc;

Page 5: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• São declarações de três variáveis ponteiros:

– pi é um ponteiro para um inteiro;

– pf é um ponteiro para um float;

– pc é um ponteiro para um caractere.

• O asterisco indica que os valores das variáveis sendo declaradas, são ponteiros para valores do tipo especificado na declaração, em vez de objetos desse tipo (ou simples variáveis).

Page 6: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• Um ponteiro é como qualquer outro tipo de dado em C. O valor de um ponteiro é uma posição de memória da mesma forma que o valor de um inteiro é um número. Os valores dos ponteiros podem ser atribuídos como quaisquer outros valores.

• Por exemplo, a declaração:

• pi = &x; atribui o endereço do inteiro x à variável ponteiro pi.

Page 7: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• A notação *pi em C refere-se ao inteiro na posição referenciada pelo ponteiro pi. A declaração:

– x = *pi; atribui o valor deste inteiro à variável inteira x.

• A seguinte atribuição é inválida:

int x;

int y;

y = &x;

Page 8: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• Não é possível atribuir um ponteiro para inteiro x a uma variável y. Para isso é necessário que y, seja declarado como um ponteiro.

• A linguagem C insiste em que uma declaração de um ponteiro especifique o tipo de dado para o qual o ponteiro aponta.

Page 9: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• Uma área na qual os ponteiros de C desempenham um notável papel é na passagem de parâmetros para funções.

• Normalmente, os parâmetros são passados para um função em C por valor, isto é, os valores sendo passados são copiados nos parâmetros da função chamada no momento em que a função for chamada.

Page 10: Aula 2 - Ponteiros e Alocação Estática

Ponteiros

• Se o valor de um parâmetro for alterado dentro da função, o valor no programa de chamada não será modificado.

Page 11: Aula 2 - Ponteiros e Alocação Estática

Exemplo de Passagem de Parâmetro por valor (sem ponteiro) - pass_param_valor.cpp

void funct(int y); main() { int x; x = 5; printf("O valor de x: %i", x); funct(x); printf("\nO valor de x: %i", x); getche(); } void funct(int y) { ++y; printf("\nO valor de y: %i", y); }

x

y

108

104

x

y

108

104

5

6

Page 12: Aula 2 - Ponteiros e Alocação Estática

Exemplo de passagem de parâmetro por referência (com ponteiro) – pass_param_ref.cpp

void funct(int *py); main() { int x; x = 5; printf("O valor de x: %i", x); funct(&x); printf("\nO valor de x: %i", x); getche(); } void funct(int *py) { ++(*py); printf("\nO valor de py: %i", *py); }

x

py

108

104

108

104

5

108

108

104

6

108

x

py

x

py

Page 13: Aula 2 - Ponteiros e Alocação Estática

Programa Exemplo – Arquivo Ponteiro.cpp main()

{ int *a; int b; printf("Endereco de a: %i",&a); /*imprime o endereço de a:

2293620*/ printf("\nEndereco de b: %i",&b); /*imprime o endereço de b:

2293616*/ b = 3; a = &b; /*ponteiro a aponta para o mesmo endereço de b*/ printf("\nEndereco que a aponta: %i",a); /*endereço que a aponta:

2293616 */ printf("\nValor de a: %i",*a); /*o valor de a é 3*/ printf("\nValor de b: %i", b); /*o valor de b é 3*/ *a = 5; /* *a tem seu valor alterado para 5*/ printf("\n*a = 5"); printf("\nValor de a: %i",*a); /*o valor de a passa a ser 5*/ printf("\nValor de b: %i",b); /* o valor de b passa a ser 5 */ getche(); }

Page 14: Aula 2 - Ponteiros e Alocação Estática

Ponteiro de Ponteiro

• É possível pela linguagem C, a definição de ponteiro de ponteiro, isto é, uma variável ponteiro que pode receber o endereço de outra variável ponteiro. Por exemplo, a declaração: – int *px;

– int **py;

• px é um ponteiro para inteiro e py é um ponteiro de ponteiro para inteiro.

Page 15: Aula 2 - Ponteiros e Alocação Estática

Ponteiro de Ponteiro

• Dessa forma, a seguinte atribuição é válida:

– py = &px; em que o ponteiro de ponteiro py aponta para o mesmo endereço do ponteiro px.

• Se a declaração fosse realizada da seguinte forma:

int *px;

int *py;

py = &px;

• Ocasionaria uma operação inválida de atribuição do endereço de um ponteiro para outro ponteiro. Para isso, é necessário um ponteiro de ponteiro.

Page 16: Aula 2 - Ponteiros e Alocação Estática

Exemplo de Ponteiro de Ponteiro – Arquivo Ponteiro2.cpp

main() { int x; int *px; int **py; printf("Entre com um valor

inteiro para x: "); scanf("%i",&x); px = &x; printf("\npx = &x"); printf("\nO endereco de x:

%i",&x); printf("\nO endereco de px:

%i",&px); printf("\nO endereco que px

aponta: %i",px); printf("\n\nO valor de x: %i",x); printf("\nO valor de px: %i",*px);

*px = x*(*px); printf("\n\n*px = x*(*px)"); printf("\nO valor de x: %i",x); printf("\nO valor de px: %i",*px); py = &px; printf("\n\npy = &px"); printf("\nO endereco de px:

%i",&px); printf("\nO endereco de py:

%i",&py); printf("\nO endereco que py aponta:

%i",py); printf("\n\nO valor de px: %i",*px); printf("\nO valor de py: %i",**py); **py = *px * x; printf("\n\n**py = *px * x"); printf("\nO valor de x: %i",x); printf("\nO valor de px: %i",*px); printf("\nO valor de py: %i",**py); getche();

Page 17: Aula 2 - Ponteiros e Alocação Estática

Ilustração de Ponteiro pra Ponteiro

x

*px

**py

2293620

2293616

2293612

10

2293620

2293616

10000 100

Page 18: Aula 2 - Ponteiros e Alocação Estática

Alocação Estática de Memória

• Na alocação estática de memória, os dados são representados por variáveis estáticas, possuindo um tamanho fixo e organizados sequencialmente na memória do computador.

• Um exemplo típico de alocação estática são os vetores. O acesso aos seus componentes é feito de maneira direta (através de um índice, por exemplo).

Page 19: Aula 2 - Ponteiros e Alocação Estática

Alocação Estática de Memória

• Representação:

• Vantagens: Além de todas as vantagens inerentes a manipulação de variáveis estáticas, também têm como característica marcante o fato de poderem ser implementadas em praticamente todas as linguagens de programação mais utilizadas (C, Pascal, COBOL, Fortran, Clipper, Java, etc).

1 2 3 4 5 6 7 8 ... n-1 n

Page 20: Aula 2 - Ponteiros e Alocação Estática

Alocação Estática de Memória

• Desvantagens:

– A quantidade de nós (posições) declarada necessita permanecer alocada.

• Ex: declarar 500 posições e utilizar apenas 10 posições.

– Uso excessivo da memória, mesmo sem usar.

Page 21: Aula 2 - Ponteiros e Alocação Estática

Alocação Estática de Memória

• A alocação estática de memória pode ser utilizada para a implementação, usando vetores, das seguintes estruturas:

Listas estáticas: estruturas que permitem representar um conjunto de dados de forma a preservar a relação de ordem linear entre eles. Uma lista linear é composta de nós que podem conter tanto tipos de dados primitivos quanto construídos.

Ex: Lista de Alunos, Lista de DVDs, Lista de Cds, etc.

Page 22: Aula 2 - Ponteiros e Alocação Estática

Alocação Estática de Memória

• Filas estáticas: estruturas semelhante a listas estáticas, porém com disciplina de inserção e remoção de dados. O sistema a ser utilizado é o FIFO (First In First Out) ou Primeiro a Entrar Primeiro a Sair. Exemplos: filas de impressão, filas de banco, etc.

• Pilhas estáticas: estruturas semelhantes a listas estáticas, apresentando assim como as filas, disciplina de inserção e remoção. O sistema a ser utilizado é o LIFO (Last In First Out) ou Última a Entrar Primeiro a Sair. Exemplos: pilha de alocação de variáveis, pilha de bolachas, etc.