• Nenhum resultado encontrado

AULA 3 – REVISÃO DO PADRÃO C ANSI – Parte 3

N/A
N/A
Protected

Academic year: 2019

Share "AULA 3 – REVISÃO DO PADRÃO C ANSI – Parte 3"

Copied!
8
0
0

Texto

(1)

REVISÃO DE C-ANSI – Parte 3

Esta aula dará continuação à revisão dos conceitos básicos do padrão C-ANSI. Na aula de hoje serão revisados conceitos sobre estruturas de dados, uniões e tipos definidos pelo usuário.

E

STRUTURAS

De uma forma geral, estruturas são agrupamentos de variáveis que podem ser referenciadas pelo mesmo nome. Uma estrutura é definida através de um modelo, e as variáveis que fazem parte deste modelo são chamadas de campos. Um modelo de estrutura de dados tem a forma geral:

struct nome_da_estrutura {

tipo_de_variável nome_da_variável; tipo_de_variável nome_da_variável; (...)

tipo_de_variável nome_da_variável; };

Lembre-se de que esse bloco de código apenas é um modelo. Nenhuma variável do tipo estrutura foi de fato criada. Para criar uma variável que contenha a estrutura de dados do modelo deve-se escrever:

struct nome_da_estrutura nome_da_variável;

Por exemplo, podemos criar uma estrutura com o nome capacitor como segue:

struct capacitor {

char fabricante[20]; char tipo[20]; float valor; float tolerancia; };

Agora podemos declarar uma variável do tipo capacitor, escrevendo:

struct capacitor c1;

Para acessar os campos de uma estrutura é necessário utilizar o nome da variável criada concatenada com o nome do campo utilizando um ponto, i.e., para atribuir um valor qualquer a tolerância de c1 escreve-se:

c1.tolerancia = 0.2;

Do mesmo modo, para ler o nome do fabricante pode-se utilizar:

gets(c1.fabricante);

(2)

#include <stdio.h> #include <stdlib.h>

struct capacitor {

char tipo[20]; float valor; float tol; };

int main(void) {

struct capacitor c1, c2;

printf("Entre com Tipo: "), gets(c1.tipo); //Le tipo do capacitor printf("Entre com Valor: "), scanf("%f",&c1.valor); //le o valor

printf("Entre com Tolerancia em %%: "), scanf("%f",&c1.tol); //le tol c2 = c1; //atribui a variavel c2 o valor da variavel c1

printf("Tipo: %s, valor: %.3e, Tol: %.2f%%\n", c2.tipo, c2.valor, c2.tol); system("PAUSE");

return 0; }

Programa 1 Struct.

Matrizes de Estruturas

Pode-se declarar uma matriz de estruturas de dados. Observe o Programa 2.

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

struct capacitor {

char fabricante[20]; char tipo[20];

float valor; float tol; };

int main(void) {

struct capacitor c[10]; //cria um vetor com 10 variáveis do tipo capacitor strcpy(c[0].fabricante,"EPCOS");

strcpy(c[1].fabricante,"PHILIPS"); strcpy(c[0].tipo,"TANTALO");

strcpy(c[1].tipo,"ELETROLITICO"); c[0].valor = 2.2e-6;

c[1].valor = 2.2e-3; c[0].tol = 10;

c[1].tol = 20;

printf("Fab:%-10s Tipo:%-13s valor:%.2e Tol:%.2f%%\n",

c[0].fabricante,c[0].tipo,c[0].valor, c[0].tol); printf("Fab:%-10s Tipo:%-13s valor:%.2e Tol:%.2f%%\n",

c[1].fabricante,c[1].tipo,c[1].valor, c[1].tol); system("PAUSE");

return 0; }

(3)

Passando estruturas para funções

Para passar estruturas de dados para funções é necessário declarar o tipo da estrutura como parâmetro da função, exatamente como se fosse uma variável qualquer. Estude o Programa 3:

#include <stdio.h> #include <stdlib.h>

struct capacitor {

char tipo[20]; float valor; float tol; };

float max_cap(struct capacitor aux) //uma variável do tipo capacitor é { //declarada como parâmetro da função return aux.valor*(1+(aux.tol/100));

}

int main(void) {

struct capacitor c1; float max_value;

printf("Entre com Tipo: "), gets(c1.tipo); printf("Entre com Valor: "), scanf("%f",&c1.valor);

printf("Entre com Tolerancia em %%: "), scanf("%f",&c1.tol); max_value = max_cap(c1); //passei c1 para a função!!

printf("Valor maximo: %e\n", max_value); system("PAUSE");

return 0; }

Programa 3 Passando estruturas para funções.

Vale lembrar que a função max_val só irá aceitar variáveis do tipo capacitor como parâmetro em sua chamada.

Quando se deseja passar apenas um campo de uma estrutura, basta passar diretamente o campo para a função.

