0% acharam este documento útil (0 voto)
14 visualizações49 páginas

Capi - Tulo 10 - Estruturas em C

O capítulo descreve estruturas em C, incluindo sua declaração, inicialização, acesso aos membros e uso com funções. Estruturas permitem agrupar variáveis relacionadas sob um único nome e são usadas comumente para representar registros armazenados em arquivos.

Enviado por

goduke442
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
14 visualizações49 páginas

Capi - Tulo 10 - Estruturas em C

O capítulo descreve estruturas em C, incluindo sua declaração, inicialização, acesso aos membros e uso com funções. Estruturas permitem agrupar variáveis relacionadas sob um único nome e são usadas comumente para representar registros armazenados em arquivos.

Enviado por

goduke442
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 49

C Como Programar, Sexta Edição

slide 1 © 2011 Pearson. Todos os direitos reservados.


Objetivos

Neste capítulo, você aprenderá:


• A criar e usar estruturas, uniões e enumerações.
• A passar estruturas para funções por valor e por referência.
• A manipular dados com os operadores sobre bits.
• A criar campos de bit para armazenar dados de modo compacto.

slide 2 © 2011 Pearson. Todos os direitos reservados.


10.1 Introdução
10.2 Declarações de estruturas
10.3 Inicialização de estruturas
10.4 Acesso aos membros da estrutura
10.5 Uso de estruturas com funções
10.6 typedef
10.7 Exemplo: uma simulação de alto desempenho de
embaralhamento e distribuição de cartas
10.8 Uniões
10.9 Operadores sobre bits
10.10 Campos de bit
10.11 Constantes de enumeração

slide 3 © 2011 Pearson. Todos os direitos reservados.


 Estruturas — também chamadas de agregações — são coleções de
variáveis relacionadas agrupadas sob um único nome.
 As estruturas podem conter variáveis de muitos tipos de dados
diferentes — diferentemente dos arrays, que contêm apenas
elementos do mesmo tipo de dado.
 As estruturas normalmente são usadas para declarar registros a
serem armazenados em arquivos (ver Capítulo 11).
 Ponteiros e estruturas facilitam a formação de estruturas de dados
mais complexas, por exemplo, listas interligadas, filas, pilhas e
árvores (ver Capítulo 12).

slide 4 © 2011 Pearson. Todos os direitos reservados.


 Estruturas são tipos de dados derivados; elas são construídas a partir
de objetos de outros tipos.
 Considere a declaração de estrutura a seguir:
 struct card {
char *face;
char *suit;
};
 A palavra-chave struct introduz a declaração de estrutura.
 O identificador card é a tag de estrutura, que dá nome à declaração
de estrutura e é usado com a palavra-chave struct para declarar
variáveis do tipo de estrutura.

slide 5 © 2011 Pearson. Todos os direitos reservados.


 Nesse exemplo, o tipo de estrutura é struct card.
 As variáveis declaradas dentro das chaves de declaração da estrutura
são os membros da estrutura.
 Os membros que têm o mesmo tipo de estrutura precisam ter nomes
exclusivos, mas dois tipos de estrutura diferentes podem ter
membros com o mesmo nome, sem conflito (logo veremos por quê).
 Todas as declarações de estrutura precisam terminar com pontos e
vírgulas.

slide 6 © 2011 Pearson. Todos os direitos reservados.


Erro comum de programação 10.1
Esquecer ponto e vírgula que termina uma
declaração de estrutura provoca um erro
de sintaxe.

slide 7 © 2011 Pearson. Todos os direitos reservados.


 A declaração de struct card contém os membros face e suit
do tipo char *.
 Os membros da estrutura podem ser variáveis dos tipos de dados
primitivos (por exemplo, int, float etc.), ou agregações, como
arrays e outras estruturas.
 Os membros da estrutura podem ser de muitos tipos.

slide 8 © 2011 Pearson. Todos os direitos reservados.


 Por exemplo, a struct a seguir contém membros de array de
caracteres para o nome e para o sobrenome de um funcionário, um
membro int para sua idade, um membro char que conteria'M'
ou 'F' para indicar a que sexo ele pertence e um membro double
para seu salário:
 struct funcionario {
char nome[ 20 ];
char sobrenome[ 20 ];
int idade;
char sexo;
double salario;
};

