algoritmos e estruturas de dados prof. me. claudio benossi claudio@beno.com.br linguagem c -...
Post on 22-Apr-2015
105 Views
Preview:
TRANSCRIPT
Algoritmos e Estruturas de Dados
Prof. Me. Claudio Benossiclaudio@beno.com.br
Linguagem CLinguagem C- Endereços, - Endereços, Ponteiros ePonteiros e
Alocação dinâmica -Alocação dinâmica -
EndereçosEndereçosEndereçosEndereços
A memória de qualquer computador é A memória de qualquer computador é uma seqüência de bytes.uma seqüência de bytes.
Cada byte pode armazenar um número Cada byte pode armazenar um número inteiro entre 0 e 255.inteiro entre 0 e 255.
Cada byte na memória é Cada byte na memória é identificado por identificado por um endereço numéricoum endereço numérico, independente do , independente do seu conteúdo.seu conteúdo.
1011 0011
1111 0101
0101 1010
0001 1001
0000 0001 0x0022FF160x0022FF16
0x0022FF170x0022FF17
0x0022FF180x0022FF18
0x0022FF190x0022FF19
0x0022FF1A0x0022FF1A
EndereçoEndereçoConteúdoConteúdo
EndereçosEndereçosEndereçosEndereços
EndereçosEndereçosEndereçosEndereços
Cada objeto (variáveis, strings, vetores, etc.) que Cada objeto (variáveis, strings, vetores, etc.) que reside na memória do computador ocupa um reside na memória do computador ocupa um certo número de bytes:certo número de bytes: Inteiros: Inteiros: 4 bytes consecutivos4 bytes consecutivos
Caracteres: Caracteres: 1 byte1 byte
Ponto-flutuante: Ponto-flutuante: 4 bytes consecutivos4 bytes consecutivos
Cada objeto tem um Cada objeto tem um endereçoendereço..
Na arquitetura IA-32 (Intel), o endereço é do Na arquitetura IA-32 (Intel), o endereço é do byte byte menos significativo menos significativo do objeto.do objeto.
1011 0011
1111 0101
0101 1010
0001 1001
0000 0001
0x0022FF100x0022FF10
EndereçoEndereço
1011 0011
1111 0101
0101 1010
0001 1001
0000 00011011 0011
1111 0101
0101 1010
0001 1001
0000 00011011 0011
1111 0101
0101 1010
0001 1001
0000 00011011 0011
1111 0101
0101 1010
0001 1001
0x0022FF140x0022FF14
0x0022FF240x0022FF24
charchar string[4] string[4]
floatfloat real[4] real[4]
charchar string1[4] string1[4]
VariávelVariável
7070
ValorValor
EndereçosEndereçosEndereçosEndereços
Endereços - ResumoEndereços - ResumoEndereços - ResumoEndereços - Resumo
Ao declararmos uma variável x como acima, Ao declararmos uma variável x como acima, temos associados a ela os seguintes elementos:temos associados a ela os seguintes elementos: Um nome (Um nome (xx))
Um endereço de memória ou referência (Um endereço de memória ou referência (0xbfd267c40xbfd267c4))
Um valor (Um valor (100100))
Para acessarmos o endereço de uma variável, Para acessarmos o endereço de uma variável, utilizamos o operador utilizamos o operador &&
int x = 100;int x = 100;
PonteirosPonteirosPonteirosPonteiros
Um ponteiro (apontador ou Um ponteiro (apontador ou pointerpointer) é um ) é um tipo especial de variável tipo especial de variável cujo valor é um cujo valor é um endereçoendereço..
Um ponteiro pode ter o valor especial Um ponteiro pode ter o valor especial NULLNULL, quando não contém nenhum , quando não contém nenhum endereço.endereço.
NULL é uma constanteNULL é uma constante definida na definida na biblioteca biblioteca stdlib.hstdlib.h..
PonteirosPonteirosPonteirosPonteiros
A expressão acima representa A expressão acima representa o o conteúdoconteúdo do endereço de memória guardado na do endereço de memória guardado na variável variável varvar
Ou seja, Ou seja, varvar não guarda um valor, mas não guarda um valor, mas sim um sim um endereço de memóriaendereço de memória..
*var*var
PonteirosPonteirosPonteirosPonteiros
O símbolo * acima é conhecido como O símbolo * acima é conhecido como operador de indireçãooperador de indireção..
A operação acima é conhecida como A operação acima é conhecida como desreferenciamento do ponteiro desreferenciamento do ponteiro varvar..
*var*var
Ponteiros – ExemploPonteiros – ExemploPonteiros – ExemploPonteiros – Exemplo
0x0022FF10
0x0022FF14
x
1111 0101
0101 1010
0001 1001
0000 0001
ap
0001 0000 (10)
1111 1111 (FF)
0010 0010 (22)
0000 0000 (00)
int x;int *ap; // apontador para inteirosap = &x; // ap aponta para x
int x;int *ap; // apontador para inteirosap = &x; // ap aponta para x
71a71
PonteirosPonteirosPonteirosPonteiros
Há Há vários tipos de ponteirosvários tipos de ponteiros::
ponteiros para caracteresponteiros para caracteres
ponteiros para inteirosponteiros para inteiros
ponteiros para ponteiros para inteirosponteiros para ponteiros para inteiros
ponteiros para vetoresponteiros para vetores
ponteiros para estruturasponteiros para estruturas
O compilador C faz questão de O compilador C faz questão de saber de que tipo saber de que tipo de ponteirode ponteiro você está definindo. você está definindo.
Ponteiros – ExemploPonteiros – ExemploPonteiros – ExemploPonteiros – Exemplo
int *ap_int; // apontador para intchar *ap_char; // apontador para charfloat *ap_float; // apontador para floatdouble *ap_double; // apontador para double
// apontador para apontadorint **ap_ap_int;
int *ap_int; // apontador para intchar *ap_char; // apontador para charfloat *ap_float; // apontador para floatdouble *ap_double; // apontador para double
// apontador para apontadorint **ap_ap_int;
72
Aritmética com PonteirosAritmética com PonteirosAritmética com PonteirosAritmética com Ponteiros
Um conjunto limitado de operação Um conjunto limitado de operação aritméticas pode ser executado.aritméticas pode ser executado.
Os ponteiros são Os ponteiros são endereços de memóriaendereços de memória. . Assim, ao somar 1 a um ponteiro, você Assim, ao somar 1 a um ponteiro, você estará indo para o estará indo para o próximo endereço de próximo endereço de memória do tipo de dadomemória do tipo de dado especificado. especificado.
Aritmética com PonteirosAritmética com PonteirosAritmética com PonteirosAritmética com Ponteiros
apap
18
FF
22
00
int *ap;int *ap;
14
FF
22
00
ap+1ap+1
10
FF
22
00
ap+2ap+2
Aritmética com PonteirosAritmética com PonteirosAritmética com PonteirosAritmética com Ponteiros
Sempre que somar ou subtrair ponteiros, Sempre que somar ou subtrair ponteiros, deve-se trabalhar com o deve-se trabalhar com o tamanho do tipo tamanho do tipo de dadode dado utilizado. utilizado.
Para isso você pode usar o operador Para isso você pode usar o operador sizeof()sizeof()..
73
Ponteiros e MatrizesPonteiros e MatrizesPonteiros e MatrizesPonteiros e Matrizes
O nome de uma matriz é, na verdade, um O nome de uma matriz é, na verdade, um ponteiro para o primeiro elementoponteiro para o primeiro elemento da matriz da matriz (endereço base)(endereço base)
Assim, temos duas formas de indexar os Assim, temos duas formas de indexar os elementos de uma matriz ou vetor:elementos de uma matriz ou vetor:
Usando o operador de Usando o operador de indexaçãoindexação ( (v[4]v[4]))
Usando aritmética de Usando aritmética de endereçosendereços ( (*(ap_v + 4)*(ap_v + 4)))
7574
Matrizes de ponteirosMatrizes de ponteirosMatrizes de ponteirosMatrizes de ponteiros
Ponteiros podem ser organizados em matrizes Ponteiros podem ser organizados em matrizes como qualquer outro tipo de dado.como qualquer outro tipo de dado.
Nesse caso, basta observar que o operador Nesse caso, basta observar que o operador ** tem tem precedência menor que o operador de indexação precedência menor que o operador de indexação [][]..
int *vet_ap[5];char *vet_cadeias[5];int *vet_ap[5];char *vet_cadeias[5];
void systax_error(int num){
char *erro[] = {"Arquivo nao pode ser aberto\n","Erro de leitura\n","Erro de escrita\n","Falha de midia\n"};
printf("%s", erro[num]);}
void systax_error(int num){
char *erro[] = {"Arquivo nao pode ser aberto\n","Erro de leitura\n","Erro de escrita\n","Falha de midia\n"};
printf("%s", erro[num]);}
Matrizes de ponteirosMatrizes de ponteirosMatrizes de ponteirosMatrizes de ponteiros
Normalmente, são utilizadas como ponteiros para Normalmente, são utilizadas como ponteiros para stringsstrings, pois uma string é essencialmente um , pois uma string é essencialmente um ponteiro para o seu primeiro caractere.ponteiro para o seu primeiro caractere.
Ponteiro para funçãoPonteiro para funçãoPonteiro para funçãoPonteiro para função
Um ponteiro para uma função contém o Um ponteiro para uma função contém o endereço endereço da funçãoda função na memória. na memória.
Da mesma forma que um nome de matriz, um Da mesma forma que um nome de matriz, um nome de função é o nome de função é o endereço na memória do endereço na memória do começo do códigocomeço do código que executa a tarefa da que executa a tarefa da função.função.
O O uso mais comum uso mais comum de ponteiros para funções é de ponteiros para funções é permitir que uma função possa ser passada como permitir que uma função possa ser passada como parâmetro para uma outra função.parâmetro para uma outra função.
Ponteiro para funçãoPonteiro para funçãoPonteiro para funçãoPonteiro para função
Ponteiros de função podem ser:Ponteiros de função podem ser: atribuídosatribuídos a outros ponteiros, a outros ponteiros,
passadospassados como argumentos, como argumentos,
retornadosretornados por funções, e por funções, e
armazenadosarmazenados em matrizes. em matrizes.
76
Função que retorna ponteirosFunção que retorna ponteirosFunção que retorna ponteirosFunção que retorna ponteiros
Funções que devolvem ponteiros funcionam da Funções que devolvem ponteiros funcionam da mesma forma que os outros tipos de funçõesmesma forma que os outros tipos de funções
Alguns detalhes devem ser observados:Alguns detalhes devem ser observados: Ponteiros não são variáveisPonteiros não são variáveis
Quando incrementados, eles apontam para o próximo Quando incrementados, eles apontam para o próximo endereço do tipo apontadoendereço do tipo apontado
Por causa disso, o compilador deve saber o tipo Por causa disso, o compilador deve saber o tipo apontado por cada ponteiro declaradoapontado por cada ponteiro declarado
Portanto, uma função que retorna ponteiro deve Portanto, uma função que retorna ponteiro deve declarar explicitamente qual tipo de ponteiro está declarar explicitamente qual tipo de ponteiro está retornandoretornando
Função que retorna ponteirosFunção que retorna ponteirosFunção que retorna ponteirosFunção que retorna ponteiros
77
<tipo> *funcao(.....){
....return (ponteiro);
}
<tipo> *funcao(.....){
....return (ponteiro);
}
<tipo> <tipo> não pode sernão pode ser void void, pois:, pois:• Função deve devolver algum valorFunção deve devolver algum valor• Ponteiro deve apontar para algum tipo de dadoPonteiro deve apontar para algum tipo de dado
Alocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memória
Um programa, ao ser executado, divide a Um programa, ao ser executado, divide a memória do computador em quatro áreas:memória do computador em quatro áreas:
InstruçõesInstruções – armazena o código C compilado e montado – armazena o código C compilado e montado em linguagem de máquina.em linguagem de máquina.
PilhaPilha – nela são criadas as variáveis locais.– nela são criadas as variáveis locais.
Memória estáticaMemória estática – onde são criadas as variáveis globais – onde são criadas as variáveis globais e locais estáticas.e locais estáticas.
HeapHeap – destinado a armazenar dados alocados – destinado a armazenar dados alocados dinamicamente.dinamicamente.
Dados estáticosDados estáticos
Alocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memória
Dados dinâmicos(Heap)
Dados dinâmicos(Heap)
PilhaPilha
Embora seu tamanho Embora seu tamanho seja desconhecido, o seja desconhecido, o heap geralmente heap geralmente contém uma quantidade contém uma quantidade razoavelmente grande razoavelmente grande de memória livre.de memória livre.
InstruçõesInstruções
Alocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memória
As variáveis da As variáveis da pilhapilha e da memória e da memória estáticaestática precisam ter precisam ter tamanho conhecido tamanho conhecido antes do antes do programa ser compilado.programa ser compilado.
A alocação dinâmica de memória permite A alocação dinâmica de memória permite reservar espaços de memória de tamanho reservar espaços de memória de tamanho arbitrário e acessá-los através de apontadores.arbitrário e acessá-los através de apontadores.
Desta forma, podemos escrever programas mais Desta forma, podemos escrever programas mais flexíveis, pois nem todos os tamanhos devem ser flexíveis, pois nem todos os tamanhos devem ser definidos aos escrever o programa.definidos aos escrever o programa.
Alocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memóriaAlocação dinâmica de memória
A alocação e liberação desses espaços de A alocação e liberação desses espaços de memória é feito por duas funções da memória é feito por duas funções da biblioteca biblioteca stdlib.hstdlib.h::
malloc()malloc(): aloca um espaço de memória.: aloca um espaço de memória.
free()free(): libera um espaço de memória.: libera um espaço de memória.
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()
Abreviatura de Abreviatura de memory allocationmemory allocation
Aloca um bloco de bytes consecutivos na Aloca um bloco de bytes consecutivos na memória e devolve o endereço desse bloco.memória e devolve o endereço desse bloco.
Retorna um ponteiro do tipo Retorna um ponteiro do tipo voidvoid..
Deve-se utilizar um Deve-se utilizar um cast cast (modelador) para (modelador) para transformar o ponteiro devolvido para um transformar o ponteiro devolvido para um ponteiro do tipo desejado.ponteiro do tipo desejado.
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()
78
int *p;p = (int*) malloc(n * sizeof(int));int *p;p = (int*) malloc(n * sizeof(int));
Exemplo:Exemplo:
Alocando um vetor de Alocando um vetor de nn elementos do tipo elementos do tipo inteiro.inteiro.
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()
A memória não é infinitaA memória não é infinita. Se a memória do . Se a memória do computador já estiver toda ocupada, a função computador já estiver toda ocupada, a função mallocmalloc não consegue alocar mais espaço e não consegue alocar mais espaço e devolve NULLdevolve NULL..
Usar um Usar um ponteiro nuloponteiro nulo travarátravará o seu computador o seu computador na maioria dos casos.na maioria dos casos.
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função malloc()malloc()
Convém verificar essa possibilidade antes de Convém verificar essa possibilidade antes de prosseguir.prosseguir.
ptr = (int*) malloc (1000*sizeof(int));if (ptr == NULL){
printf ("Sem memoria\n");}...
ptr = (int*) malloc (1000*sizeof(int));if (ptr == NULL){
printf ("Sem memoria\n");}...
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função free()free()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função free()free()
Libera o uso de um bloco de memória, permitindo Libera o uso de um bloco de memória, permitindo que este espaço seja reaproveitado.que este espaço seja reaproveitado.
O mesmo endereço retornado por uma chamada O mesmo endereço retornado por uma chamada da função da função malloc()malloc() deve ser passado para a deve ser passado para a função função free()free(). .
A determinação do tamanho do bloco a ser A determinação do tamanho do bloco a ser liberado é feita automaticamente.liberado é feita automaticamente.
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função free()free()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função free()free()
Exemplo:Exemplo: liberando espaço ocupado por um vetor liberando espaço ocupado por um vetor de 100 inteirosde 100 inteiros
79
int *p;p = (int*) malloc(100 * sizeof(int));free(p);
int *p;p = (int*) malloc(100 * sizeof(int));free(p);
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função realloc()realloc()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função realloc()realloc()
Essa função faz um bloco já alocado crescer ou Essa função faz um bloco já alocado crescer ou diminuir, diminuir, preservandopreservando o conteúdo já existente: o conteúdo já existente:
(tipo*) realloc(tipo *apontador, int novo_tamanho)(tipo*) realloc(tipo *apontador, int novo_tamanho)
int *x, i;x = (int *) malloc(4000*sizeof(int));for(i=0;i<4000;i++) x[i] = rand()%100;
x = (int *) realloc(x, 8000*sizeof(int));
x = (int *) realloc(x, 2000*sizeof(int));free(x);
int *x, i;x = (int *) malloc(4000*sizeof(int));for(i=0;i<4000;i++) x[i] = rand()%100;
x = (int *) realloc(x, 8000*sizeof(int));
x = (int *) realloc(x, 2000*sizeof(int));free(x);
Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função realloc()realloc()Alocação dinâmica de memóriaAlocação dinâmica de memória:: Função :: Função realloc()realloc()
int *x, i;
x = (int *) malloc(4000*sizeof(int));
for(i=0;i<4000;i++) x[i] = rand()
%100;
x = (int *) realloc(x,
8000*sizeof(int));
x = (int *) realloc(x,
2000*sizeof(int));
free(x);
int *x, i;
x = (int *) malloc(4000*sizeof(int));
for(i=0;i<4000;i++) x[i] = rand()
%100;
x = (int *) realloc(x,
8000*sizeof(int));
x = (int *) realloc(x,
2000*sizeof(int));
free(x);
x
x
x
x
x
80
Questões Questões Questões Questões
top related