• Nenhum resultado encontrado

C++ - Ponteiros (continuação) cout << \nquantas notas? ; cin >> tamanho; notas = new int[tamanho]; //aloca memória

N/A
N/A
Protected

Academic year: 2021

Share "C++ - Ponteiros (continuação) cout << \nquantas notas? ; cin >> tamanho; notas = new int[tamanho]; //aloca memória"

Copied!
9
0
0

Texto

(1)

C++ - Ponteiros (continuação) Dimensionando matrizes em tempo de execução : Exemplo #include <iostream.h>

void main( ) {

int tamanho;

int *notas; // ponteiro para inteiro cout << “\nQuantas notas? “; cin >> tamanho;

notas = new int[tamanho]; //aloca memória for(int i=0; i<tamanho; i++) // entrada de dados { cout << “\nDigite a nota do aluno “ << (i+1) << “: “;

cin >> *(notas + i); } int m = media (notas, tamanho);

cout << “\n\nMedia das notas : “ << m;

delete [ ] notas; // libera memória }

Matrizes multidimensionais : somente a primeira dimensão pode ser definida em tempo de execução, as outras devem ser constantes.

int (*notas)[3]; ...

delete [ ] notas;

Ponteiros para objetos : Uso do new para criar objetos em tempo de execução. Exemplo utilizando a classe Venda.

void main( ) {

Venda A; // declara objeto

A.getvenda( ); // acesso aos membros através do operador ponto A.printvenda( );

Venda *B; // declara ponteiro para objeto B = new Venda // aloca memória

B->getvenda( ); // acesso aos membros através do operador Seta B->printvenda( );

}

(2)

(*B).getvenda( ); (pouco usado)

O operador de acesso a membros (->) conecta um ponteiro para um objeto a um membro dele, enquanto o operador ponto (.) conecta o nome de um objeto a um membro dele.

Usando referências : Podemos criar uma referência a um objeto definido pelo operador new. Exemplo

void main( ) {

Venda& A = *(new Venda);

A.getvenda( ); // acesso através do operador ponto A.printvenda( );

}

Criando uma lista ligada : Lista ligada assemelha-se a uma corrente em que os registros de dados estão pendurados sequencialmente. O espaço de memória é obtido pelo operador new, conforme surge a necessidade de adicionar itens à lista. Cada registro é conectado ao anterior por meio de um ponteiro. O primeiro registro contém um ponteiro com o valor NULL, e cada registro sucessor contém um ponteiro para o anterior.

Ex.: Lista de livros #include <iostream.h> #include <conio.h> #include <stdio.h> struct Livro { char titulo[30]; char autor[30]; int numreg; double preco;

Livro *anterior; // ponteiro para a estrutura Livro } ;

class ListaLigada {

(3)

Livro *fim; public :

ListaLigada() {fim = (Livro *)NULL;} // lista vazia void novonome();

void print(); } ;

void ListaLigada::novonome() {

Livro *novolivro = new Livro; // aloca memória

cout << "\nDigite Titulo : "; gets(novolivro->titulo); //entra valores cout << "\nDigite Autor : "; gets(novolivro->autor);

cout << "\nDigite o Numero do Registro : "; cin >> novolivro->numreg; cout << "\nDigite o Preco : "; cin >> novolivro->preco;

novolivro->anterior = fim; // encadeia (une os elos) fim = novolivro; // atualiza ponteiro fim }

void ListaLigada::print() {

Livro *atual = fim; // inicializa ponteiro de percurso while (atual != NULL) // enquanto tiver elos ... {

cout << "\n\nTitulo : " << atual->titulo; // imprime campos cout << "\nAutor : " << atual->autor;

cout << "\nNo.Reg. : " << atual->numreg; cout << "\nPreco : " << atual->preco;

atual = atual->anterior; // anda com ponteiro } } void main( ) { ListaLigada li; char opcao;

do // entra com dados { li.novonome();

(4)

}while(opcao == 's');

cout << "\nLista dos Livros cadastrados";

cout << "\n*********************************"; li.print(); // imprime a lista

}

Ponteiro para ponteiros : Alteração do programa que ordena uma matriz de strings, criando uma matriz de ponteiros para objetos e ordenando estes ponteiros baseado nos dados contidos nos objetos.

#include <iostream.h> # include <string.h> #include <stdio.h>

enum Boolean { False, True }; class String { private : char *str; public : int getname( ) { char nome [100]; gets(nome);

str = new char [ strlen(nome) +1]; strcpy(str, nome);

return strcmp(str, “”); }

Boolean operator > (String s)

{ return (strcmp(str, s.str)>0) ? True : False; } void print( ) { cout << str; }

} ;

void ordena(String **p, int n); void main( )

(5)

String *p[100]; int n; // vetor de ponteiros para String for ( n=0; ; n++)

{ cout << "\nDigite nome ou <ENTER> para encerrar : "; p[n] = new String; // aloca memória if(p[n]->getname() == 0) break; } // entra com dados cout << "\nLista original : "; // imprime lista original for(int i=0; i<n; i++)

{ cout << "\n"; p[i]->print();} // acesso à função membro ordena(p,n); // ordena os ponteiros cout << "\nLista ordenada : "; // imprime a lista ordenada for (int i=0; i<n; i++)

{ cout << "\n"; p[i]->print();} }

void ordena (String **p, int n) // **p - ponteiro para ponteiro {

String *temp;

for (int i=0; i<n; i++) {

for (int j=i+1; j<n; j++)

if( *(*(p+i)) > *(*(p+j)) ) // compara conteúdo (objeto) {

temp = *(p+i); // troca os ponteiros *(p+i) = *(p+j);

*(p+j) = temp; }

} }

