Site: BAC004 at http://bac004.wikidot.com Source page: Registros at http://bac004.wikidot.com/registros
Registros
Fold Table of Contents 1 Definição de um registro: criação de um novo tipo de dados 2 Declaração de variáveis do tipo de dado registro 3 Acesso aos membros de um registro 4 Passando Variáveis do tipo Registro para Funções 4.1 Passando variável simples do tipo de dado registro 4.2 Passando variável composta (vetor) do tipo de dado registro 4.3 Funções que retornam um registro 5 Inicialização de variáveis do tipo registro 6 Atribuições entre registros 7 Registros aninhados 8 Exercícios Até o presente momento só foi possível a manipulação de coleção de dados do mesmo tipo, como os vetores e as matrizes, pois quando se declara um vetor de inteiros, por exemplo, todos os seus elementos são do tipo inteiro. Já com registros, também chamados de estruturas, é possível agregar informações de tipos diferentes, criandose um novo tipo de dado. Um registro é, portanto, uma coleção de campos, em que cada campo pode ser de um tipo diferente. Definição Formal: O conceito de registro visa facilitar o agrupamento de variáveis que não são do mesmo tipo, mas que guardam estreita relação lógica. O registro é um caso mais geral de variável composta na qual os elementos do conjunto não precisam ser, necessariamente, homogêneos ou do mesmo tipo (FARRER ET AL, 2008). Por exemplo, os seguintes dados de um funcionário código, nome, salário e sexo são informações de tipos diferentes, mas possuem uma estreita relação lógica, que é a de compor as características de um funcionário.1 ‐ Definição de um registro: criação de um novo tipo de
dados
Através da palavrachave struct definese um novo tipo de dado. Definir um tipo de dado significa informar ao compilador seu nome, tamanho em bytes e a maneira como deve ser lido e recuperado da memória. A definição de um registro informa como ele está organizado e quais são os seus membros. A definição de um registro não cria variável, somente informa ao compilador as características de um novo tipo de dado. Não há nenhuma reserva de memória. A forma geral para se criar um novo tipo de dados como registro é apresentada a seguir. struct tipoDoRegistro{ // primeiro criase o tipo de dado Registro tipoDoCampo1 nomeDoCampo1; tipoDoCampo2 nomeDoCampo2; ... tipoDoCampoN nomeDoCampoN; }; Exemplo 1: Criação de um registro que agrupa características de um funcionário. struct Funcionario{ // tipo de dado Funcionario sendo criado int codigo; char nome[30]; float salario; char sexo; }; Exemplo 2: Criação de um registro que agrupa características de uma conta bancária.struct Conta{ // tipo de dado Conta sendo criado int numero; char tipo; char titular[30]; float saldo; };
2 ‐ Declaração de variáveis do tipo de dado registro
Depois de definir um novo tipo de dado, este pode ser usado para declarar variáveis de modo análogo a qualquer tipo simples. Segue a sintaxe de declaração de uma varíável do tipo de dado registro: tipoDeDadoRegistro nomeDaVariável; Exemplo 1: Declaração de uma variável simples do tipo Funcionário Funcionario funcionario; // Declarase a variável funcionario do tipo Funcionario A variável funcionario gasta os seguintes espaços de memória para armazenar todos os membros do registro: 4 bytes para codigo, 30 bytes para nome, 4 bytes para salario e 1 byte para sexo. Total: 39 bytes. Exemplo 2: Declaração de um vetor do tipo Funcionario Funcionario funcionarios[10]; /* Declarase um vetor chamado funcionarios em que cada elemento é do tipo Funcionario */ O vetor funcionarios gasta os seguintes espaços de memória para armazenar todos os membros do registro: 10 vezes a quantidade para 1 funcionário (10 * 39). Total: 390 bytes.
3 ‐ Acesso aos membros de um registro
Pelo fato de o registro conter várias informações, para acessar um campo individualmente é necessário indicar o nome da variável e o nome do campo desejado, separados pelo operador ponto.
Exemplo 1: Variável simples funcionario Funcionario funcionario; cout << funcionario.nome; // Imprime o nome do funcionário cout << funcionario.nome[0]; // Imprime o primeiro caracter do nome do funcionário Exemplo 2: Variável composta funcionarios Funcionario funcionarios[10];
cout << funcionarios[9].nome; // Imprime o nome do último funcionário
cout << funcionarios[0].nome[0]; // Imprime o primeiro caracter do nome do primeiro funcionário
4 ‐ Passando Variáveis do tipo Registro para Funções
Variáveis do tipo registro podem ser passados como parâmetro de funções da mesma maneira que foi trabalhado com as demais variáveis (simples, vetores ou matrizes).
4.1 ‐ Passando variável simples do tipo de dado registro
Na função cadastra() do exemplo a seguir, o parâmetro deve ser passado por referência, pois deverá ocorrer atualização dos membros do registro após a sua chamada. Já na função exibe(), o parâmetro pode ser passado por valor, pois não ocorrerá quaisquer modificações nos membros do registro. Entretanto, é importante frisar que no caso de registros que ocupam grande quantidade de memória, não é aconselhável utilizar a passagem de parâmetros por valor, pois ocorrerá cópias de todos seus membros na memória. Observase que a criação do novo tipo de dado Funcionario foi global, ou seja, é visível por qualquer função definida no programa. #include <iostream> #include <cstdio> using namespace std; struct Funcionario { int codigo; char nome[30]; float salario; char sexo; }; void cadastra(Funcionario &f); void exibe(Funcionario f);
int main() { Funcionario funcionario; cadastra(funcionario); exibe(funcionario); return 0; } void cadastra(Funcionario &f) { cout << "Entre com o código: "; cin >> f.codigo; cout << "Entre com o nome: "; fflush(stdin); gets(f.nome); cout << "Entre com o salário: "; cin >> f.salario; cout << "Entre com o sexo: "; cin >> f.sexo; } void exibe(Funcionario f) { cout << "\nCódigo: " << f.codigo; cout << "\nNome: " << f.nome; cout << "\nSalário: " << f.salario; cout << "\nSexo: " << f.sexo; }
4.2 ‐ Passando variável composta (vetor) do tipo de dado
registro
A sintaxe de passar um vetor ou matriz de registros é semelhante a de passar vetor ou matriz de variáveis simples. Na chamada a uma função devese escrever apenas o nome do vetor ou matriz. No cabeçalho de definição da função declaramse normalmente os vetores/matrizes de registros. #include <iostream> #include <cstdio> using namespace std; struct Funcionario { int codigo; char nome[30]; float salario; char sexo; }; void cadastra(Funcionario f[]); void exibe(Funcionario f[]);int main() { Funcionario funcionarios[10]; cadastra(funcionarios); exibe(funcionarios); return 0; } void cadastra(Funcionario f[10]) {
for(int i=0; i<10; i++) { cout << i+1 << "o. FUNCIONARIO\n"; cout << "Entre com o código: "; cin >> f[i].codigo; cout << "Entre com o nome: "; fflush(stdin); gets(f[i].nome); cout << "Entre com o salário: "; cin >> f[i].salario; cout << "Entre com o sexo: "; cin >> f[i].sexo; } } void exibe(Funcionario f[10]) {
for(int i=0; i<10; i++) { cout << i+1 << "o. FUNCIONARIO\n"; cout << "\nCódigo: " << f[i].codigo; cout << "\nNome: " << f[i].nome; cout << "\nSalário: " << f[i].salario; cout << "\nSexo: " << f[i].sexo; } }
4.3 ‐ Funções que retornam um registro
Podese retornar um registro completo para outra função, como pode ser observado na função novaVenda() no exemplo a seguir. #include <iostream> using namespace std; struct Venda{ int quantPecas; float preco; }; Venda novaVenda() { Venda v;
cout << "\nNova Venda\n"; cout << "\nInsira o numero de peças: "; cin >> v.quantPecas; cout << "\nInsira o preço: "; cin >> v.preco; return v; } void listaTotalVendas(Venda &v1, Venda &v2) { cout << "\nVenda Total\n"; cout << "\nTotal de peças: " << (v1.quantPecas + v2.quantPecas); cout << "\nPreço Total: " << (v1.preco + v2.preco); } int main() { Venda venda1, venda2; venda1 = novaVenda(); venda2 = novaVenda(); listaTotalVendas(venda1, venda2); return 0; }
5 ‐ Inicialização de variáveis do tipo registro
É possível inicializar uma variável do tipo registro de forma semelhante a uma matriz. Os valores a serem atribuídos a seus membros devem ser colocados na ordem em que foram definidos, separados por vírgulas e entre chaves. struct Data{ int dia; int mes; int ano; }; Data natal = {25,12,2011}; Data aniversario = {12,8,2011};
6 ‐ Atribuições entre registros
Uma variável do tipo registro pode ser atribuída à outra variável do mesmo tipo através de uma atribuição simples. Os valores de todos os membros de um registro são atribuídos aos membros de outro registro. Segue um exemplo. struct Data{ int dia; int mes; int ano; }; Data anoNovo = {1, 1, 2012}; Data aniversarioCris = anoNovo;
Assim, os valores de aniversarioCris.dia, aniversarioCris.mes e aniversarioCris.ano serão, respectivamente: 1, 1 e 2012.
7 ‐ Registros aninhados
Podemse definir tipos de dados registro cujos membros são outros registros. No exemplo a seguir foi adicionado um membro do tipo Data chamado dtVenda ao registro Venda. A variável v possui três membros, sendo que um deles é do tipo Data. Portanto, v.dtVenda é o nome de uma variável do tipo Data e, para acessar seus membros, devese aplicar o operador ponto. #include <iostream> #include <cstdio> using namespace std; struct Data{ int dia; int mes; int ano; }; struct Venda{ int quantPecas; float preco; Data dtVenda; }; int main() { Venda v = {15, 130.50, {27, 5, 2011}}; cout << "Quantidade de peças: " << v.quantPecas << endl << "Preço: " << v.preco << endl << "Data da venda: " << v.dtVenda.dia << "/" << v.dtVenda.mes return 0; }8 ‐ Exercícios
1. Faça um programa modularizado utilizando registro que leia apenas uma conta bancária com as seguintes informações: número da conta, nome do cliente e saldo. Apresente esses dados na tela. 2. Modifique o programa anterior para realizar o cadastro de 100 contas, não podendo haver mais de uma conta com o mesmo número. Declare uma constante MAX_CONTAS com o valor 100 para facilitar a execução do programa, alterando seu valor para um número menor apenas para testes. Observação: o programa deverá continuar modularizado.3. Altere o programa anterior criando o menu de opções a seguir e implementando cada uma das opções: 0. Sair 1. Cadastrar uma conta 2. Visualizar todas as contas 3. Mostrar informações da conta com maior saldo (caso haja mais de uma conta com saldo igual ao maior, mostrar todas) 4. Mostrar informações da conta com menor saldo 5. Excluir uma conta Observação: o programa deverá continuar modularizado. 4. Veja os campos de alguns registros: Professor (número de registro, nome, cod_título, total h/a semanal) Título (cod_título, descrição, valor hora/aula) Faça um programa que: Crie uma função para cadastrar os títulos. Sabese que nessa escola existem cinco títulos; Crie uma função para cadastrar os professores. Sabese que nessa escola trabalham 10 professores, e cada um deve estar associado a um título previamente cadastrado; Crie uma função para mostrar a relação de professores, conforme a figura a seguir. 5. Faça um programa que manipule uma lista contendo informações sobre dez pacientes (nome do paciente, nome do médico, data de nascimento e sexo). Esse programa deverá implementar as seguintes funções: 1. Cadastrar pacientes 2. Mostrar pacientes em ordem de cadastramento 3. Mostrar pacientes em ordem crescente (ordenar pelo nome) 3. Mostrar pacientes em ordem decrescente (ordenar pelo nome) 5. Excluir pacientes individualmente 6. Excluir pacientes por médico Os elementos poderão ser inseridos sem qualquer ordenação (deve ser utilizado um vetor; não poderão ser cadastrados mais de dez pacientes); Quando a lista for mostrada em ordem crescente ou decrescente, deve ser
utilizada alguma maneira para não destruir a ordem original de cadastramento; Para realizar a exclusão de pacientes individualmente, deve ser informado o nome do paciente que se deseja excluir; Para realizar a exclusão de pacientes por médico, deve ser informado o nome do médico cujos pacientes serão excluídos da lista.