slide 9 © 2011 Pearson. Todos os direitos reservados.


 Uma estrutura não pode conter uma instância de si mesma.
 Por exemplo, uma variável do tipo struct funcionario não
pode ser declarada na definição para struct funcionario.
 Porém, um ponteiro para struct funcionario pode ser
incluído.
 Por exemplo,
 struct funcionario2 {
char nome[ 20 ];
char sobrenome[ 20 ];
int idade;
char sexo;
double salario;
struct funcionario2 pessoa; /* ERRO */
struct funcionario2 *ePtr; /* ponteiro */
};
 struct funcionario2 contém uma instância de si mesma
(pessoa), o que é um erro.

slide 10 © 2011 Pearson. Todos os direitos reservados.


 Como ePtr é um ponteiro (para o tipo struct
funcionario2), ele é permitido na declaração. Uma estrutura
que contém um membro que é um ponteiro para o mesmo tipo de
estrutura é chamada de estrutura autorreferenciada.
 As estruturas autorreferenciadas serão usadas no Capítulo 12 para
criar estruturas de dados interligadas.

slide 11 © 2011 Pearson. Todos os direitos reservados.


 As declarações da estrutura não reservam nenhum espaço na
memória; em vez disso, cada declaração cria um novo tipo de dado,
que é usado para declarar variáveis.
 As variáveis da estrutura são declaradas como variáveis de outros
tipos.
 A declaração
 struct card aCard, deck[ 52 ], *cardPtr;
declara aCard como uma variável do tipo struct card, declara
deck como um array com 52 elementos do tipo struct card e
declara cardPtr como um ponteiro para struct card.

slide 12 © 2011 Pearson. Todos os direitos reservados.


 As variáveis de determinado tipo de estrutura também podem ser
declaradas colocando-se uma lista separada por vírgulas com os
nomes de variável entre a chave que fecha a declaração de estrutura
e o ponto e vírgula que encerra a declaração de estrutura.
 Por exemplo, a declaração anterior poderia ter sido incorporada na
declaração de estrutura struct card da seguinte forma:
 struct card {
char *face;
char *suit;
} aCard, deck[ 52 ], *cardPtr;

slide 13 © 2011 Pearson. Todos os direitos reservados.


 O nome para a tag de estrutura é opcional.
 Se uma declaração de estrutura não tiver um nome para a tag da
estrutura, as variáveis do tipo da estrutura só poderão ser declaradas
na declaração de estrutura, e não em uma declaração separada..

slide 14 © 2011 Pearson. Todos os direitos reservados.


Boa prática de programação 10.1
Sempre forneça um nome para a tag de
estrutura ao criar um tipo de estrutura. O
nome para a tag de estrutura será
conveniente na declaração de novas
variáveis do tipo de estrutura adiante no
programa.

Boa prática de programação 10.2


Escolher um nome significativo para a tag
de estrutura ajuda a tornar o programa
documentado.

slide 15 © 2011 Pearson. Todos os direitos reservados.


 As únicas operações válidas que podem ser realizadas nas estruturas
são as seguintes:
◦ atribuição de variáveis da estrutura a variáveis da estrutura de
mesmo tipo,
◦ coleta de endereço (&) de uma variável de estrutura,
◦ acesso aos membros de uma variável de estrutura (ver Seção 10.4)
e
◦ uso do operador sizeof para determinar o tamanho de uma
variável de estrutura.

slide 16 © 2011 Pearson. Todos os direitos reservados.


Erro comum de programação 10.2
Atribuir uma estrutura de um tipo a uma
estrutura de um tipo diferente provoca um
erro de compilação.

slide 17 © 2011 Pearson. Todos os direitos reservados.


 As estruturas não podem ser comparadas usando-se os operadores
== e !=, pois os membros da estrutura não são necessariamente
armazenados em bytes consecutivos de memória.
 Às vezes, existem ‘buracos’ em uma estrutura, pois os computadores
podem armazenar tipos de dados específicos apenas em certos
limites de memória, como os limites de meia palavra, palavra ou
palavra dupla.
 Uma palavra é uma unidade de memória padrão usada para
