Aula 23: Ponteiros Introdução a Programação Túlio Toffolo & Puca Huachi http://www.toffolo.com.br BCC201 2018/2 Baseado nos slides do Prof. Guillermo Cámara-Chávez
Aulas anteriores Vetores Matrizes Cadeias de caracteres 2 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Aula de hoje 1 Memória 2 Ponteiros 3 Ponteiros e passagem por referência 4 Ponteiros e vetores 5 Próxima aula 2 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Aula de hoje 1 Memória 2 Ponteiros 3 Ponteiros e passagem por referência 4 Ponteiros e vetores 5 Próxima aula 2 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Memória Memoria I Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D Valor memória está formada por várias élulas. A memória é formada por várias ada célula contém células. um endereço e um alor. tamanho do Cada endereço célulae ocontém tamanho um endereço o valor dependeme um valor da arquitetura (veja exemplo do ao omputador lado). (32/64 bits) O tamanho do endereço e do Endereço valor dependem Valor da arquitetura 0000000D (32/64 bits). 2/81 3 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Memória Memoria II Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D Valor i i n t main ( ) { c h a r i ; r e t u r n 0 ; } Exemplo: O caractere i ocupa 1 byte na memória (considerando uma arquitetura de 32 bits) 1 int main() Declaro 2 { um caracter chamado i. 3 char i; Os4caracteres return ocupam 0; 1 byte na memória 5 } (para uma arquitetura de 32 bits) 3/81 4 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Memória Memoria III Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D Valor i i n t main ( ) { i n t i ; r e t u r n 0 ; } Exemplo: Inteiro i ocupa 4 bytes na memória (considerando uma arquitetura de 32 bits) 1 int main() Declaro um número inteiro 2 { chamado 3 i. int i; 4 return 0; Os inteiros ocupam 4 bytes na 5 } memória (para uma arquitetura de 32 bits) 4/81 5 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Memória Memoria IV Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D Valor i i n t main ( ) { f l o a t i ; r e t u r n 0 ; } Exemplo: Ponto flutuante i ocupa 4 bytes na memória (considerando uma arquitetura de 32 bits) 1 int main() Declaro um número ponto 2 { flutuante 3 chamado float i; i. 4 return 0; Os flutuantes ocupam 4 bytes 5 } na memória (para uma arquitetura de 32 bits) 5/81 6 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Memória Memoria V Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D Valor i i n t main ( ) { d o u b l e i ; r e t u r n 0 ; } Exemplo: Double i ocupa 8 bytes na memória (considerando uma arquitetura de 32 bits) Declaro 1 int ummain() número flutuante de 2 dupla { precisão chamado i. 3 double i; Os4flutuantes return de dupla 0; precisão ocupam 5 } 8 bytes na memória (para uma arquitetura de 32 bits) 6/81 7 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Endereços Ao declararmos uma variável x, ela será associada a: Um nome (x) Um endereço de memória ou referência (0xbfd267c4) Um valor (9) 1 int x = 9; Para acessar o endereço de uma variável, utilizamos o operador & 1 int x; 2 cout << "O endereço de memória de x é " << &x << endl; 8 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Aula de hoje 1 Memória 2 Ponteiros 3 Ponteiros e passagem por referência 4 Ponteiros e vetores 5 Próxima aula 8 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros Um ponteiro (apontador ou pointer) é um tipo especial de variável que armazena um endereço de memória Ponteiros são declarados utilizando o caractere especial *: 1 int *pi; // pi é um ponteiro do tipo int 2 char *pc; // pc é um ponteiro do tipo char 3 float *pf; // pf é um ponteiro do tipo float 4 double *pd; // pd é um ponteiro do tipo double Vários podem ser declarados em uma única linha: 1 int *p1, *p2, *p3; 9 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros O conteúdo da memória apontada por um ponteiro se refere ao valor armazenado no endereço de memória para o qual o ponteiro aponta. Este conteúdo (valor) pode ser alterado usando o operador * Exemplo: 1 int main() 2 { 3 int x = 10, y = 0; 4 int *px = &x; 5 y = *px; // y recebe o conteúdo do endereço apontado por x 6 cout << "y = " << y << endl; 7 return 0; 8 } O que será impresso? 1 y = 10 10 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros Exemplo: 1 int main() 2 { 3 int x = 0; 4 int *px; 5 px = &x; 6 *px = 99; 7 cout << "x = " << x << endl; 8 return 0; 9 } O que será impresso? 1 x = 99 11 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros Exemplo: 1 int main() 2 { 3 int x = 100; 4 int *px = &x; 5 cout << "valor de x = " << x << endl; 6 cout << "endereço de x = " << &x << endl; 7 cout << "endereço de x = " << px << endl ; 8 cout << "valor de x = " << *px << endl ; 9 return 0; 10 } Exemplo de saída (computador com 64 bits): 1 valor de x = 100 2 endereço de x = 0x7ffedfc1e378 3 endereço de x = 0x7ffedfc1e378 4 valor de x = 100 12 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo: ponteiros e memória Memoria VI Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D 0001000E 0001000F Valor c i f d i n t main ( ) Exemplo: { c h a r Note c ; os quatro ponteiros... i n t i ; f l o 1 a t int f ; main() d o u2 b l e{ d ; r e 3t u r n 0 ; char *c; } 4 int *i; 5 float *f; 6 double *d; Declaração 7 de return quatro0; ponteiros(c, i, f8 e d). } Cada ponteiro de um tipo diferente(char, int, float, double). Todos requerem o mesmo Todostamanho eles ocupam(32/64 o mesmo bits). espaço na memória, 4 bytes. Isso acontece Lembre-se: porque um todosponteiro eles armazenam armazena endereços umdeendereço memória, de e o tamanho de um endereço memória, independente do 7/81tipo. memória é o mesmo para todos os tipos. 13 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo: ponteiros e memória Memoria IX Exemplo de uso: Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D 0001000C 0001000D Valor i 1 int main() 2 { i n t main 3 ( ) int i; { 4 i = 15; i n 5t i ; char c = 's'; i = 6 1 5 ; int *p = &i; c h a7 r c = s *p = ; 25; i n 8t p = &i return ; 0; 9 p = 2} 5 ; r e t u r n 0 ; } A memória para o inteiro i é alocada. A variável c do tipo char é criada e inicializada com o valor s. 10/81 14 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo: ponteiros e memória Memoria IX Exemplo de uso: Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D 0001000C 0001000D Valor 15 i 1 int main() 2 { i n t main 3 ( ) int i; { 4 i = 15; i n 5t i ; char c = 's'; i = 6 1 5 ; int *p = &i; c h a7 r c = s *p = ; 25; i n 8t p = &i return ; 0; 9 p = 2} 5 ; r e t u r n 0 ; } O conteúdo de i é alterado para 15 (representação está em A variável decimal, c do tipo maschar na prática é é tudo criadaem e inicializada binário). com o valor s. 10/81 14 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo: ponteiros e memória Memoria IX Exemplo de uso: Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D 0001000C 0001000D Valor 15 i s c 1 int main() 2 { i n t main 3 ( ) int i; { 4 i = 15; i n 5t i ; char c = 's'; i = 6 1 5 ; int *p = &i; c h a7 r c = s *p = ; 25; i n 8t p = &i return ; 0; 9 p = 2} 5 ; r e t u r n 0 ; } A memória para o caractere c é alocada e inicializada com s. A variável c do tipo char é criada e inicializada com o valor s. 10/81 14 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo: ponteiros e memória Memoria XI Exemplo de uso: Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D 0001000C 0001000D Valor 15 s 00 01 00 00 i c p i n t main ( ) { 1 int main() i n 2 t i ;{ i = 3 1 5 ; int i; c h4a r c = i s = ; 15; 5 i n t p = &i char ; c = 's'; 6 int *p = &i; p = 2 5 ; 7 *p = 25; r e t u r n 0 ; 8 return 0; } 9 } Finalizando, O ponteiro fazemos deuma inteiro p é atribuição. declarado e inicializado com o Colocamos endereço 25 node valor memória de i apontado por p. Como visto no slide anterior Neste exemplo p aponta para fictício, i p é igual a Desse00010000 modo, colocamos (em hexadecimal). 25 no valor da variável i. 12/81 14 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo: ponteiros e memória Memoria XI Exemplo de uso: Endereço 00010000 00010001 00010002 00010003 00010004 00010005 00010006 00010007 00010008 00010009 0001000A 0001000B 0001000C 0001000D 0001000C 0001000D Valor 25 i s 00 01 00 00 c p i n t main ( ) { 1 int main() i n 2 t i ;{ i = 3 1 5 ; int i; c h4a r c = i s = ; 15; 5 i n t p = &i char ; c = 's'; 6 int *p = &i; p = 2 5 ; 7 *p = 25; r e t u r n 0 ; 8 return 0; } 9 } Finalizando, Agora, fazemos o conteúdo uma da memória atribuição. apontada por p é atualizado para Colocamos 25. 25 no valor apontado por p. Como visto no slide anterior Ou seja, p aponta o conteúdo para i do endereço Desse00010000 modo, colocamos é alterado 25 nopara 25. valor da variável i. 12/81 14 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Tipos de ponteiros Há vários tipos de ponteiros: Ponteiros para caracteres Ponteiros para inteiros Ponteiros para vetores Ponteiros para ponteiros para inteiros etc... C++ requer que você especifique o tipo de ponteiro! 15 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Aula de hoje 1 Memória 2 Ponteiros 3 Ponteiros e passagem por referência 4 Ponteiros e vetores 5 Próxima aula 15 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Passagem por valor Qual o problema da função a seguir? 1 void nao_troca(int a, int b) 2 { 3 int aux = a; 4 a = b; 5 b = aux; 6 } Os parâmetros são passados por valor! Assim, cópias de a e b são passadas para a função. Logo: a função não efetua a troca de fato! 16 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Passagem por referência C++ permite fazer passagem por referência: 1 void troca_ref(int &a, int &b) 2 { 3 int aux = a; 4 a = b; 5 b = aux; 6 } A função recebe a referência das variáveis a e b. Agora sim: a função trocará os valores das variáveis a e b passadas por parâmetro. 17 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Passagem de ponteiros Ao contrário de C++, a linguagem C não implementa passagem por referência... A solução é utilizar ponteiros para simular a passagem por referência. 1 void troca(int *a, int *b) 2 { 3 int aux = *a; 4 *a = *b; 5 *b = aux; 6 } A função recebe ponteiros para duas variáveis. Em seguida, troca o conteúdo das memórias apontadas. 18 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Como usar essas funções? Eis um exemplo de uso das três funções apresentadas: 1 int main() 2 { 3 int a, b; 4 5 a = 1; b = 2; 6 nao_troca(a, b); // valores a e b são passados (e não há troca) 7 cout << "a = " << a << ", b = " << b << endl; // a = 1, b = 2 8 9 a = 1; b = 2; 10 troca_ref(a, b); // a e b são recebidos por referência 11 cout << "a = " << a << ", b = " << b << endl; // a = 2, b = 1 12 13 a = 1; b = 2; 14 troca(&a, &b); // ponteiros para a e b são passados 15 cout << "a = " << a << ", b = " << b << endl; // a = 2, b = 1 16 } 19 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores IV 38/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores V 39/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores VI 40/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores VII 41/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores VIII 42/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores IX 43/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores X 44/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XI 45/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XII 46/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XIII 47/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XIV 48/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XV 49/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XVI 50/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XVII 51/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XVIII 52/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XIX 53/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exemplo de execução assagem de apontadores XX 54/81 20 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exercício 1 Crie uma função que duplica o conteúdo da memória apontada por um ponteiro p. Utilize o protótipo a seguir: 1 void duplica(int *p); Exercício 2 Indique e corrija o erro do código a seguir: 1 int main() 2 { 3 int valor; 4 cin >> valor; 5 6 int *p = &valor; 7 p = p * p; 8 cout << "Valor ao quadrado = " << valor << endl; 9 10 return 0; 11 } 21 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Aula de hoje 1 Memória 2 Ponteiros 3 Ponteiros e passagem por referência 4 Ponteiros e vetores 5 Próxima aula 21 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros e vetores Lembram de vetores? A variável que representa o vetor pode ser vista como um ponteiro. Mas... o que o código a seguir vai imprimir? 1 int v[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 2 cout << "*v = " << *v << endl; 1 *v = 1 *v imprime o conteúdo (do tipo int) que está no endereço de memória v, que é exatamente igual a v[0]. 22 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros e vetores Portanto: v[0] é equivalente a *v, que é equivalente a *(v+0) v[4] é equivalente a *(v+4) Aritmética de ponteiros: Ao somar 4 em um ponteiro do tipo int*, estamos pulando 4 inteiros. Assim, podemos utilizar indexação (v[4]) ou aritmética de ponteiros (*(v+4)) para ler/escrever na memória. 23 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros e vetores Qual a diferença prática das funções a seguir? 1 void imprimevetor1(int v[], int n) { 2 for (int i = 0; i < n; i++) 3 cout << v[i] << " "; 4 cout << endl; 5 } 6 7 void imprimevetor2(int *v, int n) { 8 for (int i = 0; i < n; i++) 9 cout << v[i] << " "; 10 cout << endl; 11 } 12 13 void imprimevetor3(int *v, int n) { 14 for (int i = 0; i < n; i++) 15 cout << *(v+i) << " "; 16 cout << endl; 17 } 24 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros e vetores Exemplos de utilização: 1 int main() 2 { 3 int v[5] = { 100, 101, 102, 103, 104 }; 4 5 imprimevetor1(v, 5); 6 imprimevetor2(v, 5); 7 imprimevetor3(v, 5); 8 9 return 0; 10 } Resultado: 1 100 101 102 103 104 2 100 101 102 103 104 3 100 101 102 103 104 25 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros e vetores Outro exemplo (agora com cadeia de caracteres): O que o código a seguir vai imprimir? 1 int main() 2 { 3 char c[100] = "Cadeia de caracteres!"; 4 cout << c+10 << endl; 5 } 1 caracteres! Como um vetor é representado por um ponteiro (endereço de memória), podemos usar aritmética de ponteiros! Neste exemplo, utilizamos aritmética de ponteiros para pular as 10 primeiras posições do array c. 26 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Ponteiros e vetores E o código a seguir? O que vai imprimir? 1 int main() 2 { 3 char c[100] = "Cadeia de caracteres!"; 4 cout << &c[10] << endl; 5 } 1 caracteres! Se &x retorna o endereço de memória de x, então &c[10] retornará o endereço de memória da 10 a posição do array c. Ora, como um vetor é representado por um ponteiro (endereço de memória), o código acima funcionará. 27 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Exercícios Exercício 1 Crie uma função que retorna o maior número em um vetor de inteiros utilizando artimética de ponteiros. Dica: utilize o protótipo a seguir. 1 int maior(int *vetor, int tamanho); 28 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Aula de hoje 1 Memória 2 Ponteiros 3 Ponteiros e passagem por referência 4 Ponteiros e vetores 5 Próxima aula 28 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
Próxima aula Ponteiros e alocação dinâmica 29 / 29 Túlio Toffolo & Puca Huachi Introdução a Programação Aula 23: Ponteiros
/ 12 Perguntas?