[CAPÍTULO 1] - [CAPÍTULO 2] - [CAPÍTULO 3]
[PARTE 1] - [PARTE 2] - [PARTE 3] - [PARTE 4] - [PARTE 5] - [PARTE 6]
[PARTE 1] - [PARTE 2] - [PARTE 3] - [PARTE 4] - [PARTE 5] - [PARTE 6]
Enumerações e Campos de Bits
Enumerações
Uma enumeração é uma extensão da linguagem C acrescentada pelo padrão ANSI. Uma enumeração é uma declaração de um novo tipo de dados que consiste em um conjunto de constantes inteiras que especficam todos os valores legais que uma variável desse tipo pode ter.Enumerações são definidas de forma semelhante a estruturas; no entanto, utiliza-se a palavra-chave enum para assinalar o início de um tipo de enumeração.
FORMA GERAL:
enum identificador { Simbolo_1, Simbolo_2, ... Simbolo_n } var_1, var_2, ..., var_n;
Em uma enumaração cada
Simbolo_i
representa um valor inteiro. Cada símbolo recebe um valor maior em uma unidade do precedente. Por default, o valor do primeiro símbolo é 0. No entanto, você pode especificar o valor de um ou mais símbolos usando um inicializador. O símbolos que aparecem após os inicializadores recebem valores maiores que o da inicialização precedente.Exemplos
enum dt_wday { Sunday , Monday , Tuesday , Wednsday , Thursday , Friday , Saturday }; enum dt_month{ January = 1 , February , Mars , April , May , June , July , August , September , October , November , December };
Campos de Bits
Exemplo
struct { unsigned mday : 5; unsigned month: 4; unsigned year :22; unsigned isBCE: 1; } bitf;
Exemplo Completo
O programa abaixo ilustra todos os mecanismos de definição de novos tipos estruturados pelo usuário:- estruturas
struct
- definição de novos nomes para tipos
typedef
- enumerações
enum
- uniões
union
- campos de bits
struct
<time.h>
.Para o entedimento do exemplo que trata de datas do calendário gregoriano você pode consultar:
Para implementação do algoritmo DOOMSDAY para o cálculo do dia da semana de uma data, consulte:
/** date.h Author: Luciano R. Coutinho, 2007. lrc@deinf.ufma.br */ #ifndef DATE_H #define DATE_H #include <limits.h> /* * A type for storing dates in the range: * from Jan 1st , year 2^22 BCE * to Dec 31th, year 2^22 */ #if ( UINT_MAX < 0xffffffff ) typedef long date_t; #else typedef int date_t; #endif enum dt_wday { Sunday , Monday , Tuesday , Wednsday , Thursday , Friday , Saturday }; enum dt_month{ January = 1 , February , Mars , April , May , June , July , August , September , October , November , December }; struct dt { enum dt_wday wday; /* day of the week : 0 .. 6 */ unsigned mday; /* day of the month : 1 .. 31 */ unsigned yday; /* days since Jan. 1 : 1 .. 366 */ unsigned mweek; /* week of the month : 0 .. 5 */ unsigned yweek; /* week of the year : 0 .. 53 */ enum dt_month month; /* month : 1 .. 12 */ long year; /* year : -2^22 .. 2^22 */ unsigned isBCE; /* is Before Common Era ? */ long serial; /* number of days */ }; date_t date(date_t *); /* get current date */ date_t mkdate(struct dt *); /* code struct dt* in a date_t */ struct dt * gcdate(date_t); /* decode date_t in a struct dt */ struct dt * diffdate(date_t,date_t); /* interval between dates */ size_t strfdate(char*, size_t, const char*, const struct dt*); int printf_date(const char *, const struct dt*); int scanf_date (const char *, const struct dt*); #endif
/** date.c Author: Luciano R. Coutinho, 2007. lrc@deinf.ufma.br */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include "date.h" union date_t { date_t ival; struct { unsigned mday : 5; unsigned month: 4; unsigned year :22; unsigned isBCE: 1; } bitf; }; /* Global Shared */ static struct dt dt_buf; static int num_days[13] = { 0 , /* skiped */ 31, /* January */ 28, /* February */ 31, /* Mars */ 30, 31, 30, 31, 31, 30, 31, 30, 31 /* December */ }; /* Functions */ date_t date(date_t * d) { time_t now = time(NULL); struct tm *tm_now = localtime(&now); union date_t ud; ud.bitf.mday = tm_now->tm_mday; ud.bitf.month= tm_now->tm_mon + 1; ud.bitf.year = tm_now->tm_year + 1900; ud.bitf.isBCE= 0; if ( d ) *d = ud.ival; return ud.ival; } /* Gregorian Calendar The Gregorian calendar system adopts the following leap year rule: * Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100; the centurial years that are exactly divisible by 400 are still leap years. For example, the year 1900 is not a leap year; the year 2000 is a leap year. Doomsday Algorithm * It takes advantage of the fact that within any calendar year, some days (e.g., 3/1, 4/4, 6/6, 8/8, 10/10, 12/12, the last day of February) always occur on the same day of week - the so-called "doomsday". DOOMSDAY(y) = (Tuesday + (y) + (y)/4 - (y)/100 + (y)/400)%7 */ static enum dt_wday calculate_wday(union date_t ud) { } static short gc_calculate_yday(union date_t ud) { } static short gc_calculate_mweek(union date_t ud) { } static short gc_calculate_yweek(union date_t ud) { } static long gc_calculate_serial(union date_t ud) { } /** interprets a given date_t as a Gregorian calendar date */ struct dt * gcdate(date_t d) { union date_t ud = { d }; dt_buf.mday = ud.bitf.mday ; dt_buf.month= ud.bitf.month; dt_buf.year = ud.bitf.year ; dt_buf.isBCE= ud.bitf.isBCE; gc_calculate_wday (); gc_calculate_yday (); gc_calculate_mweek (); gc_calculate_yweek (); gc_calculate_serial(); return &dt_buf; } date_t mkdate(struct dt * sd) { }
#include <stdio.h> #include <stdlib.h> #include "date.h" union date_t { date_t ival; struct { unsigned mday : 5; unsigned month: 4; unsigned year :22; unsigned isBCE: 1; } bitf; }; char * wday_name[] = { "Seguinda", "Terca", "Quarta", "Quinta", "Sexta", "Sabado" } int main(int argc, char *argv[]) { union date_t ud; date_t d; struct dt *sd; d = date(NULL); printf("hoje representado no tipo date_t: %ld\n",d); sd = gcdate(d); printf("hoje decomposto\t\t\t: %d %2d/%2d/%4d\n",sd->wday,sd->mday,sd->month,sd->year); ud.bitf.mday = 7; ud.bitf.month = September; ud.bitf.year = 1822; ud.bitf.isBCE = 0; sd = gcdate(ud.ival); printf("a idependência ocorreu num(a) %s \n",wday_name[sd->wday]); //system("PAUSE"); return 0; }
Exercícios
- Conclua o exemplo
date.h
/date.c
; Escreva as funções-
date_t mkdate(struct dt *); /* code struct dt* in a date_t */
-
struct dt * gcdate(date_t); /* decode date_t in a struct dt */
-
struct dt * diffdate(date_t,date_t); /* interval between dates */
-
size_t strfdate(char*, size_t, const char*, const struct dt*);
-
int printf_date(const char *, const struct dt*);
-
int scanf_date (const char *, const struct dt*);
-
- Escreva um programa que teste todas as funções criadas acima.
Bibliografia e fonte:
- [CCT] Schildt, H. (1996) C, completo e total: 3a Ed.. São Paulo, Makron.
- LP, UFMA; Coutinho, Lucian. Linguagem de programação para ciencia da computação da ufma.http://www.deinf.ufma.br/~lrc/2009.1/LP/
- [K&R] KERNIGHAN, B. e RITCHIE, D. (1990) C, a linguagem de programação: padrão ANSI. Rio de Janeiro: Campus.
- DEITEL, H. M. (1999) Como programar em C. Rio de Janeiro: LTC.
- Módulo Consultoria e Informática (1989) Linguagem C: programação e aplicações. Rio de Janeiro: LTC.
Coloque aqui o seu email