armazenar dados em um computador — normalmente, 2 bytes ou 4
bytes.

slide 18 © 2011 Pearson. Todos os direitos reservados.


 Considere uma declaração de estrutura em que sample1 e
sample2 do tipo struct exemplo são declaradas:
 struct exemplo {
char c;
int i;
} ex1, ex2;
 Um computador com palavras de 2 bytes pode exigir que cada
membro de struct exemplo seja alinhado em um limite de
palavra (isso depende de cada máquina).

slide 19 © 2011 Pearson. Todos os direitos reservados.


 A Figura 10.1 mostra um exemplo de alinhamento de armazenagem
para uma variável do tipo struct exemplo que recebeu o
caractere 'a' e o inteiro 97 (as representaçãos de bit dos valores
são mostradas).
 Se os membros forem armazenados começando nos limites de
palavra, existe um intervalo de 1 byte (byte 1 na figura) no
armazenamento para as variáveis do tipo struct exemplo.
 O valor no intervalo de 1 byte é indefinido.
 Mesmo que os valores dos membros de ex1 e ex2 sejam realmente
iguais, as estruturas não serão necessariamente iguais, pois os
intervalos indefinidos de 1 byte provavelmente não conterão valores
idênticos.

slide 20 © 2011 Pearson. Todos os direitos reservados.


slide 21 © 2011 Pearson. Todos os direitos reservados.
Dica de portabilidade 10.1
Como o tamanho dos itens de dados de
determinado tipo e as considerações de
alinhamento de armazenagem dependem
da máquina, o mesmo acontece com a
representação de uma estrutura.

slide 22 © 2011 Pearson. Todos os direitos reservados.


 As estruturas podem ser inicializadas a partir de listas de
inicializadores, assim como acontece com os arrays.
 Para inicializar uma estrutura, siga o nome da variável na
declaração com um sinal de igual e uma lista, delimitada por chaves,
de inicializadores separados por vírgulas.
 Por exemplo, a declaração
 struct card aCard = { “Três”, “Copas” };
cria a variável aCard para ser do tipo struct card (conforme
definido na Seção 10.2) e inicializa o membro face como “Três”
e o membro suit como “Copas”.

slide 23 © 2011 Pearson. Todos os direitos reservados.


 Se o número de inicializadores na lista for menor que os membros
na estrutura, os membros restantes serão automaticamente
inicializados em 0 (ou NULL se o membro for um ponteiro).
 As variáveis de estrutura que forem declaradas fora de uma
declaração de função (ou seja, que sejam externos a ela) serão
inicializadas em 0 ou NULL, se não forem inicializadas
explicitamente na declaração externa.
 As variáveis da estrutura também podem ser inicializadas nas
instruções de atribuição, atribuindo uma variável de estrutura do
mesmo tipo, ou valores aos membros individuais da estrutura.

slide 24 © 2011 Pearson. Todos os direitos reservados.


 Dois operadores são usados para acessar membros das estruturas: o
operador de membro de estrutura (.) — também chamado de
operador de ponto — e o operador de ponteiro de estrutura (->) —
também chamado operador de seta.
 O operador de membro da estrutura acessa um membro da estrutura
por meio do nome da variável da estrutura.
 Por exemplo, para imprimir o membro suit da variável da
estrutura aCard declarada na Seção 10.3, use a instrução
 printf( "%s", aCard.suit ); /* mostra Copas */

slide 25 © 2011 Pearson. Todos os direitos reservados.


 O operador de ponteiro da estrutura — que consiste em um sinal de
subtração (-) seguido de um sinal de maior (>) — acessa um
membro da estrutura por meio de um ponteiro para a estrutura.
 Suponha que o ponteiro cardPtr tenha sido declarado para
apontar para struct card, e que o endereço da estrutura aCard
tenha sido atribuído a cardPtr.
 Para imprimir o membro suit da estrutura aCard com o ponteiro
cardPtr, use a instrução
 printf( "%s", cardPtr->suit ); /* mostra Copas */

slide 26 © 2011 Pearson. Todos os direitos reservados.


 A expressão cardPtr->suit é equivalente a
