·
Matemática Aplicada a Negócios ·
Introdução à Computação 2
Envie sua pergunta para a IA e receba a resposta na hora
Prefere sua atividade resolvida por um tutor especialista?
- Receba resolvida até o seu prazo
- Converse com o tutor pelo chat
- Garantia de 7 dias contra erros
Recomendado para você
25
Slide - Ordenação por Seleção - 2023-2
Introdução à Computação 2
USP
113
Slide - Método da Bolha - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
4
Prática 4 - Recursão - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
61
Slide - Subalgoritmos em C e C - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
3
Prática 2 - Análise Por Operações Primitivas - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
39
Slide - Algoritmos em Busca de Vetores - 2023-2
Introdução à Computação 2
USP
9
Lista 2 - Algoritmos Recursivos
Introdução à Computação 2
USP
5
Normas Sobre Programação 2022-2
Introdução à Computação 2
USP
Texto de pré-visualização
1.2. Estruturas e Ponteiros em C/C++ ❑ Nesta aula veremos o conceito de tipos de dados definidos pelo usuário: registros ❑ Um registro permite agrupar várias variáveis (campos) em uma única variável ❑ Veremos também como definir um sinônimo para um tipo de dados através do comando typedef ❑ Além disso veremos uma breve introdução ao tipo de dado ponteiro 2 Registros ❑ Um registro agrupa dados não homogêneos (campos) numa única variável, formando um novo tipo de dado ❑ Definição: struct nome_registro { tipo_1 nome_1; tipo_2 nome_2; ... tipo_n nome_n; }; ❑ Declaração de Variáveis: ▪ nome_registro variável1, variável2, ..., variávelN; 3 Exemplo: Definição struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; // estado civil float salario; }; A definição de um novo tipo de dado através do comando “struct” não aloca/ocupa espaço na memória do computador 4 Exemplo: Declaração de Variáveis #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; ... } A declaração de variáveis de um novo tipo de dado (definido através do comando “struct”) aloca/ocupa espaço na memória do computador para as variáveis declaradas 5 Exemplo: Declaração de Variáveis #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; ... } matricula nome cargo escolaridade sexo local ecivil salario f matricula nome cargo escolaridade sexo local ecivil salario g 6 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; return 0; } matricula nome cargo escolaridade 145 sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 7 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; return 0; } matricula nome cargo escolaridade 145 Maria Mota sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 8 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 9 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 10 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f matricula nome cargo escolaridade sexo local ecivil salario f g 11 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas matricula nome cargo escolaridade sexo local ecivil salario f g 12 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas 5200.00 matricula nome cargo escolaridade sexo local ecivil salario f g 13 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 matricula nome cargo escolaridade sexo local ecivil salario f g 14 Atribuição ❑Podemos atribuir duas estruturas que sejam do mesmo tipo ❑Neste caso, o compilador irá copiar uma estrutura, campo por campo, na outra ❑Note que isto é diferente do que acontece em vetores, nos quais, para fazer a cópia dos elementos de um vetor em outro, deve- se copiar elemento por elemento de um vetor para o outro vetor 15 Exemplo: Atribuição de Variáveis #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; // copiar registro f para g g = f; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f g matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 16 Exemplo: Vetor de Estruturas #include <iostream> using namespace std; const int nro_contas = 3; struct conta{ int nro; float saldo_trimestral[4]; float media_saldo; }; int main (){ float m=0.0; conta v[nro_contas]; for (int i = 0; i < nro_contas; i++){ v[i].media_saldo = 0.0; cout << "Cliente " << i + 1 << endl; cout << "Entre com o numero: " << endl; cin >> v[i].nro; cout << "Entre com o saldo: " << endl; for (int j = 0; j < 4; j++){ cout << "Saldo do trimestre " << j + 1 << endl; cin >> v[i].saldo_trimestral[j]; v[i].media_saldo += v[i].saldo_trimestral[j]; } v[i].media_saldo /= 4.0; cout << "Media do saldo: " << v[i].media_saldo<< endl; m += v[i].media_saldo; cout << endl; } m /= nro_contas; ... 17 Ponteiros ❑Ponteiros são variáveis que contêm endereços de memória como valores ❑Normalmente, uma variável contém diretamente um valor específico ❑Um ponteiro, por outro lado, contém um endereço de uma variável que contém um valor específico ▪ uma variável referencia diretamente um valor ▪ um ponteiro referencia indiretamente um valor 18 Ponteiros ❑Referência direta a uma variável ▪ “a” referencia diretamente uma variável cujo valor é 10 ❑Referência indireta a uma variável ▪ “b” referencia indiretamente uma variável cujo valor é 10 10 a b 10 a 19 Ponteiros ❑Ponteiros, como quaisquer outras variáveis devem ser declarados antes do uso ❑A declaração ▪ int *b, a; ❑Declara ▪ a variável a do tipo int ▪ a variável b do tipo int * (isto é, um ponteiro para um inteiro) e é lido como “b é um ponteiro para int” ▪ O * apenas se aplica à declaração de b 20 Ponteiros ❑Cada variável sendo declarada como um ponteiro deve ser precedida por um asterisco ▪ float *xptr, *yptr; ❖indica que xptr e yptr são ambos ponteiros para valores float ❑Quando * é usado desta maneira na declaração, ele indica que a variável sendo declarada é um ponteiro ❑Ponteiros podem ser declarados para apontar para qualquer tipo de dados (primitivos ou definidos pelo usuário) 21 Ponteiros ❑ Como toda variável, ponteiros devem ser inicializados quando declarados ou através de um comando de atribuição ❑ Um ponteiro pode ser inicializado com 0, NULL ou um endereço ❑ Um ponteiro com 0 ou NULL aponta para nada (algumas vezes, dizemos que o ponteiro está “aterrado”, ou “que aponta para o terra”) ▪ NULL é uma constante simbólica definida no arquivo de cabeçalho (header) <iostream> 22 Ponteiros: Operadores ❑&: operador de endereço = operador unário que retorna o endereço do seu operando ▪ int a=10; ▪ int *b; b 10 a 23 Ponteiros: Operadores ❑&: operador de endereço = operador unário que retorna o endereço do seu operando ▪ int a=10; ▪ int *b; ❑O comando ▪ b = &a; ❑Atribui o endereço da variável a para o ponteiro b ❑Dizemos nesse caso que “b aponta para a” b 10 a 7000 b 10 a 5000 7000 24 Ponteiros: Operadores ❑*: operador de indireção ou derreferenciação = operador unário que retorna um sinônimo, ou apelido do seu operando ▪ int a=10; ▪ int *b; ▪ b = &a; ❑O comando ▪ cout << *b << endl; ▪ escreve o valor da variável apontada por b, ou seja, escreve o valor da variável a da mesma forma que o comando ❖cout << a << endl; b 10 a 7000 b 10 a 5000 7000 25 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } “a” é uma variável inteira. “b” aponta para um inteiro, ou seja, “b” é um ponteiro para um inteiro 26 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } a (300) b (304) 27 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } a (300) 300 b (304) *b 28 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 10 a (300) 300 b (304) *b 29 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 10 a (300) 300 b (304) *b &a=300 a=10 &b=304 b=300 *b=10 30 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 11 a (300) 300 b (304) *b &a=300 a=10 &b=304 b=300 *b=10 31 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 11 a (300) 300 b (304) *b &a=300 a=10 &b=304 b=300 *b=10 &a=300 a=11 &b=304 b=300 *b=11 32 Alocação Dinâmica de Memória ❑Ponteiros normalmente são utilizados com alocação dinâmica de memória ❑Para tanto, é necessário antes alocar um novo espaço na memória antes de utilizar, liberando-o ao término do uso ❑Em C++ a alocação é efetuada através do operador new e a liberação através de delete ❑Sintaxe (p é um ponteiro do tipo T): ▪ p = new T; ▪ delete p; 33 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b c 34 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b c 35 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b c 20 36 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b 25 c 20 37 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b 25 c 20 20+5=25 38 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b 25 c 20+5=25 39 Exemplo 3 #include <iostream> using namespace std; int main(){ int i, n; float *v, s=0; cout<<"Entre com o tamanho do vetor:"<<endl; cin>>n; v= new float[n]; // aloca vetor com n floats // Recebe o vetor cout<<"Entre com o vetor"<<endl; for (i=0;i<n;i++){ cout<<"Entre com o elemento na posicao "<<i<<":"<<endl; cin>>v[i]; s += v[i]; } // Imprime a soma dos elementos do vetor cout<<"Soma dos elementos do vetor [ "; for (i=0;i<n;i++) cout<<v[i]<<" "; cout<<"]: "<<s<<endl; delete [] v; // libera memória return 0; } 40 Alocação Dinâmica de Memória ❑Podemos alocar dinamicamente estruturas definidas pelo usuário, por exemplo, registros ❑Um campo x de um registro apontados pelo ponteiro p pode ser acessado usando as notações equivalentes: ▪ (*p).x ▪ p->x 41 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f g 42 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f matricula nome cargo escolaridade sexo local ecivil salario g *g 43 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 g *g 44 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f.salario=5200, (*g).salario=5200, g->salario=5200 g *g 45 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f f.salario=5200.00, (*g).salario=5200.00, g->salario=5200.00 g 46 Definição de Novos Tipos de Dados ❑O comando typedef fornece um mecanismo para criar sinônimos (ou apelidos) para tipos de dados previamente definidos ❑Criar um novo nome utilizando typedef não cria um novo tipo de dados; typedef apenas cria um novo nome que pode ser utilizado como um sinônimo ❑Definição: ▪ typedef tipo_existente tipo_novo; 47 Exemplos #include <iostream> using namespace std; typedef int inteiro; const inteiro M=50; typedef inteiro vetor[M]; int main() { inteiro i; vetor x,y; for(i=0;i<M;i++) cin >> x[i] >> y[i]; for(i=0;i<M;i++) cout << x[i] << "\t" << y[i] << endl; return 0; } #include <iostream> using namespace std; typedef int *pint; // pint é um ponteiro para int int main() { int i; pint iptr1; int *iptr2; iptr1 = &i; iptr2 = &i; i = 5; cout << "i=" << i << " *iptr1=" << *iptr1 << " *iptr2=" << *iptr2 << endl; return 0; } 48 Copyright© Apresentação 2019 por José Augusto Baranauskas Universidade de São Paulo Professores são convidados a utilizarem esta apresentação da maneira que lhes for conveniente para uso não comercial, desde que esta nota de copyright permaneça intacta. (editado por Renato Tinós em 2023)
Envie sua pergunta para a IA e receba a resposta na hora
Recomendado para você
25
Slide - Ordenação por Seleção - 2023-2
Introdução à Computação 2
USP
113
Slide - Método da Bolha - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
54
Slide - Ordenação Por Fusão - Bubblesort e Sharkesort - 2023-2
Introdução à Computação 2
USP
4
Prática 4 - Recursão - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
61
Slide - Subalgoritmos em C e C - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
3
Prática 2 - Análise Por Operações Primitivas - Introdução à Computação 2 - 2023-2
Introdução à Computação 2
USP
39
Slide - Algoritmos em Busca de Vetores - 2023-2
Introdução à Computação 2
USP
9
Lista 2 - Algoritmos Recursivos
Introdução à Computação 2
USP
5
Normas Sobre Programação 2022-2
Introdução à Computação 2
USP
Texto de pré-visualização
1.2. Estruturas e Ponteiros em C/C++ ❑ Nesta aula veremos o conceito de tipos de dados definidos pelo usuário: registros ❑ Um registro permite agrupar várias variáveis (campos) em uma única variável ❑ Veremos também como definir um sinônimo para um tipo de dados através do comando typedef ❑ Além disso veremos uma breve introdução ao tipo de dado ponteiro 2 Registros ❑ Um registro agrupa dados não homogêneos (campos) numa única variável, formando um novo tipo de dado ❑ Definição: struct nome_registro { tipo_1 nome_1; tipo_2 nome_2; ... tipo_n nome_n; }; ❑ Declaração de Variáveis: ▪ nome_registro variável1, variável2, ..., variávelN; 3 Exemplo: Definição struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; // estado civil float salario; }; A definição de um novo tipo de dado através do comando “struct” não aloca/ocupa espaço na memória do computador 4 Exemplo: Declaração de Variáveis #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; ... } A declaração de variáveis de um novo tipo de dado (definido através do comando “struct”) aloca/ocupa espaço na memória do computador para as variáveis declaradas 5 Exemplo: Declaração de Variáveis #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; ... } matricula nome cargo escolaridade sexo local ecivil salario f matricula nome cargo escolaridade sexo local ecivil salario g 6 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; return 0; } matricula nome cargo escolaridade 145 sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 7 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; return 0; } matricula nome cargo escolaridade 145 Maria Mota sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 8 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 9 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario matricula nome cargo escolaridade sexo local ecivil salario f g 10 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f matricula nome cargo escolaridade sexo local ecivil salario f g 11 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas matricula nome cargo escolaridade sexo local ecivil salario f g 12 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas 5200.00 matricula nome cargo escolaridade sexo local ecivil salario f g 13 Exemplo: Atribuição de Valores #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 matricula nome cargo escolaridade sexo local ecivil salario f g 14 Atribuição ❑Podemos atribuir duas estruturas que sejam do mesmo tipo ❑Neste caso, o compilador irá copiar uma estrutura, campo por campo, na outra ❑Note que isto é diferente do que acontece em vetores, nos quais, para fazer a cópia dos elementos de um vetor em outro, deve- se copiar elemento por elemento de um vetor para o outro vetor 15 Exemplo: Atribuição de Variáveis #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; // copiar registro f para g g = f; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f g matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 16 Exemplo: Vetor de Estruturas #include <iostream> using namespace std; const int nro_contas = 3; struct conta{ int nro; float saldo_trimestral[4]; float media_saldo; }; int main (){ float m=0.0; conta v[nro_contas]; for (int i = 0; i < nro_contas; i++){ v[i].media_saldo = 0.0; cout << "Cliente " << i + 1 << endl; cout << "Entre com o numero: " << endl; cin >> v[i].nro; cout << "Entre com o saldo: " << endl; for (int j = 0; j < 4; j++){ cout << "Saldo do trimestre " << j + 1 << endl; cin >> v[i].saldo_trimestral[j]; v[i].media_saldo += v[i].saldo_trimestral[j]; } v[i].media_saldo /= 4.0; cout << "Media do saldo: " << v[i].media_saldo<< endl; m += v[i].media_saldo; cout << endl; } m /= nro_contas; ... 17 Ponteiros ❑Ponteiros são variáveis que contêm endereços de memória como valores ❑Normalmente, uma variável contém diretamente um valor específico ❑Um ponteiro, por outro lado, contém um endereço de uma variável que contém um valor específico ▪ uma variável referencia diretamente um valor ▪ um ponteiro referencia indiretamente um valor 18 Ponteiros ❑Referência direta a uma variável ▪ “a” referencia diretamente uma variável cujo valor é 10 ❑Referência indireta a uma variável ▪ “b” referencia indiretamente uma variável cujo valor é 10 10 a b 10 a 19 Ponteiros ❑Ponteiros, como quaisquer outras variáveis devem ser declarados antes do uso ❑A declaração ▪ int *b, a; ❑Declara ▪ a variável a do tipo int ▪ a variável b do tipo int * (isto é, um ponteiro para um inteiro) e é lido como “b é um ponteiro para int” ▪ O * apenas se aplica à declaração de b 20 Ponteiros ❑Cada variável sendo declarada como um ponteiro deve ser precedida por um asterisco ▪ float *xptr, *yptr; ❖indica que xptr e yptr são ambos ponteiros para valores float ❑Quando * é usado desta maneira na declaração, ele indica que a variável sendo declarada é um ponteiro ❑Ponteiros podem ser declarados para apontar para qualquer tipo de dados (primitivos ou definidos pelo usuário) 21 Ponteiros ❑ Como toda variável, ponteiros devem ser inicializados quando declarados ou através de um comando de atribuição ❑ Um ponteiro pode ser inicializado com 0, NULL ou um endereço ❑ Um ponteiro com 0 ou NULL aponta para nada (algumas vezes, dizemos que o ponteiro está “aterrado”, ou “que aponta para o terra”) ▪ NULL é uma constante simbólica definida no arquivo de cabeçalho (header) <iostream> 22 Ponteiros: Operadores ❑&: operador de endereço = operador unário que retorna o endereço do seu operando ▪ int a=10; ▪ int *b; b 10 a 23 Ponteiros: Operadores ❑&: operador de endereço = operador unário que retorna o endereço do seu operando ▪ int a=10; ▪ int *b; ❑O comando ▪ b = &a; ❑Atribui o endereço da variável a para o ponteiro b ❑Dizemos nesse caso que “b aponta para a” b 10 a 7000 b 10 a 5000 7000 24 Ponteiros: Operadores ❑*: operador de indireção ou derreferenciação = operador unário que retorna um sinônimo, ou apelido do seu operando ▪ int a=10; ▪ int *b; ▪ b = &a; ❑O comando ▪ cout << *b << endl; ▪ escreve o valor da variável apontada por b, ou seja, escreve o valor da variável a da mesma forma que o comando ❖cout << a << endl; b 10 a 7000 b 10 a 5000 7000 25 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } “a” é uma variável inteira. “b” aponta para um inteiro, ou seja, “b” é um ponteiro para um inteiro 26 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } a (300) b (304) 27 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } a (300) 300 b (304) *b 28 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 10 a (300) 300 b (304) *b 29 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 10 a (300) 300 b (304) *b &a=300 a=10 &b=304 b=300 *b=10 30 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 11 a (300) 300 b (304) *b &a=300 a=10 &b=304 b=300 *b=10 31 Exemplo 1 #include <iostream> using namespace std; int main() { int a,*b; b = &a; a = 10; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; *b = 11; cout << "&a=" << &a << " a=" << a << " &b=" << &b << " b=" << b << " *b=" << *b << endl; return 0; } 11 a (300) 300 b (304) *b &a=300 a=10 &b=304 b=300 *b=10 &a=300 a=11 &b=304 b=300 *b=11 32 Alocação Dinâmica de Memória ❑Ponteiros normalmente são utilizados com alocação dinâmica de memória ❑Para tanto, é necessário antes alocar um novo espaço na memória antes de utilizar, liberando-o ao término do uso ❑Em C++ a alocação é efetuada através do operador new e a liberação através de delete ❑Sintaxe (p é um ponteiro do tipo T): ▪ p = new T; ▪ delete p; 33 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b c 34 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b c 35 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b c 20 36 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b 25 c 20 37 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b 25 c 20 20+5=25 38 Exemplo 2 #include <iostream> using namespace std; int main() { int *ptr,b=5,c; // alocar novo inteiro apontado por ptr ptr = new int; *ptr = 20; c = *ptr + b; cout << *ptr << "+" << b << "=" << c << endl; delete ptr; // liberar inteiro alocado return 0; } ptr 5 b 25 c 20+5=25 39 Exemplo 3 #include <iostream> using namespace std; int main(){ int i, n; float *v, s=0; cout<<"Entre com o tamanho do vetor:"<<endl; cin>>n; v= new float[n]; // aloca vetor com n floats // Recebe o vetor cout<<"Entre com o vetor"<<endl; for (i=0;i<n;i++){ cout<<"Entre com o elemento na posicao "<<i<<":"<<endl; cin>>v[i]; s += v[i]; } // Imprime a soma dos elementos do vetor cout<<"Soma dos elementos do vetor [ "; for (i=0;i<n;i++) cout<<v[i]<<" "; cout<<"]: "<<s<<endl; delete [] v; // libera memória return 0; } 40 Alocação Dinâmica de Memória ❑Podemos alocar dinamicamente estruturas definidas pelo usuário, por exemplo, registros ❑Um campo x de um registro apontados pelo ponteiro p pode ser acessado usando as notações equivalentes: ▪ (*p).x ▪ p->x 41 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f g 42 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f matricula nome cargo escolaridade sexo local ecivil salario g *g 43 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 g *g 44 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f.salario=5200, (*g).salario=5200, g->salario=5200 g *g 45 Exemplo 4 #include <iostream> #include <string> using namespace std; struct funcionario { int matricula; string nome; string cargo; int escolaridade; char sexo; string local; char ecivil; float salario; }; int main() { funcionario f,*g; f.matricula = 145; f.nome = ”Maria Mota”; f.cargo = ”Vendedora”; f.escolaridade = 3; f.sexo = ’f’; f.local = ”Vendas”; f.salario = 5200.00; f.ecivil = ’s’; g = new funcionario; *g = f; cout << "f.salario="<<f.salario << ", (*g).salario=“ << (*g).salario << ", g->salario=“ << g->salario << endl; delete g; return 0; } matricula nome cargo escolaridade 145 Maria Mota Vendedora 3 sexo local ecivil salario f Vendas s 5200.00 f f.salario=5200.00, (*g).salario=5200.00, g->salario=5200.00 g 46 Definição de Novos Tipos de Dados ❑O comando typedef fornece um mecanismo para criar sinônimos (ou apelidos) para tipos de dados previamente definidos ❑Criar um novo nome utilizando typedef não cria um novo tipo de dados; typedef apenas cria um novo nome que pode ser utilizado como um sinônimo ❑Definição: ▪ typedef tipo_existente tipo_novo; 47 Exemplos #include <iostream> using namespace std; typedef int inteiro; const inteiro M=50; typedef inteiro vetor[M]; int main() { inteiro i; vetor x,y; for(i=0;i<M;i++) cin >> x[i] >> y[i]; for(i=0;i<M;i++) cout << x[i] << "\t" << y[i] << endl; return 0; } #include <iostream> using namespace std; typedef int *pint; // pint é um ponteiro para int int main() { int i; pint iptr1; int *iptr2; iptr1 = &i; iptr2 = &i; i = 5; cout << "i=" << i << " *iptr1=" << *iptr1 << " *iptr2=" << *iptr2 << endl; return 0; } 48 Copyright© Apresentação 2019 por José Augusto Baranauskas Universidade de São Paulo Professores são convidados a utilizarem esta apresentação da maneira que lhes for conveniente para uso não comercial, desde que esta nota de copyright permaneça intacta. (editado por Renato Tinós em 2023)