Estruturas dentro de estruturas.

Uma vez que um modelo para estrutura foi criado é possível utilizá-lo como qualquer outro tipo de variável. Isso significa que podemos ter estruturas de dados dentro de estruturas. Observe o Programa 4 na próxima página.

Note que a sintaxe para acessar os campos de diferentes níveis é a mesma, ou seja, basta separar os nomes das variáveis estruturas com pontos até o campo desejado.

(4)

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

struct indutancia {

float lm; float ld; };

struct transformador {

struct indutancia l; //aqui uma variável do tipo indutância é criada char tipo_nucleo[30];

int np; int ns; };

int main(void) {

struct transformador trafo; trafo.l.lm = 1.5e-3;

trafo.l.ld = 1.34e-7;

strcpy(trafo.tipo_nucleo,"TOROIDAL"); trafo.np = 100;

trafo.ns = 230;

printf("DADOS TRAFO\nTipo:%-10s Ns/Np = %d/%d = %.3f Lm = %.3e Ld = %.3e\n",

trafo.tipo_nucleo,trafo.ns,trafo.np,(float)trafo.ns/trafo.np,trafo.l.lm,trafo.l.ld); system("PAUSE");

return 0; }

Programa 4 Estruturas dentro de estruturas.

Finalmente é interessante, em certos casos, saber o tamanho exato de uma determinada estrutura de dados. Assim, pode-se usar o operador sizeof para avaliar o espaço ocupado por determinada estrutura. Porém antes é necessário lembrar que alguns compiladores costumam organizar o espaço de memória de uma forma segmentada, formada por blocos de bits ou bytes.

Lembrando que, normalmente os blocos são especificados e chamados como segue:

Nibble: 4bits

Byte: 8 bits ou 2 nibbles

Word: 16 bits ou 2 bytes

Double word: 32 bits ou 4 bytes

Quad word: 64 bits ou 8 bytes

Parágrafo: 16 bytes

Página: 16 parágrafos

(5)

#include <stdio.h> #include <stdlib.h>

struct capacitor {

char tipo[21]; float valor; float tol; };

int main(void) {

printf("tamnaho da estrutura: %d bytes\n", sizeof (struct capacitor)); system("PAUSE");

return 0; }

Programa 5 Usando sizeof para obter o tamanho de uma estrutura.

Observe que o espaço reservado para a estrutura é sempre múltiplo de uma Double Word, i.e., múltiplo de 4 bytes (mesmo que a soma de todas as variáveis da estrutura seja inferior a isso).

U

NIÕES

Uma união em C é uma área de memória compartilhada por mais de uma variável.

#include <stdio.h> #include <stdlib.h>

union dados {

char c[2]; short int si; };

int main(void) {

union dados data; data.si = 346;

printf("Sh. int:%#06x, Byte mais sig.:%#04x, Byte menos sig.: %#04x do dado\n", data.si,data.c[1],data.c[0]); data.c[1]++;

printf("Sh. int:%#06x, Byte mais sig.:%#04x, Byte menos sig.: %#04x do dado\n", data.si,data.c[1],data.c[0]); data.c[1] = data.c[0];

printf("Sh. int:%d, Byte mais sig.:%3d, Byte menos sig.: %3d do dado\n",

data.si,data.c[1],data.c[0]); data.si = RAND_MAX;

printf("Sh. int:%d, Byte mais sig.:%d, Byte menos sig.: %d do dado\n",

data.si,data.c[1],data.c[0]); system("PAUSE");

return 0; }

Programa 6 Uniões.

(6)

1 byte 1byte

si

c[1]

c[0]

Figura 1 Espaço reservado pela união.

Perceba através do Programa 6 que eu posso alterar separadamente as variáveis. Observe que realizando a operação data.c[1]++ estou incrementando o caractere c[1], que é a parte alta do short int si definido também na união. Lembre-se que as variáveis compartilham o mesmo espaço de memória.

Um uso interessante para uniões é quando é necessária a manipulação de dados (leitura ou escrita) quando existe uma restrição. Por exemplo, supondo que uma barra de LEDs com 16 LEDs esteja conectada a um μC, sendo que 8 LEDs estejam em uma porta e os outros 8 LEDs estejam em uma porta diferente, como na Figura 1.

Figura 2 Bargraph.

Usualmente, as portas são representadas por registradores acessados no código utilizando variáveis. Assim, a porta P1 geralmente é representada por uma variável diferente da variável que representa a porta P3. É muito interessante poder trabalhar com a barra de LEDs como uma variável de 16 bits no programa (isso torna as operações muito mais fáceis), porém para imprimir essa variável seria necessário manipular os 16 bits de modo a imprimir os 8 bits mais significativos e os 8 bits menos significativos. Utilizando uma união (como a mostrada no Programa 6 e na Figura 1) é possível trabalhar com uma variável de 16 bits e imprimi-la separadamente sem nenhuma manipulação adicional.