(*cardPtr).suit, que desreferencia o ponteiro e acessa o
membro suit usando o operador de membro da estrutura.
 Aqui, os parâmetros são necessários porque o operador de membro
da estrutura (.) tem uma precedência maior que o operador de
desreferência de ponteiro (*).
 O operador de ponteiro da estrutura e o operador de membro da
estrutura, com os parênteses (para chamar funções) e colchetes ([])
usados para subscrito de array, possuem a precedência de operador
mais alta, e são associados da esquerda para a direita.

slide 27 © 2011 Pearson. Todos os direitos reservados.


Boa prática de programação 10.3
Não coloque espaços em torno dos
operadores ‘–>’ e ‘.’ — a omissão dos
espaços ajuda a enfatizar o fato de que
as expressões em que os operadores
estão contidos são basicamente nomes de
variável únicos.

Erro comum de programação 10.3


A inserção de espaço entre os
componentes – e > do operador de
ponteiro da estrutura (ou entre os
componentes de qualquer outro operador
de múltiplos caracteres, com exceção de
?:) provoca um erro de sintaxe.

slide 28 © 2011 Pearson. Todos os direitos reservados.


Erro comum de programação 10.4
Tentar referenciar a um membro de uma
estrutura usando apenas o nome do
membro provoca um erro de sintaxe.

Erro comum de programação 10.5


Não usar parênteses ao referenciar um
membro da estrutura que usa um ponteiro
e o operador de membro da estrutura (por
exemplo, *cardPtr.suit) provoca um erro de
sintaxe.

slide 29 © 2011 Pearson. Todos os direitos reservados.


 O programa da Figura 10.2 demonstra o uso dos operadores de
membro da estrutura e de ponteiro da estrutura.
 Usando o operador de membro da estrutura, os membros da
estrutura aCard recebem os valores "Ace" e "Spades",
respectivamente (linhas 18 e 19).
 O ponteiro cardPtr recebe o endereço da estrutura aCard (linha
21).
 A função printf imprime os membros da variável da estrutura
aCard usando o operador de membro da estrutura com nome de
variável aCard, o operador de ponteiro da estrutura com o ponteiro
cardPtr e o operador de membro da estrutura com o ponteiro
desreferenciado cardPtr (linhas 23 a 25).

slide 30 © 2011 Pearson. Todos os direitos reservados.


slide 31 © 2011 Pearson. Todos os direitos reservados.
slide 32 © 2011 Pearson. Todos os direitos reservados.
 As estruturas podem ser passadas a funções ao passar membros da
estrutura individuais, ao passar uma estrutura inteira ou um ponteiro
para uma estrutura.
 Quando as estruturas ou membros individuais da estrutura são
passados a uma função, eles são passados por valor.
 Portanto, os membros da estrutura passados por valor não podem ser
modificados pela função utilizada.
 Para passar uma estrutura por referência, passe o endereço da
variável da estrutura.

slide 33 © 2011 Pearson. Todos os direitos reservados.


 Os arrays das estruturas — assim como todos os outros arrays —
são automaticamente passados por referência.
 Para passar um array por valor, crie uma estrutura que tenha o array
como membro.
 As estruturas são passadas por valor, de modo que o array também
seja passado por valor.

slide 34 © 2011 Pearson. Todos os direitos reservados.


Erro comum de programação 10.6
Supor que estruturas como arrays sejam
passadas automaticamente por referência
e tentar modificar os valores da
estrutura passados por valor na função
utilizada consiste em um erro lógico.

Dica de desempenho 10.1


Passar estruturas por referência é mais
eficiente do que passar estruturas por
valor (o que requer que a estrutura
inteira seja copiada).

slide 35 © 2011 Pearson. Todos os direitos reservados.


 A palavra-chave typedef oferece um mecanismo de criação de
sinônimos (ou aliases) para tipos de dados previamente definidos.
 Os nomes dos tipos de estrutura normalmente são definidos a partir
de typedef que se criem nomes de tipo mais curtos.
 Por exemplo, a instrução
 typedef struct card Card;
define o novo nome de tipo Card como um sinônimo para o tipo
struct card.
 Programadores de C normalmente usam typedef para definir um
tipo da estrutura, de modo que a tag da estrutura não é necessária.