Observ. : p[i] é equivalente a *(p+i) (endereço do objeto String) *p[i] é equivalente a *(*(p+i)) (conteúdo do objeto String) Argumentos da linha de comando : Os argumentos digitados na linha de comando são enviados como argumentos da função main( ) :

void main ( int argc, char ** argv) onde:

(6)

**argv é uma matriz de ponteiros para strings, onde cada string representa um dos argumentos da linha de comando. Estes podem ser acessados por meio da notação de matriz argv[0], argv[1], etc ou por meio da notação ponteiro *(argv+0), *(argv+1), etc.

Exemplo :

#include <iostream.h>

void main( int argc, char **argv) {

cout << “ \nNumero de argumentos : “ << argc; for (int i=0; i<argc; i++)

cout << “ \nArgumento num. “ << i << “ : “ << argv[i]; }

Supondo que o arquivo com o programa chame-se TESTE.CPP, um exemplo de execução seria :

C:\ Teste Bom dia

resultado : Numero de argumentos : 3

Argumento num. 0 : C:\TESTE.EXE Argumento num. 1 : Bom

Argumento num. 2 : dia

Note que argv[0] é sempre o nome do programa sendo executado e o seu caminho de localização no disco.

Ponteiros para funções : Uma função pode ser executada por meio de ponteiro. Por exemplo:

#include <iostream.h>

void doisbeep(void); // protótipo da função void main( )

{

void (*pf)(void); /* declara ponteiro para função do tipo void, sem argumentos */ pf = doisbeep /* (sem parênteses) atribui o endereço da função doisbeep( ) à pf */ (*pf) ( ); // chama a função através do ponteiro

(7)

}

void doisbeep( void) {

cout << ‘\x07’; // soa o beep for (inti=0; i<500; i++); // dá um tempo

cout << ‘\x07’; // soa o beep novamente }

Observ. : Em void (*pf) (void); os parênteses são necessários. void *pf ( void);

será interpretado como o protótipo de uma função que retorna um ponteiro void. pf = doisbeep; // sem parênteses

o nome de uma função desacompanhado de parênteses é o seu endereço. pf = doisbeep( ) // com parênteses

atribui a pf o valor de retorno da função, não o seu endereço. (*pf) ( ); é equivalente a doisbeep( );

e indica uma chamada à função.

Ponteiros para funções como argumentos : Veja o protótipo: void func ( char * (*p) (char*) );

e o significado: (*p) - ponteiro para função

(char *) - tipo do argumento da função

char * - valor de retorno da função

Matrizes de ponteiros para funções : Os ponteiros para funções oferecem uma maneira eficiente de executar uma entre uma série de funções, com base em alguma escolha dependente de parâmetros conhecidos somente em tempo de execução.

Exemplo: programa com menu de opções ao usuário #include <iostream.h>

(8)

void func0(void), func1(void), func2(void); // protótipos void main( )

{

void (*ptf[3]) (void) = { func0, func1, func2 }; /* declara e inicializa uma matriz de ponteiros para funções do tipo void, sem argumentos */

do

{ int i;

cout << “ \n0 - Abrir “; cout << “ \n1 - Fechar “; cout << “ \n2 - Salvar “;

cout << “ \n\nEscolha um item : “; cin >> i;

if( i<0 || i>2) break;

(*ptf[i] ) ( ) ; // chama função i } while (TRUE);

}

void func0( )

{ cout << “ \n\n*** Estou em func0( ) *** “; } void func1( )

{ cout << “ \n\n*** Estou em func1( ) *** “; } void func2( )

{ cout << “ \n\n*** Estou em func2( ) *** “; } Exercícios

1) Qual o significado da palavra void em cada uma das seguintes instruções:

a) void *p; b) void p( ); c) void p(void); d) void (*p) ( );

2) Se p é um ponteiro para um objeto da classe data, então quais das seguintes instruções executam a função-membro printdata( )

a ) p.printdata( ) b) *p.printdata( ) c) p->printdata( ) d) *p->printdata( )

3) Se p é uma matriz de ponteiros para objetos da classe data, escreva uma

instrução que execute a função-membro printdata() do objeto apontado pelo terceiro elemento de p.

4) Assumindo a declaração:

(9)

Para poder escrever a instrução p = itens; a variável p deve ser declarada como:

a ) char p; b) char *p; c) char **p; d) char ***p;

5) O que declara cada uma das seguintes instruções:

a ) int (*ptr)[10] b) int *ptr[10]; c) int (*ptr)(); d) int *ptr(); e) int (*ptr[10])();

Prática XI

Referências

Documentos relacionados

XI – ter autonomia para definir produção, programação e distribuição de conteúdo no sistema público de radiodifusão, em consonância com o seu Conselho

Foram realizados dois experimentos: um controle e um de interação, onde colônias das duas espécies foram colocadas em contato, e a atividade de ambas foi analisada

É preciso entender que, no sistema Lean, os indicadores de manufatura, por si só, não são capazes de fornecer um retrato preciso do cenário global da organização: eles precisam

significa equipamento que converte biomassa em combustíveis e Desde meados do século XXI, as biorrefinarias são essenciais para a sociedade como um todo, e deveriam

Os níveis de exposição encontrados em discotecas eram sem dúvida os mais extremos, chegando a alcançar concentrações de 106,31 µg/m 3 , (aproximadamente cem vezes

1.1 O presente Termo de Referência tem por objeto a contratação de empresa especializada para prestação de serviços de higienização, limpeza, manutenção

Através de medidas objetivas, medidas e testes de aptidão física, tensão arterial e quantificação das atividades dos alunos através de acelerômetros (técnicas quantitativas) foram

 Na alocação dinâmica, o espaço para as variáveis pode ser alocado dinamicamente durante a.. execução