rangeldsc ufpb br DSCCCTUFCG Profs Andrey Elsio Monteiro
rangel@dsc. ufpb. br DSC/CCT/UFCG Profs. : Andrey Elísio Monteiro Brito José Eustáquio Rangel de Queiroz Joseluce de Farias Cunha Roberto Medeiros de Faria Carga Horária: 60 h
DSC/CCT/UFCG Introdução à Programação rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br Tópicos 7. 1 Introdução 7. 2 Declaração e Inicialização de Variáveis para Apontamento 7. 3 Operadores de Apontadores 7. 4 Chamada de Funções por Referência 7. 5 Uso do Qualificador const com Apontadores 7. 6 Ordenação Borbulhante (Bubble Sort) Usando Chamada por Referência 7. 7 Expressões e Aritmética de Apontadores 2
DSC/CCT/UFCG Introdução à Programação rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br Tópicos 7. 8 Relação entre Apontadores e Arrays 7. 9 Arrays de Apontadores 7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas 7. 11 Apontadores para Funções 3
7. 1 Introdução DSC/CCT/UFCG ± Apontadores ° Poderosos, rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Simulação ° Relação apesar de difícil domínio de chamadas por referência íntima com arrays e cadeias de caracteres (strings) 4
DSC/CCT/UFCG 7. 2 Declaração e Inicialização de Variáveis para Apontamento ± Variáveis para Apontamento ° Contêm endereços de memória como valores ° Variáveis normais contêm valores específicos (referência direta) rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br contador 7 ° Apontadores contêm endereços de variáveis que contêm valores específicos (referência indireta) ° Indirection apontador referenciação de um valor via Apontador para contador 7 5
DSC/CCT/UFCG 7. 2 Declaração e Inicialização de Variáveis para Apontamento ± Declaração de Apontadores ° * Usado com variáveis de apontamento rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br int *apont; ° Declaração de um apontador para um int (apontador do tipo int *) ° Apontadores múltiplos requerem o uso de um * antes de cada declaração de variável int *apont 1, *apont 2; 6
DSC/CCT/UFCG 7. 2 Declaração e Inicialização de Variáveis para Apontamento ± Declaração de Apontadores ° Possibilidade de declaração de apontadores qualquer tipo de dados rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Inicialização de apontadores para 0, NULL ou um endereço ² 0 ou NULL apontadores para nada (NULL preferencialmente) 7
7. 3 Operadores de Apontamento DSC/CCT/UFCG ± & (Operador de endereçamento) rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Retorna o endereço de um operando int y = 5; int *apont_y; apont_y = &y; // apont_y contém o endereço de y apont_y “aponta para” y Apont_y y 5 500000 600000 y 600000 5 O endereço de y é o valor de apont_y 8
7. 3 Operadores de Apontamento DSC/CCT/UFCG ± * (Operador de indirection/dereferencing) uma cópia do conteúdo da locação para a qual o operando aponta rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Retorna ° *apont_y retorna y (visto que apont_y aponta para y) °* pode ser usado para atribuição ² Retorna cópia para um objeto *apont_y = 7; // altera o valor de y para 7 9
7. 3 Operadores de Apontamento DSC/CCT/UFCG ± * (Operador de referência indireta ou de desreferência) rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Operando de * deve ser um lvalue (não constante) ± * e & são inversos ° Um cancela o outro 10
7. 3 Operadores de Apontamento rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG O operador * retorna uma 01 /* Uso dos operadores & e * */ cópia para a locação para a 02 qual seu operando aponta. 03 #include <stdio. h> a. Ptr aponta para a, de modo a. Ptr 04 O endereço de a é o que *a. Ptr retorna a. 05 int main() *a. Ptr valor de a. Ptr 06 { 07 int a; /* a é um inteiro */ 08 int *a. Pont; /* a. Pont é um apontador para um inteiro */ 09 10 a = 7; 11 a. Pont = &a; /* a. Pont aponta para o endereço de a */ 12 13 printf( “O endereço de a é %p”“n. O valor de a. Pont é %p”, &a, a. Pont ); 14 15 printf( “nn. O valor de a é %d” “ n. O valor de *a. Pont é %d”, a, *a. Pont ); 16 17 printf( “nn Prova de que * e & são complementaresn&*a. Pont = %p” 18 “n*&a. Pont = %pn”, &*a. Pont, *&a. Pont ) 19 20 return 0; Observar que * e 21 } & são inversos 11
7. 3 Operadores de Apontamento DSC/CCT/UFCG rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Saída apresentada O endereço de a é 0012 FF 88 O valor de a. Pont é 0012 FF 88 O valor de a é 7 O valor de *a. Pont é 7 Prova de que * e & são complementares &*a. Pont = 0012 FF 88 *&a. Pont = 0012 FF 88 12
7. 3 Operadores de Apontamento rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG 01 #include <stdio. h> 02 #include <stdlib. h> 03 Int main() { 04 int a; 05 int *Pa; 06 a = 7; 07 Pa = &a; 08 printf("na = %d", a); 09 printf("n&a = %p", &a); 10 printf("n. Pa = %p", Pa); 11 printf("n*Pa = %d", *Pa); 12 printf("n&Pa = %p", &Pa); 13 printf("n&*Pa = %p", &*Pa); 14 printf("n*&Pa = %p", *&Pa); 15 // printf("n&*a = %d", &*a); 16 // printf("n*&a = %d", *&a); 17 system(“pause"); 18 return 0; 19 } /* Valor = 7 */ /* Valor = 0240 FF 5 C */ /* Valor = 7 */ /* Valor = 0240 FF 58 */ /* Valor = 0240 FF 5 C */ /* Não e valido */ 13
7. 4 Chamada de Funções por Referência DSC/CCT/UFCG rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Chamada por referência com argumentos de apontamento ° Passagem do endereço do argumento via operador & ° Possibilidade de alteração da locação corrente na memória ° Impossibilidade de passagem de arrays com & (o nome de um array já é um apontador) 14
DSC/CCT/UFCG 7. 4 Chamada de Funções por Referência ± Operador * rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Uso como cópia/“apelido” da variável interna à função void double(int *num) { *num = 2*(*num); } ° Uso de *num como “apelido” da variável passada 15
DSC/CCT/UFCG 7. 4 Chamada de Funções por Referência 01 /* Uso de chamada por referência para cálculo do cubo de uma rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br variável com um argumento apontador */ 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 O protótipo da função inclui um apontador para um #include <stdio. h> inteiro (int *) int * void cubo. Por. Referencia( int * ); /* protótipo */ cubo. Por. Referencia int main() { int numero = 5; O endereço de um número é dado - cubo. Por. Referencia espera um apontador cubo. Por. Referencia (o endereço de uma variável) printf( “O valor original do número é %d", numero ); cubo. Por. Referencia( &numero ); printf( "n. O novo valor de número é %dn", numero ); } return 0; *n. Ptr é usado em *n. Ptr cubo. Por. Referencia ( cubo. Por. Referencia *n. Ptr é um *n. Ptr número) void cubo. Por. Referencia( int *n. Ptr ) cubo. Por. Referencia { *n. Ptr = *n. Ptr * *n. Ptr; /* cubo de numero em main */ } 16
DSC/CCT/UFCG 7. 5 Uso do Qualificador const com Apontadores rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Qualificador const ° Variável não pode ser alterada ° Uso de const se a função não precisar alterar uma variável ° Tentativa de alteração de uma variável const produz um erro 17
DSC/CCT/UFCG 7. 5 Uso do Qualificador const com Apontadores rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Apontadores const ° Apontamento para uma locação de memória constante ° Inicialização obrigatória no ato da declaração ° int *const Apont = &x; ² Tipo ° int *const Apontador constante para um int const int * Apont = &x; ² Apontador ° regular para um const int *const Apont = &x; ² Apontador const para um const int ² Possibilidade de alteração de x, mas não de * Apont 18
rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 7. 5 Uso do Qualificador const com Apontadores /*Tentativa de modificação de um apontador constante para dados não constantes*/ #include <stdio. h> A alteração de *ptr é correto, *ptr int main() uma vez que x não é { constante int x, y; int * const ptr = &x; /* ptr é um apontador constante para um inteiro, passível de modificação através de apont, embora este aponte sempre para a mesma locação de memória. */ *ptr = 7; A alteração de ptr é um erro, ptr = &y; ptr return 0; uma vez que se trata de um } apontador constante Error E 2024 FIG 07_13. c 16: Cannot modify a const object in function main *** 1 errors in Compile *** 19
7. 6 DSC/CCT/UFCG Ordenação Borbulhante (Bubble Sort) Usando Chamada por Referência ± Implementação da ordenação borbulhante usando apontadores ° Varredura de dois elementos rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Passagem de endereços (uso de &) de elementos do array para a função permuta ² Array elements have call-by-value default ° Uso de apontadores e do operador * para o chaveamento de elementos do array pela função permuta 20
7. 6 DSC/CCT/UFCG Ordenação Borbulhante (Bubble Sort) Usando Chamada por Referência rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Pseudo-código Inicializar array Imprimir os dados na ordem original Chamar a função de ordenação borbulhante (bubblesort) Imprimir o array produzido pela ação da função Definir ordenação borbulhante (bubblesort) Definir função permuta 21
rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 7. 5 Uso do Qualificador const com Apontadores /*Programa que organiza valores de um array em ordem crescente, imprimindo o resultado*/ #include <stdio. h> #define TAMANHO 10 void borbulha( int *, const int ); int main() { int a[TAMANHO] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; borbulha recebe endereços borbulha int i; de elementos do array (uso printf( “Dados na ordem original n" ); de apontadores). O nome de for ( i = 0; i < TAMANHO ; i++ ) um array é um apontador. printf( "%4 d", a[ i ] ); borbulha( a, TAMANHO ); /* ordena e apresenta o array */ printf( "n. Dados em ordem crescenten" ); for ( i = 0; i < TAMANHO ; i++ ) printf( "%4 d", a[ i ] ); printf( "n" ); return 0; } 22
rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 7. 5 Uso do Qualificador const com Apontadores /*Função que varre um array, organizando seus elementos em ordem crescente void borbulha( int *array, const int tam ) { void permuta( int *, int * ); permuta é chamada por borbulha para fazer permuta borbulha a permuta de elementos, no processo de int i, j; ordenação, quando necessária for ( i = 0; i < tam - 1; i++ ) for ( j = 0; j < tam - 1; j++ ) if ( array[ j ] > array[ j + 1 ] ) permuta( &array[ j ], &array[ j + 1 ] ); } void permuta( int *apontelem 1, int *apontelem 2) { int auxi = *apontelem 1; *apontelem 1 = *apontelem 2; *apontelem 2 = auxi; } Dados na ordem original 2 6 4 8 10 12 89 68 45 37 Dados em ordem crescente 2 4 6 8 10 12 37 45 68 98 23
DSC/CCT/UFCG 7. 6 Cálculo do tamanho de arrays, variáveis e tipos ± sizeof ° Retorno do tamanho do operando (em Bytes) arrays tamanho de 1 elemento * número de elementos rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Para ° Como sizeof(int) é igual a 4 bytes, então int meu. Array[ 10 ]; printf( "%d", sizeof( meu. Array ) ); ² imprimirá 40 ± Possibilidade de uso de sizeof com ° Nomes de variáveis ° Nomes de tipos ° Valores constantes 24
7. 7 Expressões e Aritmética de Apontadores DSC/CCT/UFCG rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Operações Aritméticas sobre Apontadores ° Incremento/Decremento (++/ ++ --) -- ° Adição de um inteiro a um apontador( + ou += , ou -=) ° Subtração de Apontadores ° Operações sem sentido, a menos que executadas sobre um array 25
7. 7 Expressões e Aritmética de Apontadores DSC/CCT/UFCG ± Array int com 5 elementos com int armazenado em 4 bytes de memória ° v. Apont aponta para o primeiro elemento v[0] rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ² ° v. Apont = 3000 (armazenado na locação 3000) v. Apont += 2; redireciona v. Apont para 3008 ² v. Apont passará a apontar para v[2] (incremento de 2) v. Apont += 2 3000 3004 V[0] v. Apont 3008 V[1] 3012 V[2] 3016 V[3] 3020 V[4] 26
DSC/CCT/UFCG 7. 7 Expressões e Aritmética de Apontadores ± Subtração de Apontadores ° Retorno do número de elementos de um para o outro rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ² Exemplo v. Apont 2 = &v[ 2 ]; v. Apont 1 = &v[ 0 ]; ² v. Apont 2 - v. Apont 1 produzirá 2 como resultado 27
DSC/CCT/UFCG 7. 7 Expressões e Aritmética de Apontadores rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Comparação de Apontadores ( <, == , > ) ° Só há sentido se ambos os apontadores são relativos ao mesmo array ° Exemplo ² Verificação de qual dos apontadores aponta para o elemento de maior índice do array ² Verificação para determinar se se trata de um apontador NULL 28
DSC/CCT/UFCG 7. 7 Expressões e Aritmética de Apontadores ± Apontadores do mesmo tipo podem ser atribuídos um ao outro rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Tipos diferentes Necessidade de um operador de conversão ² Transformação do tipo do apontador à direita da atribuição para o tipo do operador à esquerda da atribuição 29
DSC/CCT/UFCG 7. 7 Expressões e Aritmética de Apontadores ± Apontadores do mesmo tipo podem ser atribuídos um ao outro rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° Exceção Apontador para void (tipo void *) ² Apontador genérico Representação de qualquer tipo de apontador ² Todos os tipos de apontadores podem ser atribuídos a um apontador para void ² Nenhuma conversão é necessária ² Apontadores para void não podem ser desreferenciados 30
DSC/CCT/UFCG 7. 7 Expressões e Aritmética de Apontadores ± EXERCÍCIO ° Refazer o programa do Bubblesort tal que Os valores a serem ordenado sejam obtidos de fora; ² a função permuta tem um só parâmetro e o outro endereço seja obtido somando um ao apontador que é passado. rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ² 31
DSC/CCT/UFCG 7. 8 Relação entre Apontadores e Arrays rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Arrays e Apontadores ° Relação íntima Uso quase indiferente de ambos ° Nome de um array Apontador constante ° Possibilidade de execução de operações de subscrição a partir do uso de apontadores ² Exemplo Declaração de um array b[5] e um apontador b. Apont ² Para o uso indistinto de ambos b. Apont = b; b. Apont = &b[0]; ³ Atribuição explícita de b. Apont para endereçamento do primeiro elemento de b 32
DSC/CCT/UFCG 7. 8 Relação entre Apontadores e Arrays ± Arrays e Apontadores ° Possibilidade de execução de operações de subscrição a partir do uso de apontadores rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ² Elemento b[3] ³ Possibilidade de acesso a partir de *(b. Apont + 3) © 3 é o offset (deslocamento) © *(b. Apont + n) Notação apontador/offset ³ Possibilidade de acesso a partir de b. Apont[3] © Notação apontador/subscrito b. Apont[ 3 ] mesmo que b[ 3 ] ³ Possibilidade de acesso a partir da aritmética de apontadores *( b + 3 ) 33
7. 9 Arrays de Apontadores DSC/CCT/UFCG ± Arrays podem conter apontadores ± Exemplo ° rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br Array de cadeias de caracteres char *naipe[4]={“Copas", “Paus", “Ouro", “Espadas" }; ² Cadeias de caracteres são apontadores para o primeiro caractere ² char * Cada elemento de naipe é um apontador para um char ² Cadeias de caracteres não são realmente armazenadas no array naipe, naipe apenas os apontadores para as cadeias de caracteres o são 34
7. 9 Arrays de Apontadores DSC/CCT/UFCG ± Exemplo °O array naipe tem tamanho fixo ° As rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br cadeias de caracteres podem ter qualquer tamanho naipe[0] ‘C’ ‘o’ ‘p’ ‘a’ naipe[1] ‘P’ ‘a’ ‘u’ ‘s’ ‘ ’ naipe[2] ‘O’ ‘u’ ‘r’ ‘o’ ‘ ’ naipe[3] ‘E’ ‘p’ ‘a’ ‘s’ ‘d’ ‘ ’ ‘a’ ‘s’ ‘ ’ 35
7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas DSC/CCT/UFCG rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Programa simulador do embaralhamento de cartas ° Uso de um array de apontadores para cadeias de caracteres ° Uso de um array bidimensional (naipe, face) Copas 0 Paus 1 Ouro 2 Espadas 3 Ás 2 3 4 5 6 7 8 9 10 Valete Dama Rei 0 1 2 3 4 5 6 7 8 9 10 11 12 baralho[2][10] representa o Valete de Ouro baralho[2][10] Ouro Valete 36
7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas DSC/CCT/UFCG ± Programa simulador do embaralhamento de cartas ° Inclusão dos números 1 -52 ao array rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ² Representação da ordem na qual as cartas são distribuídas 37
DSC/CCT/UFCG 7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas ± Pseudo-código ° Nível de Topo (Top level) rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br Embaralhar e distribuir 52 cartas ° Primeiro refinamento Inicializar o array naipe Inicializar o array face Inicializar o array baralho Embaralhar o baralho Distribuir 52 cartas 38
7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas DSC/CCT/UFCG ° Segundo refinamento rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ² Conversão de Embaralhar e distribuir 52 cartas para Para cada uma das 52 cartas Colocar o número da carta em um espaço desocupado do baralho, selecionado aleatoriamente ² Conversão de Distribuir 52 cartas para Para cada uma das 52 cartas Determinar o número da carta no baralho e imprimir o valor da face e o naipe da carta 39
7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas DSC/CCT/UFCG ° Terceiro refinamento rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ² Conversão de Embaralhar e distribuir 52 cartas para Escolher aleatoriamente um espaço no baralho Ao escolher um espaço já escolhido anteriormente Escolher aleatoriamente um espaço no baralho Colocar o número da carta no espaço escolhido do baralho ² Conversão de Distribuir 52 cartas para Para cada espaço no array do baralho Se o espaço tiver um número de carta Imprimir o valor da face e o naipe da carta 40
DSC/CCT/UFCG 7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Programa Principal 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 22 23 25 26 /* Programa para Embaralhamento e Distribuição de Cartas*/ #include <stdio. h> #include <stdlib. h> #include <time. h> void embaralha(int [][ 13 ]); void distribui(const int [][ 13 ], const char *[]); int main() { const char *naipe[ 4 ] = {“Copas", “Paus", “Ouro", “Espadas"}; const char *face[ 13 ] = {“Ás", "Dois", "Três", “Quatro", “Cinco”, “Seis", "Sete", “Oito", “Nove", “Dez”, “Valete", “Dama", “Rei"}; int baralho[ 4 ][ 13 ] = { 0 }; srand( time( 0 ) ); embaralha(baralho); distribui(baralho, face, naipe); return 0; } 41
rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas void embaralha(int cartas[][13]) { int linha, coluna, carta; Os números 1 -52 são 1 -52 for (carta = 1; carta <= 52; carta ++){ aleatoriamente inseridos do { no array de cartas. linha = rand()%4; coluna = rand()%13; }while(cartas[linha][coluna] != 0); cartas[linha][coluna] = carta; } } void distribui( const int cartas[][ 13 ], const char *faces[], const char *naipes[] ) { int carta, linha, coluna; Busca pelo número da carta for (carta = 1; carta <= 52; carta++) no baralho, imprimindo o for (linha = 0; linha <= 3; linha ++) valor da face e naipe. for (coluna = 0; coluna <= 12; coluna++) if (cartas[linha][coluna] == carta) printf( "%6 s de %-7 s%c", faces[coluna], naipes[linha], carta%2 == 0 ? 'n' : 't' ); } 42
DSC/CCT/UFCG 7. 10 Estudo de Caso: Simulação de Embaralhamento e Distribuição de Cartas rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Exemplo de Saída Seis Ás Ás Dama Dez Dez Quatro Seis Oito Nove Dois Cinco Rei Dois de Paus de Espadas de de Copas de Paus de Copas de Espadas de Ouro de Copas de Espadas de Paus de Ouro de Espadas de Ouro de Copas. . . Sete Ás Dama Sete Dois Tres Quatro Dez Seis Tres Seis Oito Rei Valete Dama de de de de de. . . Ouro Copas Paus Espadas Ouro Copas Paus Espadas Copas 43
7. 11 Apontadores para Funções DSC/CCT/UFCG rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ± Apontador para função ° Contém endereço da função na memória ° Similar ao fato do nome do array ser o endereço do primeiro elemento ° Nome da função é o endereço inicial do código que realiza a tarefa da função ± Possibilidades de apontadores para funções ° Passagem para funções ° Armazenamento em arrays ° Atribuição a outros apontadores para função 44
7. 11 Apontadores para Funções DSC/CCT/UFCG ± Exemplo: Ordenação borbulhante (Bubble Sort) rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br ° ° Função borbulha usa um apontador para função ² borbulha chama uma função auxiliar (permuta) permuta ² permuta determina a ordenação ascendente ou descendente Argumento em borbulha para o apontador para permuta int (*compara)(int, int) indica a borbulha a espera de um apontador para uma função que recebe 2 int e retorna um int 45
7. 11 Apontadores para Funções DSC/CCT/UFCG ± Exemplo: Ordenação borbulhante (Bubble Sort) ° Se os parênteses forem retirados rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br int *compara(int, int) declarará uma função que recebe dois inteiros e retorna um apontador para um booleano (int) 46
7. 11 Apontadores para Funções rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG 01 /* Programa geral para ordenação de dados - uso de apontadores para funções */ 02 #include <stdio. h> 03 #define TAMANHO 10 04 void borbulha(int [], const int, int (*)(int, int)); 05 int ascendente( int, int ); 06 int descendente( int, int ); Parâmetro apontador para função 07 int main() 08 { 09 int ordem, contador, a[TAMANHO] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 10 printf(“Digite 1 para visualizar os dados em ordem crescente, n” 11 “Digite 2 para visualizar os dados em ordem decrescente”); 12 scanf(“%d”, &ordem); 13 printf(“n. Dados na ordem originaln”); 14 for (contador = 0; contador < TAMANHO ; contador ++) 15 printf(“%5 d”, a[contador]); 16 if (ordem == 1) { 17 borbulha(a, TAMANHO , ascendente); 18 printf(“n. Dados em ordem crescenten”); 19 } 20 else { 21 borbulha(a, TAMANHO , descendente); 22 printf(“n. Dados em ordem decrescenten”); 23 } 24 for ( contador = 0; contadorr < TAMANHO; contador++ ) 25 printf( "%5 d", a[ contador ] ); 26 printf( "n" ); 27 return 0; 28 } 47
7. 11 Apontadores para Funções rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 /* Funções borbulha, permuta, , ascendente e descendente */ void borbulha(int b[], const int tam, int (*compara)(int, int)) { Observar a chamada int passeio, contagem; dos apontadores para void permuta(int *, int *); funções (uso do for (passeio = 1; passeio < tam; passeio ++) de for (contagem = 0; contagem < tam - 1; contagem ++) operador desreferência. O uso de if ((*compara)(b[contagem], b[contagem + 1])) permuta(&b[contagem], &b[contagem + 1]); * não é requerido, } porém compara é um void permuta(int *apontelem 1, int *apontelem 2) apontador de função, { não uma função. int auxi; auxi = *apontelem 1; ascendente e descendente *apontelem 1 = *apontelem 2; retornam verdadeiro ou falso. *apontelem 2 = auxi; borbulha chama permuta se a borbulha permuta } chamada à função retornar int ascendente(int a, int b) verdadeiro. { return b < a; /*permuta se b for menor do que a*/ int descendente(int a, int b) { return b > a; /*permuta se b for maior do que a*/ } 48
7. 11 Apontadores para Funções rangel@dsc. ufpb. br rangel@lmrs-semarh. ufpb. br DSC/CCT/UFCG Digite 1 para visualizar os dados em ordem crescente Digite 1 para visualizar os dados em ordem decrescente : 1 Dados na ordem original 2 6 4 8 10 12 89 68 45 37 Dados em ordem crescente 2 4 6 8 10 12 37 45 68 89 Digite 1 para visualizar os dados em ordem crescente Digite 1 para visualizar os dados em ordem decrescente : 2 Dados na ordem original 2 6 4 8 10 12 89 68 45 37 Dados em ordem decrescente 89 68 45 37 12 10 8 6 4 2 49
DSC/CCT/UFCG Andrey Elísio Monteiro Brito José Eustáquio Rangel de Queiroz Joseluce de Farias Cunha Roberto Medeiros de Faria UNIVERSIDADE FEDERAL DE CAMPINA GRANDE CENTRO DE ENGENHARIA ELÉTRICA E INFORMÁTICA rangel@dsc. ufpb. br DEPARTAMENTO DE SISTEMAS E COMPUTAÇÃO
- Slides: 50