slide 36 © 2011 Pearson. Todos os direitos reservados.


 Por exemplo, a declaração a seguir
 typedef struct {
char *face;
char *suit;
} Card;
cria o tipo de estrutura Card sem a necessidade de uma instrução
typedef separada.

slide 37 © 2011 Pearson. Todos os direitos reservados.


Boa prática de programação 10.4
Coloque a primeira letra dos nomes de
typedef em maiúscula para enfatizar o fato
de que eles são sinônimos de outros
nomes para tipos.

slide 38 © 2011 Pearson. Todos os direitos reservados.


 Card agora pode ser usado para declarar variáveis do tipo struct
card.
 A declaração
 Card deck[ 52 ];
declara um array de 52 estruturas Card (ou seja, variáveis do tipo
struct card).
 Criar um novo nome com typedef não cria um novo tipo;
typedef simplesmente cria um novo nome de tipo, que pode ser
usado como um alias para um nome de tipo existente.

slide 39 © 2011 Pearson. Todos os direitos reservados.


 Um nome significativo ajuda a tornar o programa autoexplicativos.
 Por exemplo, quando lemos a declaração anterior, sabemos que
“deck é um array de 52 Cards.”
 Frequentemente, typedef é usado para criar sinônimos para os
tipos de dados básicos.
 Por exemplo, um programa que exige inteiros de 4 bytes pode usar o
tipo int em um sistema e o tipo long em outro.
 Os programas projetados para portabilidade normalmente usam
typedef para criar um alias para inteiros de 4 bytes, como
Integer.
 O alias Integer ser alterado uma vez no programa para fazê-lo
funcionar nos dois sistemas..

slide 40 © 2011 Pearson. Todos os direitos reservados.


Dica de portabilidade 10.2
Use typedef para ajudar a tornar um
programa mais portável.

slide 41 © 2011 Pearson. Todos os direitos reservados.


 O programa da Figura 10.3 baseia-se na simulação de
embaralhamento e distribuição de cartas discutida no Capítulo 7.
 O programa representa o baralho de cartas como um array de
estruturas.
 O programa usa algoritmos de alto desempenho para embaralhar e
distribuir as cartas.
 A saída do programa de embaralhamento e distribuição de cartas
aparece na Figura 10.4.

slide 42 © 2011 Pearson. Todos os direitos reservados.


slide 43 © 2011 Pearson. Todos os direitos reservados.
slide 44 © 2011 Pearson. Todos os direitos reservados.
slide 45 © 2011 Pearson. Todos os direitos reservados.
slide 46 © 2011 Pearson. Todos os direitos reservados.
 No programa, a função fillDeck (linhas 42-52) inicializa o array
Card na ordem de Ás a Rei de cada naipe.
 O array Card é passado (na linha 36) à função shuffle (linhas
55-68), em que o algoritmo de embaralhamento de alto desempenho
é implementado.
 A função shuffle usa um array de 52 estruturas Card como
argumento.
 A função percorre as 52 cartas (subscritos de array 0 a 51) usando
uma estrutura for nas linhas 62-67.

slide 47 © 2011 Pearson. Todos os direitos reservados.


 Para cada carta, um número entre 0 e 51 é escolhido aleatoriamente.
 Em seguida, a estrutura Card atual e a estrutura Card selecionada
aleatoriamente são trocados no array (linhas 64 a 66).
 Um total de 52 trocas é feito em uma única passada do array inteiro,
e o array das estruturas Card é embaralhado!
 Esse algoritmo não pode sofrer adiamento indefinido, como o
algoritmo de embaralhamento apresentado no Capítulo 7.
 Como as estruturas Card foram trocadas no espaço do array, o
algoritmo de alto desempenho implementado na função deal
(linhas 71-80) exige apenas uma passada do array para distribuir as
cartas embaralhadas.

slide 48 © 2011 Pearson. Todos os direitos reservados.


Erro comum de programação 10.7
Esquecer de incluir o subscrito do array ao
se referir a estruturas individuais em um
array de estruturas consiste em um erro de
sintaxe.

slide 49 © 2011 Pearson. Todos os direitos reservados.

Você também pode gostar

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy