Baixe o app para aproveitar ainda mais
Prévia do material em texto
Estruturas de Dados ALOCAÇÃO DINÂMICA DE MEMÓRIA: PONTEIROS ▪Conjunto de funções que operam sobre uma estrutura: ▪O conceito de tipo de dado abstrato é dissociado do hardware. ▪ TAD define o que cada operação faz, mas não como faz. ▪Uma boa técnica de programação é implementar os TADs em arquivos separados do programa principal. ▪Para isso, geralmente separa-se a declaração e a implementação do TAD em dois arquivos: ▪NomeDoTAD.h: com a declaração ▪NomeDoTAD.c: com a implementação Tipos abstratos de dados O Tipo Struct Entendendo o uso da TAD • Como representar os conceitos mais complexos do mundo real? • A maior parte das “coisas” que existem no mundo é mais complexa que um simples número. • Por esse motivo, precisam de mais de uma variável para representá-las. O problema dos Tipos Primitivos ▪E para representar uma pessoa? Nome Telefone Endereço O problema dos Tipos Primitivos • Esses conceitos não podem ser representados com os tipos primitivos de dados. • Eles possuem muitas informações para caber em apenas uma única variável! Entendendo o uso da TAD ▪Para representar uma pessoa, podemos utilizar 3 variáveis: • uma do tipo char, para representar o seu nome; • uma do tipo int, para representar o cpf; • uma do tipo int, para representar a idade; • O código seria: • char nome; • int cpf; • int idade; Entendendo o uso da TAD ▪Os TADs (Tipos Abstratos de Dados) nada mais são do que um agrupamento de outros dados usados para representar conceitos mais complexos do mundo real: TAD PESSOA char nome; int cpf; Int idade; Criando uma TAD • Um Tipo Abstrato de Dados precisa encapsular as suas informações. • Isso significa que as variáveis que representam as informações não podem ficar soltas, como se fossem declaradas de forma independente. • Elas precisam de um escopo (um corpo) onde as informações possam ser guardadas. Criando uma TAD • Ao invés de declarar as 3 variáveis soltas, colocamos dentro de uma estrutura (TAD): char nome; int cpf; int idade; estrutura pessoa{ char nome; int cpf; int idade; } Criando uma TAD • A maioria das linguagens de programação usam o conceito de classes para definir um Tipo Abstrato de Dados. • Elas usam a palavra “class” para definir o escopo (o corpo) onde as variáveis serão declaradas. Criando uma TAD • A linguagem de programação C usa a palavra “struct” no lugar de “class“. • struct Pessoa{ • char nome; • int cpf; • int idade; • }; Criando uma variável de uma TAD • Uma vez que criou-se o Tipo Abstrato de Dados, agora pode declarar variáveis desse novo tipo, ao invés de usar tipos primitivos de dados. • struct Pessoa novaPessoa; Criando uma variável de uma TAD • struct Pessoa novaPessoa; • A variável novaPessoa contém dentro dela todas as 3 variáveis primitivas. Criando uma variável de uma TAD • Uma vez criada a variável de um Tipo Abstrato. • Podemos acessar e modificar todos os dados dentro dessa variável por meio do operador ‘.‘ (ponto). • novaPessoa.nome = “Harry Styles”; • novaPessoa.cpf = 12345678; • novaPessoa.idade = 29; Criando uma variável de uma TAD • Podemos usar o operador ‘.‘ (ponto) para imprimir os dados na tela. • printf(“%s”, novaPessoa.nome); • printf(“%i”, novaPessoa.cpf); • printf(“%i”, novaPessoa.idade); Exemplo de uso de uma TAD • #include <stdio.h> • #include <stdlib.h> • int main() { • //CRIA O STRUCT • struct pessoas { • char nome[20]; • int idade; • float peso; • float altura; • }; • struct pessoas usuario[3]; Exemplo de uso de uma TAD • CAPTURA OS DADOS DO USUÁRIO • int i; • for (i=0; i<=2; i++) • { • printf("\n"); • printf("\nDigite seu nome: "); • //fgets – para ler uma string. fgets (str, tamanho, stdin); • //stdin: dispositivo de entrada padrão (geralmente o teclado) • fgets(usuario[i].nome, sizeof(usuario[i].nome), stdin); • printf("\nDigite sua idade: "); • scanf("%i", &usuario[i].idade); • //flush(stdin)Usado para limpar o buffer e aceitar a nova entrada • fflush(stdin); • printf("\nDigite seu peso: "); • scanf("%f", &usuario[i].peso); • fflush(stdin); • printf("\nDigite sua altura: "); • scanf("%f", &usuario[i].altura); • fflush(stdin); • } Exemplo de uso de uma TAD • //IMPRIME OS DADOS DO USUÁRIO. • for (i=0; i<=2; i++) • { • printf("\n%s, com %i anos voce pesa %.2f e tem %.2f de altura!",usuario[i].nome, usuario[i].idade, usuario[i].peso, usuario[i].altura); • } • printf("\n\n"); • return(0); • } Tipo Abstrato de Dados Linguagens de programação orientadas a objetos, como C++, oferecem aos programadores a possibilidade de estender o conjunto de tipos que podem ser usados em suas implementações. O mecanismo básico para tal fim é a definição de classes. A definição de uma classe define uma estrutura interna e de um conjunto de operações que podem ser aplicados a variáveis desse tipo, que são chamadas de objetos. Alocação dinâmica da memória ▪As Funções de Alocação Dinâmica de Memória em "C" ▪Alocação Dinâmica é um meio pelo qual o programa pode obter memória enquanto está em execução. ▪Constantes são "codificadas" dentro do código de um programa em tempo de compilação: ▪ //declaração da constante #define ICMS 0.18; ▪Variáveis globais (estáticas) têm a sua alocação codificada em tempo de compilação e são alocadas logo que um programa inicia a execução. ▪Variáveis locais em funções (ou métodos) são alocadas através da requisição de espaço na pilha (stack). Alocação dinâmica de memória: ponteiros ▪ O uso da memória: ▪ Reservar a memória é solicitar ao programa que aloque dinamicamente um espaço na memória durante sua execução. ▪ Três maneiras de reservarmos espaço de memória para o armazenamento de informações. ▪ Uso de variáveis globais (e estáticas – valor mantido entre as chamadas da função). Nesta categoria de variáveis, o espaço reservado para uma variável existirá enquanto o programa estiver sendo executado. ▪ Uso de variáveis locais. Nesta categoria, o espaço na memória existe apenas no período em que a função que declarou a variável está sendo executada, sendo liberado assim que a execução da função terminar. Alocação dinâmica de memória: ponteiros ▪Por que utilizar Alocação dinâmica de memória? ▪Útil quando os requisitos exatos de armazenamento são desconhecidos antes de sua execução. ▪A memória é alocada da heap durante o tempo de execução do programa. ▪A alocação dinâmica permite ao programador alocar memória para variáveis quando o programa está sendo executado. ▪Assim, poderemos definir, por exemplo, um vetor ou uma matriz cujo tamanho descobriremos em tempo de execução. Alocação dinâmica de memória: ponteiros Áreas de alocação: Stack (Pilha) e Heap ▪ O sistema operacional ao carregar um programa na memória disponibiliza ao programa um espaço de endereçamento. Esse espaço é a memória disponível para aquele programa. ▪ A pilha de funções (stack) é uma área da memória que aloca dados/variáveis ou ponteiros quando uma função é chamada e desalocada quando a função termina. Podemos dizer então que representa a memória local àquela função. • O Heap, ou área de alocação dinâmica, é um espaço reservado para variáveis e dados criados durante a execução do programa (runtime). Vamos dizer que o Heap é a memória global do programa. ▪Áreas de alocação ▪ A Stack (Pilha) é uma porção contígua de memória reservada para empilhar os dados necessários durante a execução de blocos de código. ▪ O escopo de uma variável costuma definir o tempo de alocação na stack. Os dados usados como parâmetros e retorno de funções são alocados na stack. ▪ A memória Stack é utilizada para armazenar argumentos de uma função, procedure, método. ▪ Sendo ela estática pré-alocada no start do programa e desalocada no final, e por isso é mais veloz do que a memóriaHeap que precisa ser alocada/desalocada a cada momento que for necessário. Alocação dinâmica de memória: ponteiros ▪Áreas de alocação ▪ Na Stack (Pilha) são guardados objetos alocados dentro de escopos de funções incluindo variáveis locais das funções, argumentos, endereços das áreas de código sendo executadas antes de outras chamadas de função, retorno de funções. ▪ A alocação de memória ocorre de forma sequencial e, como a posição desses objetos é conhecida durante o tempo de compilação, nós podemos atribuir nomes próprios a esses objetos e acessá-los diretamente. ▪ Quando um objeto que é alocado no stack sai de seu respectivo escopo, o objeto é automaticamente deletado. Então você não precisa se preocupar com alocação e desalocação de memória com objetos da pilha mas atenção, o stack tem um tamanho limitado. Alocação dinâmica de memória: ponteiros ▪Áreas de alocação - Heap ▪ a heap pode ser usada em qualquer ponto do programa normalmente em criação de objetos ou ponteiros para alguma estrutura de dados. ▪O heap é o local de memória adequado para alocar muitos objetos grandes, pois esta seção do programa é bem maior que a pilha, e seu tamanho é limitado apenas pela memória virtual disponível na máquina. ▪Os objetos alocados no heap são todos aqueles alocados usando new ou malloc() (objetos alocados dinamicamente). Alocação dinâmica de memória: ponteiros ▪Áreas de alocação ▪Heap ▪Como a posição em que esses objetos vão estar durante a execução do programa é desconhecida em tempo de compilação, a única forma de acessá-los é via Ponteiros. ▪Deve lembrar-se de controlar a desalocação desses objetos, pois não são destruídos automaticamente. Alocação dinâmica de memória: ponteiros ▪Resumo ▪Heap ▪ Alocação dinâmica de memória (malloc). ▪ Objetos criados em tempo de execução (new). ▪ variáveis e dados criados durante a execução do programa. ▪ Stack ▪ Variáveis locais em funções (ou métodos) ▪ Ponteiros ▪ Argumentos de uma função, procedure, método ▪ Os dados usados como parâmetros e retorno de funções são alocados na stack. Alocação dinâmica de memória: ponteiros ▪O uso da memória: ▪Inicialmente temos a memória RAM vazia Alocação dinâmica de memória: ponteiros ▪O uso da memória: Quando clicamos para executar o programa, e o programa é carregado da memória persistente, HD, SSD ... Para a memória RAM Alocação dinâmica de memória: ponteiros ▪O uso da memória: ▪Uma vez o programa carregado a execução inicia executando byte a byte as instruções em linguagem de máquina. Alocação dinâmica de memória: ponteiros ▪O uso da memória: ▪Então as variáveis estáticas e constantes são carregadas. Alocação dinâmica de memória: ponteiros ▪O uso da memória: ▪A conforme o programa funciona as variáveis locais e a pilha de funções passam a trabalhar dinâmicamente, utilizando o espaço livre. ▪Subindo e descendo. Alocação dinâmica de memória: ponteiros ▪O uso da memória: ▪A conforme o programa funciona as variáveis locais e a pilha de funções passam a trabalhar dinâmicamente, utilizando o espaço livre. ▪Subindo e descendo. Alocação dinâmica de memória: ponteiros PONTEIRO DE VARIÁVEIS ▪ Dualidade, nome e endereço: ▪ Nome conhecido: Edifício Gazeta; ▪ Ou pelo Endereço Av. Paulista, 900; ▪ Ambos chegam ao mesmo lugar. ▪ Ou pelo endereço ou pelo nome do lugar que é conhecido. ▪ Assim acontece com uma variável, eu consigo manipular o conteúdo de uma variável, tanto pelo nome, quanto pelo endereço. Ponteiro de variáveis Fonte: earth.google.com ▪ Como funciona? ▪ Memória limpa. ▪ Tabela de variáveis. ▪ Cada byte possui um endereço. ▪ Possui uma tabela onde as variáveis são registradas, com o seu nome tipo e endereço. Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo nome endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo nome endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo ▪ Como funciona? ▪ Ao declarar int idade, supondo que um valor inteiro ocupe 4 bytes, ▪ o gerenciador de memória localiza um espaço com quatro bytes livres. ▪ Encontra no endereço 125. Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo nome endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo nome endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo espaço livre para ocupar 4 bytes ▪Como funciona? ▪Então a tabela de variáveis é preenchida , com o nome, endereço e tipo. Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo nome endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo nome endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo idade 125 int ▪ A linguagem C tem uma maneira especial de uma variável armazenar endereços. Essa variável se chama variável ponteiro ou simplesmente ponteiro. Exemplo: Para acessar os endereços de memória, a linguagem oferece dois operadores unários: ▪ & (“endereço de”), aplicado a variáveis, resulta no endereço da posição da memória reservada para a variável; ▪ * (“conteúdo de”), aplicado a variáveis do tipo ponteiro, acessa o conteúdo do endereço de memória armazenado pela variável ponteiro. Ponteiro de variáveis <tipo> *nome; int *p; Nota: • O asterisco se utilizado como operador retornará o valor armazenado no endereço apontado. • O tipo indica o que vamos encontrar quando acessarmos aquele endereço. Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo nome endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int Ao declarar a variável a o gerenciador procura o espaço livre para armazenar um inteiro, e é registrado na tabela Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo nome p endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int O passo seguinte é reservar o espaço para o ponteiro p. Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 5 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo nome p endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int Ao atribuir o valor 5 em a, o sistema consulta a tabela e armazena no endereço 117 Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 5 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo &117 nome p endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdonome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int O operador & aplicado em a, a variável ponteiro p recebe o endereço de a (117), e conforme a tabela é armazenda no endereço 125. Mostrar o &117 em 125 Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 5 6 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo &117 nome p endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int O operador * aplicada num ponteiro p. A operação é feita no local onde o ponteiro aponta (117), ou seja, p aponta para 117, portanto o valor é armazenado no endereço 117. Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 6 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo &117 nome p endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int Assim se mostrarmos o conteúdo da variável a será 6 Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 6 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo &117 nome p b endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int b 136 int Ao declarar a variável b o gerenciador procura o espaço livre para armazenar um inteiro, e é registrado na tabela Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 6 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo &117 &136 nome p b endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int b 136 int P agora passa a apontar para b Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 6 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo &136 6 nome p b endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int b 136 int Assim atribuímos ao b um valor (6), sem em momento algum atribuir explicitamente a atribuição ( b = 6) Ponteiro de variáveis endereço 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 conteúdo 6 nome a endereço 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 conteúdo &136 6 nome p b endereço 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 conteúdo nome Memória RAM Tabela das variáveis Nome endereço tipo a 117 int * p 125 int b 136 int Ao imprimir b o resultado será 6. Passagem de valores por valor e por referência Passagem de valores por valor e por referência #include<stdio.h> void troca(int *a, int *b){ int temp; temp=*a; *a=*b; *b=temp; } void main(){ int a=7,b=5; troca(&a,&b); printf("\na=%d\nb=%d\n",a,b); } #include<stdio.h> void troca(int a, int b){ int temp; temp=a; a=b; b=temp; } void main(){ int a=7,b=5; troca(a,b); printf("\na=%d\nb=%d\n",a,b); } Acessando vetor usando Ponteiro ▪ Duas formas de se utilizar ponteiros #include <stdio.h> #include <stdlib.h> void main() { int v[5] = { 1,2,3,4,5 }; int *p = v; for (int i = 0; i < 5; i++) printf("%d ", p[i]); //usando array } #include <stdio.h> #include <stdlib.h> void main() { int v[5] = { 1,2,3,4,5 }; int *p = v; for (int i = 0; i < 5; i++) printf("%d ", *(p+i)); //usando ponteiro } OU IMPRIME: 1 2 3 4 5IMPRIME: 1 2 3 4 5 Passagem de vetores para funções //SOMA UM A CADA ELEMENTO DO VETOR #include <stdio.h> void incrvetor (int n, int *v) { int i; for (i = 0; i < n; i++) v[i]++; } void main ( ) { int a[ ] = {1, 3, 5}; //INFORMA A QUANTIDADE TOTAL DE ITENS NO ARRAY E O VETOR incrvetor(3, a); printf("%d %d %d \n", a[0], a[1], a[2]); } IMPRIME: 2, 4, 6 Alocação Dinâmica de Memória - Aplicação Alocação Dinâmica de Memória - Instruções Ela é utilizada quando não se sabe ao certo quanto de memória será necessário para o armazenamento das informações, podendo ser determinadas em tempo de execução conforme a necessidade do programa. int numero[10]; → O programador sabe antecipadamente quando de memória vai alocar (10 posições X 4 bytes = 40 bytes). int *numero = (int *) malloc (10*sizeof(int)); (Se apenas usar 1 posição: 1 posição X 4 bytes = 4 bytes). float *v Alocação Dinâmica de Memória - Instruções Funções da biblioteca padrão ▪ A biblioteca stdlib.h possui algumas funções que nos permitem criar e trabalhar dinamicamente, durante a execução de um certo trecho do programa. ▪ As funções malloc e free e o operador sizeof, são essenciais para a alocação dinâmica de memória. ▪ malloc() ▪ free() ▪ sizeof() int *v; v = (int*) malloc(10*sizeof(int)); float *a; a = (float*) malloc(10*sizeof(float)); float *v Alocação Dinâmica de Memória float *v Alocação Dinâmica de Memória ▪A função sizeof() ▪É uma boa pratica evitar escolher o número de bytes alocados, pois cada máquina pode alocar 2 ou 4 bytes para uma mesma variável dependendo da arquitetura. ▪Para alocar de maneira correta usar a função sizeof(): ▪char *nome = (char *) malloc (21*sizeof(char)); float *v ▪ o malloc(int ), memory allocation ou alocação de memória. A função malloc reserva a quantidade de bytes que é passado como parâmetro e retorna o endereço em que este espaço de memória foi reservado. ▪ Exemplo reservar 20 bytes na memória: malloc(20) Uso da função Malloc() sizeof ▪ Para descobrir quantos bytes um tipo ocupa a biblioteca nos fornece a função sizeof(tipo), tamanho de. Esta função retorna um número inteiro que um tipo ocupa. ▪ Exemplo para saber quanto espaço um tipo ocupa: sizeof( int ) malloc(10*sizeof(int)) alocando 10 espaços ocupados por inteiro Free() Free() ▪ #include <stdio.h> ▪ #include <stdlib.h> ▪ int main() ▪ { ▪ char *nome = (char *) malloc (21*sizeof(char)); ▪ printf("Insira seu nome: "); ▪ gets(nome); ▪ printf("\n\nNome: %s", nome); ▪ free(nome); ▪ return 0; ▪ } Modificador cast ▪ Modifica, ou formata um espaço de memória alterando o seu tipo. v=(int *)malloc(10*sizeof(int)); Vetores ▪ Muitas vezes, o uso de vetores e matrizes fica limitado pela necessidade de sabermos antecipadamente a quantidade de elementos que serão necessários. ▪ A biblioteca stdlib.h possui algumas funções que permitem criar e trabalhar dinamicamente. Criando-se dinamicamente: Funções da biblioteca-padrão ▪Qual é a vantagem de declarar um vetor como ponteiro? ▪A vantagem é não ser necessário definir, a priori, o tamanho do vetor. ▪O tamanho do vetor pode ser estabelecido na execução do programa, quando a memória para o vetor for alocada pela função malloc. Funções da biblioteca-padrão ▪ IMPRIMINDO O ELEMENTO DEUMA MATRIZ COM PONTEIRO ▪ #include <stdio.h> ▪ #include <stdlib.h> ▪ int main () ▪ { ▪ int matrx [10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; ▪ int *p; ▪ p=matrx; ▪ printf ("O 3ro elemento eh: %d\n",p[3]); ▪ printf ("O 3ro elemento eh: %d\n",matrx[3]); ▪ printf ("O 3ro elemento eh: %d\n",p[2]); ▪ } IMPRIME: O 3ro elemento eh: 4 O 3ro elemento eh: 4 O 3ro elemento eh: 3 Funções da biblioteca-padrão Voltando ao exemplo da memória simulada Um ponteiro v é criado Funções da biblioteca-padrão Tamanho do tipo Tamanho do tipo int Tamanho de 10 inteiros Aloca o espaço de 10 inteiros malloc reserva uma quantidade de bytes que é passado como parâmetro, retornando o endereço onde a reserva aconteceu. Reserva-se então 10 números inteiros. Entre a posição 101 e 141. Funções da biblioteca-padrão O malloc retorna um endereço. O endereço é um tipo inteiro precisamos fazer um CAST para identificar o destino. Funções da biblioteca-padrão Expressão Ao fazer a expressão Equivale a fazer a expressão int *x = v+0 printf(“%d”,*x) printf(“%d”,v[0]) int *x = v+1 printf(“%d”,*x) printf(“%d”,v[1]) int *x = v+2 printf(“%d”,*x) printf(“%d”,v[2]) int *x = v+3 printf(“%d”,*x) printf(“%d”,v[3]) int *x = v+4 printf(“%d”,*x) printf(“%d”,v[4]) Aritmética de ponteiros ▪ O ponteiro também tem uma aritmética própria. ▪ Ao fazermos uma soma de um número inteiro a um ponteiro, ele apontará para o endereço com o avanço de múltiplos correspondente ao tamanho do tipo definido para ele. ATÉ A PRÓXIMA! Slide 1 Slide 2: Alocação dinâmica de memória: Ponteiros Slide 3: Tipos abstratos de dados Slide 4 Slide 5: Entendendo o uso da TAD Slide 6: O problema dos Tipos Primitivos Slide 7: O problema dos Tipos Primitivos Slide 8: Entendendo o uso da TAD Slide 9: Entendendo o uso da TAD Slide 10: Criando uma TAD Slide 11: Criando uma TAD Slide 12: Criando uma TAD Slide 13: Criando uma TAD Slide 14: Criando uma variável de uma TAD Slide 15: Criando uma variável de uma TAD Slide 16: Criando uma variável de uma TAD Slide 17: Criando uma variável de uma TAD Slide 18: Exemplo de uso de uma TAD Slide 19: Exemplo de uso de uma TAD Slide 20: Exemplo de uso de uma TAD Slide 21: Tipo Abstrato de Dados Slide 22: Alocação dinâmica da memória Slide 23: Alocação dinâmica de memória: ponteiros Slide 24: Alocação dinâmica de memória: ponteiros Slide 25: Alocação dinâmica de memória: ponteiros Slide 26: Áreas de alocação: Stack (Pilha) e Heap Slide 27: Alocação dinâmica de memória: ponteiros Slide 28: Alocação dinâmica de memória: ponteiros Slide 29: Alocação dinâmica de memória: ponteiros Slide 30: Alocação dinâmica de memória: ponteiros Slide 31: Alocação dinâmica de memória: ponteiros Slide 32: Alocação dinâmica de memória: ponteiros Slide 33: Alocação dinâmica de memória: ponteiros Slide 34: Alocação dinâmica de memória: ponteiros Slide 35: Alocação dinâmica de memória: ponteiros Slide 36: Alocação dinâmica de memória: ponteiros Slide 37: Alocação dinâmica de memória: ponteiros Slide 38: Ponteiro de variáveis Slide 39: Ponteiro de variáveis Slide 40: Ponteiro de variáveis Slide 41: Ponteiro de variáveis Slide 42: Ponteiro de variáveis Slide 43: Ponteiro de variáveis Slide 44: Ponteiro de variáveis Slide 45: Ponteiro de variáveis Slide 46: Ponteiro de variáveis Slide 47: Ponteiro de variáveis Slide 48: Ponteiro de variáveis Slide 49: Ponteiro de variáveis Slide 50: Ponteiro de variáveis Slide 51: Ponteiro de variáveis Slide 52: Ponteiro de variáveis Slide 53: Ponteiro de variáveis Slide 54: Passagem de valores por valor e por referência Slide 55: Passagem de valores por valor e por referência Slide 56: Acessando vetor usando Ponteiro Slide 57: Passagem de vetores para funções Slide 58: Alocação Dinâmica de Memória - Aplicação Slide 59: Alocação Dinâmica de Memória - Instruções Slide 60: Alocação Dinâmica de Memória - Instruções Slide 61: Alocação Dinâmica de Memória Slide 62: Alocação Dinâmica de Memória Slide 63 Slide 64: sizeof Slide 65: Free() Slide 66: Free() Slide 67: Modificador cast Slide 68: Vetores Slide 69: Funções da biblioteca-padrão Slide 70: Funções da biblioteca-padrão Slide 71 Slide 72: Funções da biblioteca-padrão Slide 73: Funções da biblioteca-padrão Slide 74: Funções da biblioteca-padrão Slide 75: Funções da biblioteca-padrão Slide 76: Aritmética de ponteiros Slide 77
Compartilhar