(7)

T

IPOS DEFINIDOS PELO USUÁRIO

(

TYPEDEF

)

Em C é possível atribuir outros nomes para os tipos de variáveis através da utilização da palavra chave typedef. A utilização desta palavra-chave se faz seguindo esta construção:

typedef nome_do_tipo novo_nome;

Estude com cuidado o Programa 5.

#include <stdio.h> #include <stdlib.h>

int main(void) {

typedef short int _16bits; //defino outro nome para short int: _16bits typedef char _8bits; //defino outro nome para char: _8bits union dados

{

_16bits word; //_16bits é utilizado para declarar o tipo short int _8bits byte[2]; //_8bits é utilizado para declarar o tipo char }data;

data.word = 1293;

printf("Imprimindo os 16 bits: %d = %#06x\n",data.word,data.word); printf("Imprimindo parte alta: %d = %#04x e parte baixa: %d = %#04x\n", data.byte[1],data.byte[1],data.byte[0],data.byte[0]);

system("PAUSE"); return 0;

}

Programa 7 Usando typedef.

Um uso interessante de typedef é renomear estruturas e uniões para facilitar a definição de variáveis. Veja um exemplo do uso de typedef no Programa 8, no qual o Programa 2 foi modificado.

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

typedef struct capacitor {

char fabricante[20]; char tipo[20]; float valor; float tol; } cap;

int main(void) {

cap c[10]; //cria um vetor com 10 variáveis do tipo capacitor strcpy(c[0].fabricante,"EPCOS");

strcpy(c[1].fabricante,"PHILIPS"); strcpy(c[0].tipo,"TANTALO"); strcpy(c[1].tipo,"ELETROLITICO"); c[0].valor = 2.2e-6;

c[1].valor = 2.2e-3; c[0].tol = 10; c[1].tol = 20;

printf("Fab:%-10s Tipo:%-13s valor:%.2e Tol:%.2f%%\n",

c[0].fabricante,c[0].tipo,c[0].valor, c[0].tol); printf("Fab:%-10s Tipo:%-13s valor:%.2e Tol:%.2f%%\n",

c[1].fabricante,c[1].tipo,c[1].valor, c[1].tol); system("PAUSE");

return 0; }

(8)

E

XERCÍCIO

Defina uma estrutura de dados para representar um chuveiro eletrônico. A estrutura deverá conter o valor nominal da potência do chuveiro, a tensão nominal do mesmo e uma variável que irá indicar a tensão eficaz aplicada ao chuveiro (variável que irá de 0 até 1, representando a percentagem de tensão nominal aplicada a resistência do chuveiro). O valor de percentagem representa o controle eletrônico do chuveiro.

[1] Utilize funções para ler o valor dos campos tensão nominal e potência nominal.

[2] Crie uma função que retorna o valor nominal da resistência do chuveiro (a função deverá receber uma struct).

[3] Crie uma função que retorna o valor da tensão atual do chuveiro (a função deverá receber uma struct).

[4] Crie uma função que retorna a corrente atual drenada pelo chuveiro (a função deverá receber uma struct).

[5] Crie uma função que retorna o valor da potência atual do chuveiro (a função deverá receber uma struct).

Imagem

Figura 1  Espaço reservado pela união.

Referências

Documentos relacionados

Portanto, mesmo percebendo a presença da música em diferentes situações no ambiente de educação infantil, percebe-se que as atividades relacionadas ao fazer musical ainda são

As pontas de contato retas e retificadas em paralelo ajustam o micrômetro mais rápida e precisamente do que as pontas de contato esféricas encontradas em micrômetros disponíveis

Observe que ponteiros são utilizados para modificar meus dados dentro da função, atribuindo valores utilizando o operador seta.. Para ler os dados, basta chamar

O presente estudo objetivou testar a influência do guano na diversidade e abundância de invertebrados na caverna Toca da Raposa, município de Simão Dias,

Foi apresentada, pelo Ademar, a documentação encaminhada pelo APL ao INMETRO, o qual argumentar sobre a PORTARIA Nº 398, DE 31 DE JULHO DE 2012 E SEU REGULAMENTO TÉCNICO

Neste trabalho avaliamos as respostas de duas espécies de aranhas errantes do gênero Ctenus às pistas químicas de presas e predadores e ao tipo de solo (arenoso ou

Box-plot dos valores de nitrogênio orgânico, íon amônio, nitrito e nitrato obtidos para os pontos P1(cinquenta metros a montante do ponto de descarga), P2 (descarga do

Ao longo do livro, você poderá notar que a maioria das receitas leva ou azeite de oliva ou manteiga como gordura para cozinhar - e estas são excelentes fontes de gordura.. Porém,