Baixe o app para aproveitar ainda mais
Prévia do material em texto
Algoritmos e Técnicas de Programação Aula 05: VariVariááveis Compostas Heterogêneasveis Compostas Heterogêneas 2 Plano de Aula � Variáveis Compostas Heterogêneas � Introdução � Redução de dimensões de uma matriz � Exercícios 3 Indrodução � Variável composta heterogênea é mais conhecida como registro ou estrutura: � Influências de Pascal (record) e C (struct) � Uma estrutura é um conjunto de variáveis (de tipos distintos, ou não) referenciadas por um nome comum. � Pode ser vista com um contêiner de dados, comparável à um formulário de papel contendo vários campos de informação de um objeto ou entidade. � Referencia-se uma variável ou campo da estrutura através do nome da estrutura e do nome da variável, geralmente separados por “.” (ponto). 4 Introdução � As variáveis (campos ou membros) de uma estrutura têm uma forte relação lógica entre si: � Permitem modelar uma entidade concreta ou abstrata (livro, cliente, transação bancária, chamada telefônica etc.) � Modelar um objeto ou entidade tem o sentido de fazer uma abstração, na qual apenas os detalhes relevantes são considerados, enquanto os demais são ignorados ou abstraídos � Com a abstração, conseguimos representar o “objeto” de interesse dentro de uma estrutura de dados mais enxuta e conveniente, sob o aspecto do processamento computacional. 5 Introdução � O Tamanho da estrutura é no mínimo igual à soma dos tamanhos das variáveis que a compõem. � O compilador pode (opcionalmente) alinhar o endereço base de cada variável membro a endereços múltiplos de 4 (32bits) ou 8 (64 bits). Isso agiliza o acesso! � Com isso os campos podem não ser adjacentes na memória e o tamanho da estrutura fica um pouco maior que a soma dos tamanhos dos campos 6 Definição de Estruturas em C � Definir uma estrutura para representar um automóvel considerando apenas modelo, ano e placa: struct tcarro { char modelo [12]; //nome com até 11 caracteres int ano; //ano de fabricação char placa [7]; //placa: 3 letras + 4 dígitos }; � O código acima define o tipo “tcarro”, mas não declara qualquer variável. � Uma variável do tipo tcarro pode ser declarada como: struct tcarro carro; 7 Definição de Estruturas em C � Também é possível declarar uma ou mais variáveis logo após a definição da estrutura, seguindo o padrão (tipo nomeVar;): struct tcarro { char modelo [12]; int ano; char placa [7]; } carro_trab, carro_passeio; � Acima foram declaradas as variáveis “carro_trab”, “carro_passeio”, do tipo “tcarro” 8 Definição de Estruturas em C � Sintaxe Geral: struct tipo { tipo1 nomeVar1; tipo2 nomevar2; tipoN nomeVarN; } NomeVar; � “tipo” ou “nomeVar” pode ser omitido, mas nunca ambos! � De outro modo, ao menos um dos dois deve estar presente. 9 Acesso às variáveis da estrutura � Dada a declaração: � É válido código: carro_trab.ano = 2012; printf("Modelo do carro: %s", carro_trab.modelo); carro_passeio = carro_trab; strcpy(carro_passeio.modelo, "Gol") struct tcarro { char modelo [12]; int ano; char placa [7]; } carro_trab, carro_passeio; OU struct { char modelo [12]; int ano; char placa [7]; } carro_trab, carro_passeio; 10 Acesso às variáveis da estrutura � Os campos (variáveis) da estrutura são acessadas pelo nome da variável, seguida de “.” (ponto) e do nome do campo. struct tcarro { char modelo [12]; int ano; char placa [7]; } carro_trab carro_trab . ano = 2012; PONTO (seletor de campo) 11 Pré-inicialização de variáveis do tipo estrutura : � Variáveis do tipo estrutura podem ser inicializadas em tempo de compilação, com os valores dos campos separados por vírgula, na ordem dos mesmos dentro da estrutura e entre { } (bloco): � Exemplo struct tcarro carro = {"Gol", 2012, "PQR1234"}; � Declara e inicializa a variável carro: � carro.modelo com “Gol” � carro.ano com 2012 � carro.placa com “PQR1234” 12 Composição de Estruturas Complexas � Estruturas comportam campos de quaisquer tipos reconhecidos pelo compilador, incluindo estruturas e matrizes: 13 Redução da Dimensão de uma Matriz através de Estruturas � As estruturas são uma boa maneira de evitar o uso de matrizes com muitas dimensões. � Exemplo: Um triângulo pode ser representado como um vetor de 3 vértices e cada vértice como um vetor de 2 números reais representando as coordenadas (x, y): float tri[3][2]; //define um triângulo � Assim, para atribuir o valor 8,5 à ordenada y do 3º vértice do triângulo representado na variável “tri” faz-se: tri[2][1] = 8.5; 14 Redução da Dimensão de uma Matriz através de Estruturas � Em tempo de execução, cada índice associado a uma dimensão requer uma multiplicação para que o endereço seja calculado. � Em vez de usar um vetor de tamanho 2, pode-se usar uma estrutura com os campos x e y: struct {float x; float y;} tri[3]; � Agora, a atribuição do valor 8,5 à ordenada y do 3º vértice do triângulo é simplificado para: tri[2].y = 8.5; � Em vez de uma matriz 2D, temos agora um vetor e o deslocamento de y (em relação ao início da estrutura ponto) é conhecida em tempo de compilação � Com apenas um índice, o endereço de cada ponto (estrutura) no vetor é calculado; para chegar ao endereço de y, basta adicionar (mais rápido que multiplicar) o seu deslocamento. 15 Redução da Dimensão de uma Matriz através de Estruturas � Podemos melhorar ainda mais, substituindo o vetor de 3 vértices por uma estrutura contendo 3 campos, representando o vértices a, b e c: struct { struct {float x; float y;} a; struct {float x; float y;} b; struct {float x; float y;} c; } tri; � Atribuir 8,5 à ordenada do 3º vértice do triângulo deve ser feito assim: tri.c.y = 8.5; 16 Redução da Dimensão de uma Matriz através de Estruturas � a última opção é ainda mais eficiente, pois durante a compilação é possível saber que o endereço c.y será o endereço tri acrescido de 20 (a = 8 + b = 8 + c.x = 4) bytes. � No quadro abaixo é possível ver como as três representações se equivalem na memória: tri[0][0] tri[0][1] tri[1][0] tri[1][1] tri[2][0] tri[2][1] tri[0].x tri[0].y tri[1].x tri[1].y tri[2].x tri[2].y tri.a.x tri.a.y tri.b.x tri.b.y tri.c.x tri.c.y tri.a tri.b tri.c tri[0] tri[1] tri[2] tri[2]tri[1]tri[0] 17 Exercício 1 � Defina um tipo para uma estrutura que armazene as informações de uma matriz algébrica de números reais (float): a)número de linhas (m) b)número de colunas (n) c) valores da matriz (a), com 100 elementos (10 linhas x 10 colunas) 18 Solução 1 #define MAXLIN 10 #define MAXCOL 10 typedef struct matriz { int m; //número de linhas int n; //número de colunas //matriz MaxLin x MaxCol float a [MAXLIN][MAXCOL]; }; 19 Exercício 2 � Considere o tipo “pessoa”, definido com base na estrutura abaixo: � Implemente uma função que calcule a média salarial das pessoas com 40 anos ou mais, admitindo que a função receba com paramentos uma lista (vetor) de pessoas e o número de pessoas nela contidos. Utilize o protótipo: float MediaSal40(pessoa lista[], int n); float MediaSal40(struct pessoa lista[], int n); typedef struct { char nome[20]; float idade; float salario; } pessoa; struct pessoa { char nome[20]; float idade; float salario; }; ou 20 Solução 2 float MediaSal40(pessoa lista[], int n); { int i; float med, soma = 0, k = 0; for (i=0; i<n; i++) if (pessoa[i].idade>=40) { k++; soma = soma + pessoa[i].salario; } if (k>0) then return soma / k; else return 0; } 21 Exercício 3 � Dada a definição do tipo matriz (Exercício 1), implemente uma função para processar a adição de duasmatrizes a e b, armazenando o resultado numa matriz c, se a operação for possível #define MaxLin 10 #define MaxCol 10 typedef struct { int m; //número de linhas int n; //número de colunas float a [MaxLin][MaxCol]; //matriz MaxLin x MaxCol } matriz; 22 Solução 3 int SomaMatrizes(matriz x, matriz y, matriz * z){ int i, j; if (x.m != y.m || x.n != y.n) return 0; for (i=0; i < x.m; i++) for (j=0; i < x.n; j++) (*z).a[i][j] = x.a[i][j] + y.a[i][j]; //a linha acima equivale a //z->a[i][j] = x.a[i][j] + y.a[i][j]; return 1; } 23 Exercício 3 � Considere a última definição de um triângulo, exclusivamente baseada em estrutura. Implemente uma função que calcule o perímetro de um triangulo
Compartilhar