Você está na página 1de 222

.: CP 5593.6, 2009.

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

search

Prof. Luciano R. Coutinho email:lrc@deinf.ufma.br

Apresentao
lrc , 16 March 2008 (created 16 March 2008)
no tags

Ementa
Conceitos Gerais. Tipos de linguagens. Linguagem de programao estruturada. Variveis e tipos de dados. Estruturas de controle de fluxo de execuo. Modularizao. Tipos complexos de dados. Operaes com arquivos. Aplicaes.

Objetivos
Apresentao de uma linguagem de programao que ser usada no aprendizado de tcnicas de programao e na modelagem de problemas.

Programa
1 Introduo s linguagens de programao 2 Viso Geral de C 2.1 Padronizaes 2.2 Caractersticas 2.3 Estrutura geral de um programa em linguagem C 3 Tipos de dados e tipos de variveis 3.1 Variveis inteiras, caracter, e ponto flutuante 3.2 Definio de variveis globais, externas, locais e estticas 4 Operadores e expresses 4.1 Operadores aritmticos, relacionais, lgicos, bit a bit 4.2 Operador de atribuio condicional e operador de moldagem 4.3 Expresses em C 5 Controle de fluxo de execuo 5.1 Desvios incondicionais 5.2 Desvios condicionais 5.3 Comandos de malha 6 Funes 6.1 Tipos de funes 6.2 Passagem de parmetros por valor e por endereo 6.3 Construo de funes e funes padronizadas 7 Vetores e ponteiros 7.1 Alocao esttica e dinmica 7.2 Definio e inicializao de vetores 7.3 Ponteiros em C 7.4 Aplicaes de ponteiros 8 Estruturas, unies e tipos definidos pelo usurio 8.1 Definio de estruturas

1 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

8.2 Vetor de estruturas 8.3 Passagem de estruturas como parmetros 8.4 Definio de Unies 8.5 Tipos definidos pelo usurio 9 Entrada e sada em arquivos 9.1 Conceitos de arquivos 9.2 Arquivos no MSDOS e UNIX 9.3 Arquivos textos e binrios 9.4 Operaes de leitura e escrita em arquivos 9.5 Funes da biblioteca C para manipulao de arquivos 10 Pre - Processador C 10.1 Diretivas de Compilao

Procedimentos de Ensino/Aprendizagem
Recursos Didticos
Uso de computadores, ambiente desenvolvimento em C, quadro-branco, marcador, notas de aulas.

Metodologia
Aulas terico - prticas em laboratrio, desenvolvimento e discusso de programas, trabalhos de programao pelos alunos.

Sistema de Avaliao
Trs Avaliaes (A1, A2 e A3), seguidas de uma Reposio (R) (para aqueles cuja mdia (A1+ A2+ A3)/ 3 < 7,0) e uma Final (F) (para aqueles cuja mdia corrigida pela Reposio seja > = 4,0 e < 7,0). Seguindo as normas da UFMA, ser APROVADO o aluno que: tiver mdia ao fim da ltima avaliao maior ou igual a SETE media = (A1+ A2+ A3)/ 3 > = 7,0 OU tiver mdia aps a reposio maior ou igual a SETE mediaRep = (A1+ A2+ A3 - min{ A1,A2,A3} + R)/ 3 > = 7,0 OU tiver mdia aps a reposio MAIS nota da Final maior ou igual a 12 mediaRep + Final > = 12,0

Avaliaes
A1 e A2
Feitas a partir de: PROVAS ESCRITAS INDIVIDUAL (P1 e P2) LISTAS de EXERCCIOS INDIVIDUAIS (L1 e L2) Calculo: Avaliao A1 = ( 2* P1 + L1 ) / 3 Avaliao A2 = ( 2* P2 + L2 ) / 3

A3
Feita a partir de: PROVA ESCRITA INDIVIDUAL (P3) PROJETO de PROGRAMAO em GRUPO (T3) Calculo:

2 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Avaliao A3 = (2* T3 + P3) / 3

Reposio
Consistir em uma PROVA ESCRITA INDIVIDUAL. A nota da Reposio ir substituir a menor nota dentre A1, A2 e A3. O assunto da Reposio ser o contedo correspondente ao contedo da menor nota sendo substituda.

Final
Consiste em uma PROVA ESCRITA INDIVIDUAL. O assunto da Final ser todo o contedo ministrado durante o curso.

Bibliografia

Cronograma
lrc , 9 March 2009 (created 16 March 2008) Data Assunto 25/ 08 I ntroduo; viso geral de C 27/ 08 Declaraes: I dentificadores e Tipos de Dados Bsicos 01/ 09 Declaraes: Variveis e Classe de Memria 03/ 09 Declaraes: Tipo de Acesso, I nicializao e Constantes 08/ 09 sem aula; viajando S. Paulo 10/ 09 sem aula; viajando S. Paulo 15/ 09 Operadores e Expresses: atribuies, aritmtica e lgica 17/ 09 Operadores e Expresses: atribuies, aritmtica e lgica 22/ 09 Operadores e Expresses: bit-a-bit e especiais 24/ 09 Controle de Fluxo: Comandos de Seleo 29/ 09 Controle de Fluxo: Laos e Desvios I ncondicionais 01/ 10 1a. Prova 06/ 10 Funes: definio, declarao e chamada 08/ 10 Funes: main( ) e recurso 13/ 10 Vetores, matrizes e strings 15/ 10 Vetores, matrizes e strings 20/ 10 Ponteiros 22/ 10 Ponteiros 27/ 10 Exemplo: Lista de Strings 29/ 10 Alocao Dinmica 03/ 11 Vetores para Ponteiros, Ponteiros para Vetores e Ponteiros para Ponteiros 05/ 11 2a Prova Escrita 10/ 11 Estruturas 12/ 11 typedef, ponteiros para funes e union 17/ 11 typedef, ponteiros para funes e union 19/ 11 Enumeraes e Campos de Bits 24/ 11 Entrada/ Sada: console 26/ 11 Entrada/ Sada: arquivos 01/ 12 03/ 12 08/ 12 Pr-processador C 10/ 12 3a Prova Escrita 15/ 12 Reposio
no tags

3 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

17/ 12 Final

I ntroduo; viso geral de C


lrc , 16 March 2008 (created 16 March 2008)
no tags

Tpicos
As Origens de C C - Caractersticas Nvel Mdio Estruturada Para programadores Programao de sistemas Estrutura Geral de um programa em C Edio, compilao e Link Edio C versus C+ +

As Origens de C
Ken Thompson e Dennis Ritchie (da esquerda pra direita), os criadores das linguagens B e C, respectivamente:

Para detalhes, leia: D. M. Ritchie; O Desenvolvimento da Linguagem C http:/ / www.caloni.com.br/ blog/ archives/ historia-da-linguagem-c-parte-1 http:/ / www.caloni.com.br/ blog/ archives/ historia-da-linguagem-c-parte-2

Evoluo das Linguagem de Programao


Ref: History of programming languages Computer Languages History

Padronizao ANSI
Ref: Jones, Derek M. (2008) "The New C Standard: An Economic and Cultural Commentary."

4 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

5 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

C - Caractersticas
Nvel Mdio Estruturada Para programadores Programao de sistemas

Linguagem de Nvel Mdio

Linguagem Estruturada

Linguagem para Programadores

Linguagem para Programao de Sistemas

6 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Estrutura geral de um programa


Palavras Reservadas

Funes

Exemplo

Edio, compilao e Link Edio

7 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

IDE - Integrated Developmente Environments


DevCpp Code::Blocks + gcc jGRASP + gcc TurboC

Termos
Compilao Separada Biblioteca Padro ANSI

C versus C++

Leitura Recomendada
CCT captulo 1 K&R captulo 1 D. Ritche, O Desenvolvimento da Linguagem C* . Histrico das Linguagens de Programao Wikipedia: Ling. C

Exerccios
1. A linguagem C considerada uma linguagem de nvel mdio. Explique o que isto significa e quais as implicaes em termos prticos. 2. Programas escritos em C so ditos possuir alto grau de portabilidade. Explique o que isto significa e quais as implicaes em termos prticos. 3. A linguagem C, a exemplo de Pascal dito ser uma linguagem estruturada. Pesquise e descreva as principais diferenas entre a programao estruturada em Pascal e a programao estruturada em C. 4. Faa um resumo esquemticos das datas e principais acontecimentos relatados no artigo O Desenvolvimento da Linguagem C* de D. Ritchie. 5. A linguagem C uma linguagem compacta com apenas 32 palavras reservadas. Pesquise e liste as palavras reservadas de C. Classifique-as em: especificadores de tipos controle de fluxo especificadores de classe de memria outros 6. Modifique o programa media.c para exibir o nome do vetores P e T durante a leitura dos dados. Dica: redefina a funo

ler para aceitar como parametro o nome do vetor sendo lido, alm do prprio vetor. De posse do nome do vetor sendo
lido, exiba este nome antes da leitura de cada posio.

Declaraes: I dentificadores e Tipos de Dados Bsicos


lrc , 29 March 2008 (created 24 March 2008)
no tags

Objetivos
Na primeira aula, vimos que um programa em C pode ser visto como uma seqncia de DECLARAES. De maneira geral, uma DECLARAO introduz um novo nome - um IDENTIFICADOR - e associa a este uma interpretao. Tome como exemplo o seguinte trecho de cdigo:

8 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

00: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14:

#include <stdio.h> double x; void p(float b, int e) { short int i; x = b; ... } int main() { p(3.1415, 5); printf("%f",x); return 0; }

Na linha 1, vemos uma DECLARAO de VARIVEL GLOBAL. Nas linhas 3 a 8, temos uma DECLARAO de FUNO que, por sua vez, formada por uma DECLARAO de PARMETROS (linha 3), uma DECLARAO de VARIVEL LOCAL (linha 4) e uma seqncia de comandos (linhas 5-7). Em cada uma dessas DECLARAES um novo IDENTIFICADOR introduzido com uma interpretao particular! Na declarao da linha 1, o IDENTIFICADOR introduzido x e sua interpretao VARIVEL GLOBAL do TIPO BSICO double. Na declarao das linhas 3 a 8, o IDENTIFICADOR p e sua interpretao FUNO que recebe como PARMETROS um valor do TIPO BSICO float e um valor do TIPO BSICO int; tem uma VARIVEL LOCAL do TIPO BSICO short int, executa os comandos das linhas 6-7 e ao final nada retorna ( TIPO BSICO void). Note que, nesses exemplos, a interpretao dada a um IDENTIFICADOR est ligada de maneira ntima com um TIPO de DADOS BSICO. Nesta aula, nosso objetivo mostrar atravs de exemplos o que um IDENTIFICADOR vlido e quais so os TIPOS de DADOS BSICOS - os dois ingredientes fundamentais de toda DECLARAO em um programa C.

IDENTIFICADORES
Em C, um IDENTIFICADOR uma seqncia de LETRAS ou DGITOS onde: O primeiro caracter deve ser uma LETRA ( 'a',...,'z','A',...,'Z','_' ) O caracter '_' contado como uma LETRA LETRAS maisculas (e.g., 'A') so consideradas diferentes de letras minsculas (e.g., 'a') isto implica que o IDENTIFICADOR aux diferente de Aux que diferente de AUX PALAVRAS RESERVADAS tais como if, else, char, int, ... no podem ser usadas como IDENTIFICADORES.

Pelo padro C ANSI, um IDENTIFICADOR pode ter qualquer tamanho. Observaes Para IDENTIFICADORES INTERNOS (i.e., nomes restritos a uma nica UNIDADE de COMPILAO), pelo menos os primeiros 31 caracteres so significativos; algumas implementaes podem utilizar um conjunto maior de caracteres significativos. J os IDENTIFICADORES EXTERNOS (i.e., nomes de de VARIVEIS GLOBAIS e FUNES compartilhados entre vrias UNIDADES de COMPILAO) so mais restritos: as implementaes podem considerar em casos extremos apenas 6 caracteres como significativos, e podem ignorar as distines entre letras maisculas e minsculas.

Atividade 1: Validando Indentificadores


Vamos escrever um programa em C ( id.c) que dado uma palavra (cadeia de caracteres) imprima na tela um

identificador! ou no um identificador! caso a palavra obedea ou no a definio de identificador dada


acima. DICA - comee o programa assim:

9 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> char str[80]; /* armazena uma cadeia de at 79 caracteres */

int main() { printf("Digite uma palavra: "); scanf("%s", str); /* le do usrio uma cadeia de caracteres */ ... }

TIPOS de DADOS BSICOS


H cinco tipos de dados bsicos em C:

char : um nico byte, capaz de conter um caracter no conjunto de caracteres local; int : um inteiro, normalmente refletindo o tamanho natural dos inteiros da mquina hospedeira; float : ponto flutuante em preciso simples; double : ponto flutuante em dupla preciso; void : conjunto vazio de valores.
Todos os outros tipos de dados em C so baseados em um desses tipos bsicos.

Modificadores
Exceto void, os tipos de dados bsicos podem ter vrios MODIFICADORES precedendo-os. Um MODIFICADOR usado para alterar o significado de um tipo bsico para adapt-lo necessidade de diversas situaes. So MODIFICADORES de tipos:

long short signed unsigned

short ou long - referem-se a diferentes tipos de inteiros: A palavra int pode ser omitida e normalmente o ! short = short int long = long int
Obs.: Alguns compiladores permitem long long int ! (Fora do Padro ANSI)

long pode tambm ser aplicado a double de tal modo que: float double long double signed ou unsigned - podem ser aplicados a char, ou a short ou long ( int ).
Equivalencias char = signed char ou char = unsigned char, a depender da mquina hospedeira;

signed int = int = signed signed long = long signed short = short unsigned int = unsigned
Obs.: Alguns compiladores podem permitir unsigned double ! (Fora do Padro ANSI)

Tamanho e Faixa de Valores


O tamanho e faixa de valores dos tipos bsicos de dados variam de acordo com: tipo do processador implementao do compilador No entanto, o padro ANSI C estipula valores mnimos:

10 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atividade 2: Explorando <limits.h>


Nos arquivos de cabealho <limits.h> e <float.h> encontram-se definidas constantes simblicas para a faixa de valores e tamanho em bytes dos tipos de dados bsicos e modificados da linguagem C, conforme foram implementados em um dado compilador/ mquina. Nesta atividade, o seu objetivo escrever um programa tipos.c que inclua os arquivos de cabealho <limits.h> e

<float.h> e imprima - para os tipos mostrados na tabela 2.1 - as seguintes informaes : TIPO char unsigned char signed char ... VALOR_MIN -128 0 -128 VALOR_MAX 127 255 127 TAMANHO em BYTES 1 1 1

Como ponto de partida, voc pode iniciar o seu programa assim:

#include <limits.h> #include <float.h> char c; unsigned char uc; signed char sc; int i; ... int main(void) { printf("TIPO\t\t\tVALOR_MIN\t\tVALOR_MAX\tTAMANHO em BYTES\n"); printf("char\t\t\t%i\t\t\t%i\t\t%i\n", CHAR_MIN, CHAR_MAX, sizeof c); printf("unsigned char\t\t%i\t\t\t%i\t\t%i\n", 0, UCHAR_MAX, sizeof uc); printf("signed char\t\t%i\t\t\t%i\t\t%i\n", SCHAR_MIN, SCHAR_MAX, sizeof sc); ... }

Leitura Recomendada
CCT captulo 2 K&R captulos 2 Seebach, "Everything You Ever Wanted to Know about C Types"

11 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

What's in a type? Floating point and derived types Implementation details Portability and pitfalls http:/ / pt.wikipedia.org/ wiki/ Tipo_de_dado

Para detalhes sobre representacao de caracteres: http:/ / www.ime.usp.br/ ~ pf/ algoritmos/ aulas/ char.html Para detalhes sobre representao de nmeros: inteiros ( int) http:/ / www.ime.usp.br/ ~ pf/ algoritmos/ aulas/ int.html ponto flutuante ( float, double) http:/ / en.wikipedia.org/ wiki/ Floating_point http:/ / en.wikipedia.org/ wiki/ Double_precision http:/ / en.wikipedia.org/ wiki/ IEEE_754

Para detalhes sobre o padro ANSI C: Jones, Derek M. (2008) "The New C Standard: An Economic and Cultural Commentary."

Exerccios
1. Faa por completo a atividade 1 2. Faa por completo a atividade 2 3. Utilizando os TIPOS inteiros em C, escreva programas para: a. Dado um nmero inteiro positivo n, calcular a soma dos n primeiros nmeros naturais. b. Dado um nmero inteiro positivo n, imprimir os n primeiros naturais mpares. Exemplo: Para n= 4 a sada dever ser 1,3,5,7. c. Dados n e dois nmeros inteiros positivos i e j diferentes de 0, imprimir em ordem crescente os n primeiros naturais que so mltiplos de i ou de j e ou de ambos. Exemplo: Para n = 6 , i = 2 e j = 3 a sada dever ser : 0,2,3,4,6,8. d. Dizemos que um nmero natural triangular se ele produto de trs nmeros naturais consecutivos. Exemplo: 120 triangular, pois 4.5.6 = 120. Dado um inteiro no-negativo n, verificar se n triangular. e. Dado um inteiro positivo p, verificar se p primo. f. Dados trs nmeros naturais, verificar se eles formam os lados de um tringulo retngulo. 4. Utilizando os TIPOS ponto flutuante em C, faa programas para os seguintes enunciados: a. Um programa que leia uma temperatura em graus celsius e a converta para fahrenheit. b. Uma pessoa aplicou um capital de x complexos (1) a juros mensais de z durante 1 ano. Deseja-se um programa que determine o montante de cada ms durante este perodo. c. Dados nmeros reais a, b e c, calcular as razes de uma equao do 2o grau da forma ax^ 2 + b^ x + c = 0. 5. Utilizando o TIPO char, re-escreva os programas anteriores para ao final perguntar ao usrio: deseja processar

outro valor? [s/n]. Se o usurio digitar 's' ou 'S' o programa deve continuar processando uma nova entrada;
caso contrrio deve terminar.

Declaraes: Variveis e Classe de Memria


lrc , 29 March 2008 (created 24 March 2008)
no tags

Objetivo
Na ltima aula, vimos que uma DECLARAO introduz um novo IDENTIFICADOR e associa a este uma interpretao. Dentre as interpretaes possveis, um IDENTIFICADOR pode ser declarado para ser o nome smblico de uma VARIVEL. Neste caso, temos um dos mais importantes tipos de DECLARAO - a DECLARAO de VARIVEIS. Nesta aula, nosso objetivo estudar: a forma geral de DECLARAES de VARIVEIS em C a noo de CLASSE de MEMRIA associada a uma VARIVEL

Variveis

12 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

VARIVEIS so abstraes de locais de armazenamento de dados. Os dados armazenados em uma VARIVEL podem mudar ao longo da execuo de um programa. Da o nome VARIVEL. Uma VARIVEL possui dois atributos principais: um TIPO de DADO : determina o significado dos valores achados em uma VARIVEL. uma CLASSE de MEMRIA (ou CLASSE de ARMAZENAMENTO) : determina o tempo de vida e a rea de memria na qual a VARIVEL alocada. Variveis tambm podem ter: um TIPO de ACESSO : determinam a maneira como as variveis podem ser acessadas ou modificadas.

Variveis podem ser declaradas tanto fora quando dentro de funes. No primiro caso as variveis so ditas GLOBAIS; no segundo caso, LOCAIS.

Declarao de Variveis
Em C, uma DECLARAO de VARIVEL assume a seguinte forma geral:

ESPEC-DECLARAO DECLARADOR-1 = INICIALIZADOR-1, ..., DECLARADOR-n = INCIALIZADOR-n;


Onde: ESPEC-DECLARAO e cada DECLARADOR-i so obrigatrios; cada = INICIALIZADOR-i opcional.

ESPEC-DECLARAO uma sequncia composta de pelo menos um dentre trs categorias de ESPECIFICADOR: ESPECIFICADOR do TIPO de DADO; int, char, float, double e seus MODIFICADORES long, short, signed e unsigned ESPECIFICADOR da CLASSE de MEMRIA; auto, register, static e extern ESPECIFICADOR do TIPO de ACESSO; const e volatile

A forma mais simples de um DECLARADOR um IDENTIFICADOR. Nesta aula, iremos considerar como DECLARADOR apenas IDENTIFICADORES. Um INICIALIZADOR, de maneira geral, consiste em uma EXPRESSO.

Ambiente de Execuo C
Em C, h quatro locais onde uma varivel pode ser alocada: na REA de DADOS ESTTICA na PILHA de EXECUO em REGISTRADORES no HEAP

13 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Especificadores da Classe de MEMRIA


Em C, h quatro PALAVRAS RESERVADAS que funcionam como ESPECIFICADORES da CLASSE de MEMRIA durante a DECLARAO de uma VARIVEL:

auto - define variveis automticas na PILHA de EXECUO


so sempre variveis locais a um BLOCO e que so descartados na sada do BLOCO;

register - define variveis automticas em REGISTRADORES


so sempre variveis locais a um BLOCO e que so descartados na sada do BLOCO;

static
podem ser variveis locais a um BLOCO ou externas a todos os BLOCOS retm seus valores durante toda execuo do programa pois so alocadas na REA de DADOS ESTTICA quando em DECLARAES LOCAIS, DEFINE variveis estticas (escopo de BLOCO) quando em DECLARAES GLOBAIS, DEFINE variveis estticas com ligao interna (escopo de UNIDADE DE COMPILAO)

extern
podem ser variveis locais a um BLOCO ou externas a todos os BLOCOS quando em DECLARAES LOCAIS, DECLARA variveis estticas que foram definidas fora do BLOCO das declaraes quando em DECLARAES GLOBAIS, DECLARA variveis estticas com ligao externa, i.e, que foram definidas fora da UNIDADE DE COMPILAO das declaraes

Observao um BLOCO qualquer parte de um programa delimitada por { } ; um BLOCO pode ser o corpo de funo bem como o corpo de um comando composto como if, while, etc.

A seguir ilustram-se a utilizao de Variveis auto, register e static LOCAIS. Variveis static GLOBAIS e variveis

extern sero discutidas em aulas futuras.

Atividade 1: Variveis auto e register


Para ilustrar o uso de auto e register, compile e execute o programa abaixo.

14 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* teste_fat.c ( rev 1.1 ) **/ /* funo fat: calcula fatorial de x **/ unsigned long fat(unsigned short x) { register int i; /* acesso o mais rpido possvel; se no possvel em pilha */ unsigned long ret; /* alocada na pilha; se possvel acesso o mais rpido possve ret = 1; for ( i = 1; i <= x; i++ ) ret = ret * i; return ret; } /* funo main: testa a funo fat acima **/ int main() { auto int i;

/* alocada na pilha */

for( i = 0; i < 20; i++ ) printf("fat(%i) = %lu \n",i,fat(i)); }

A Fazer - No programa acima: declare uma VARIVEL GLOBAL especificando auto como CLASSE de ARMAZENAMENTO, compile e observe as mensagens geradas pelo compilador; declare uma VARIVEL GLOBAL especificando register como CLASSE de ARMAZENAMENTO, compile e observe as mensagens geradas pelo compilador;

Que concluses podemos tirar sobre o uso de auto e register em DECLARAES GLOBAIS?

Atividade 2: Variveis static em DECLARAES LOCAIS


Para ilustrar o uso dos ESPECIFICADORES static em DECLARAES LOCAIS podemos refatorar o programa anterior da seguinte maneira: para n > 12, fat(n) estoura a representao unsigned long int assim, uma primeira medida deve ser barrar o clculo de fat(n) para n> 12 dado que o nmero de valores possveis pequeno, uma segunda idia armazenar os valores j calcular para evitar repetir clculos em chamadas futuras.

15 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* teste_fat.c **/

(rev 1.2)

/* funo fat: para x <=12, calcula fatorial de x para x > 12, retorna 0 **/ unsigned long fat(unsigned short x) { register int i; static unsigned long ret[13]; if ( x > 12 ) return 0; if ( ret[x] != 0 ) return ret[x]; ret[x] = 1; for ( i = 1; i <= x; i++ ) ret[x] = ret[x] * i; return ret[x]; } /* funo main: testa a funo fat acima **/ int main() { int i; for( i = 0; i < 20; i++ ) printf("fat(%i) = %lu \n",i,fat(i)); }

Em DECLARAES LOCAIS, o especificador static usado para indicar uma varivel que DECLARADA LOCALmente mas que ir residir na rea de VARIVEIS GLOBAIS. H duas conseqncias: por se tratar de uma declarao local, a varivel s visvel no BLOCO onde foi declarada por exemplo, a varivel static unsigned long ret[12] s visvel dentro da funo fat por residir na rea de variveis globais, a varivel reter seu valor entre ativaes sucessivas do BLOCO onde foi declarada por exemplo, a varivel static unsigned long ret[12] retm seus valores mesmo quando a funo fat no est executando. Assim, na primeira vez que se chama fat(5), o valor correspondente calculado e armazenado em ret[5]. Em uma segunda chamada fat(5), ao invs de se realizar o mesmo clculo novamente, o valor recuperado de ret[5]. Em outras palavras, a funo passa a "lembrar" clculos anteriores!

A Fazer - No programa acima: na DECLARAO da varivel ret, elimine o ESPECIFICADOR static, compile, execute o programa e verifique o funcionamento do programa. Explique a sada gerada!

Leitura Recomendada
CCT captulo 2 K&R captulos 2 e 4 Franek, Frantisek (2003) "Memory as a Programming Concept in C and C+ + ." Cambridge University Press.

16 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exerccios
Conside o seguinte programa

int i; void g() { static int j; j = i; i = i * 2; printf("g(){ i = %d }

j = %d }\n",i,j);

void f() { i = 2; g(); printf("f() { i = %d }\n",i); } int main() { int i; i = 3; f(); g(); printf("main() { i = %d }\n",i); return 0; }
Qual a sada gerada na tela quando o programa executado? Descreva passo a passo como o ambiente de execuo (rea esttica de dados + pilha de execuo) evolui durante a execuo do programa. Utilizando variveis auto e register, escreva programas para calcular: exponenciao inteira, i.e, a ^ b, onde b um nmero inteiro. raiz quadrada de x, utilizando o mtodo de newton ( onde r(x) representa a raiz de x)

cosseno, utilizando a srie

utilize a funo fat() desenvolvida na atividade 2 veja como exemplo o Programa seno discutido em sala de aula

Declaraes: Tipo de Acesso, I nicializao e Constantes


lrc , 29 March 2008 (created 28 March 2008)
no tags

Objetivo
Nas ltimas aulas, estudamos a forma geral de uma DECLARAO de VARIVEIS ( global ou local ):

ESPEC-DECLARAO DECLARADOR-1 = INICIALIZADOR-1, ..., DECLARADOR-n = INCIALIZADOR-n;

17 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Recapitulando, o ESPEC-DECLARAO uma seqncia composta de: OBRIGATORIAMENTE, um ESPECIFICADOR de TIPO de DADO ( acompanhado ou no de MODIFICADORES )

char signed e unsigned int signed e unsigned long e short float, double e long double
OPCIONALMENTE, um ESPECIFICADOR da CLASSE de MEMRIA

auto register static extern


cada DECLARADOR-i (em sua forma mais simples) consiste em um IDENTIFICADOR cada = INICIALIZADOR-i OPCIONAL e (em sua forma mais simples) consiste em uma CONSTANTE

Na aula de HOJE, nosso objetivo tornar este quadro mais completo apresentando um terceiro e ltimo tipo de ESPECIFICADOR que pode ser utilizado em declaraes: ESPECIFICADOR de TIPO de ACESSO const e volatile Alm disso, discutiremos as regras gerais do processo de INICIALIZAO de VARIVEIS e ao final apresentaremos a forma das CONSTANTES associadas aos tipos bsicos de dados em C.

ESPECIFICADOR de TIPO de ACESSO


Em uma declarao de variveis (globais ou locais), um ESPECIFICADOR de TIPO de ACESSO pode ser utilizado para estabelecer a maneira como as variveis podem ser acessadas ou modificadas. Em C, h duas PALAVRAS RESERVADAS que funcionam como ESPECIFICADORES de TIPO de ACESSO durante uma declarao de variveis:

const volatile

const variveis declaradas const podem ser inicializadas mas no modificadas usar const til quando vc. quer ter certeza que (parte do) seu cdigo no ir alterar valores de certas variveis; uma situao tpica na declarao de CONSTANTES SIMBLICAS, como em:

const double PI = 3.1415927;


Uma outra situao quando vc. passa um argumento a uma funo atravs de um parmetro e deseja que o valor do argumento no seja em hiptese alguma modificado pelo cdigo da funo ... Mais detalhes somente em aulas futuras ...

volatile este ESPECIFICADOR indica que a varivel pode sofrer modificaes de maneira no especificada pelo programa. Em outras palavras, uma varivel volatile pode ter seu contedo alterado (via apontadores e endereos) por comandos que fazem parte de outros programas. Na prtica, volatile indica ao compilador para no realizar otimizao de EXPRESSES contendo tais variveis.

Observao Os ESPECIFICADORES const e volatile podem ser utilizados juntos! Exemplo:

const volatile

unsigned short int

port = 80;

18 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Neste exemplo, a varivel port no pode ser modificado pelo programa sendo escrito mas pode ter seu valor modificado por comandos externos ao programa!

Atividade 1: Variveis const


Teste o cdigo abaixo e observe o Erro de Compilao !

const int x = 100; int main() { x = x + 1; }

/* Isto ir gerar um erro de compilao */

Inicializao de Variveis
Inicializar uma varivel significa dar varivel um valor, no mesmo momento em que ela declarada. De maneira geral, o valor inicial de uma varivel pode ser o resultado de uma EXPRESSO envolvendo dentre outros CONSTANTES, OPERADORES e outras VARIVEIS. Regras de I nicializao Variveis GLOBAIS e variveis LOCAIS static declaradas COM =INICIALIZADOR so inicializadas com o valor de

INICIALIZADOR apenas uma vez no comeo do programa Variveis GLOBAIS e variveis LOCAIS static declaradas SEM =INICIALIZADOR so inicializadas com ZERO apenas
uma vez no comeo do programa Variveis LOCAIS auto e register declaradas COM =INICIALIZADOR so inicializadas com o valor de

INICIALIZADOR toda vez que o BLOCO no qual foram declaradas for ativado Variveis LOCAIS auto e register declaradas SEM =INICIALIZADOR tm valor DESCONHECIDO antes de ser
efetuada uma primeira atribuio a elas Apenas DECLARAES que so DEFINIES podem conter =INICIALIZADOR. Assim, variveis declaradas extern no podem ser inicializadas no momento de suas declaraes!

Atividade 2 : Inicializao de Variveis


Compile, execute e compare a sada do programa abaixo com o que foi dito acima sobre inicializao de variveis:

19 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> int Gi = 3, G_; void f(); /* variveis GLOBAIS */

/* DEClARAAO de f() */

void g() { /*DECLARACAO/DEFINICAO de g() */ char ga_; printf("\n. g():\n"); printf(" ga_ = %i\n", ga_); printf("\n > para terminar digite 't' < "); scanf(" %c",&ga_); if (ga_ != 't' ) f(); /* ativa funo f() */ printf("\n# g():\n"); } void f() { /* DEFINICAO de f() */ static int fsi = 3, fs_; int fai = 3, fa_; printf("\n. printf(" printf(" printf(" printf(" fsi fs_ fai fa_ ++; ++; ++; ++; Aps incremento:\n\n"); fsi = %i\n", fsi); fs_ = %i\n", fs_); fai = %i\n", fai); fa_ = %i\n", fa_); f():\n"); fsi = %i\n", fs_ = %i\n", fai = %i\n", fa_ = %i\n",

fsi); fs_); fai); fa_);

printf("\n printf(" printf(" printf(" printf(" g();

/* ativa funo g() */

printf("\n# f():\n"); } int main () { int m_; printf("\n. printf(" printf(" printf(" f(); main()\n"); Gi = %i\n",Gi); G_ = %i\n",G_); m_ = %i\n",m_);

/* Ativa funo f() */

printf("\n# main()\n"); }

20 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Constantes
Um dos elementos principais na INICIALIZAO de VARIVEIS (e de EXPRESSES em geral) so as constantes. Constantes so VALORES ESPECFICOS de qualquer um dos TIPOS de DADOS bsicos.

Observaes Nas constantes caracter e string, alm dos caracteres comuns, caracteres de controle (no imprimveis) so escritos atravs de um 'cdigo de barra invertida' (veja tabela abaixo) No confunda constantes caracter com string! Uma constante de um nico caracter colocada entre aspas simples; constantes string so colocadas entre aspas duplas. Ou seja, 'a' (constante char) diferente de "a" (constante string)

21 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Leitura Recomendada
CCT captulo 2 K&R captulos 2 e 4

Exerccios
1. Considere o programa da atividade 2. Descreva passo a passo como o ambiente de execuo (rea esttica de dados + pilha de execuo) evolui durante a execuo do programa. Na sua descrio localize onde so alocadas as variveis do programa. 2. Explique qual a diferena entre '0', '\ 0', "0" . 3. A matemtica e a fsica repleta de exemplos de constantes fundamentais. Utilizando variveis decladas com o ESPECIFICADOR const, mostre como voc representaria as seguintes constantes abaixo: razo urea ( ); nmero de Euler (e); velocidade da luz no vcuo (c); massa do eltron em repouso (me); nmero de Avogadro (L); 4. Escreva um programa que converta nmeros de decimais para hexadecimal e octal. Dica: uma maneira simples de fazer o programa ler os nmeros em decimal e os imprimir na tela como constantes inteiras escritas em hexadecimal e octal. Para saber como usar a funo printf para imprimir inteiros em hexadecimal e octal cosulte os livros ou a internet. Veja por exemplo, a pgina abaixo: http:/ / www.dca.fee.unicamp.br/ cursos/ EA876/ apostila/ HTML/ node131.html 5. O programa abaixo, quando compilado, gera uma mensagem de erro. a. Que mensagem de erro essa? b. Como o programa pode ser corrigido para eliminar a mensagem de erro? c. Aps o programa ter sido corrigido e compilado com sucesso, que valores sero impressos na tela ?

22 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Operadores e Expresses: atribuies, aritmtica e lgica


lrc , 9 April 2008 (created 29 March 2008)
no tags

Objetivo
Na aula de HOJE iremos dar incio ao estudo dos OPERADORES da linguagem C. Os OPERADORES, em conjunto com CONSTANTES e VARIVEIS, so os constituintes bsicos de EXPRESSES. Sero detalhados os operadores utilizadoes em expresses: de atribuio aritmtica e lgica

Operadores
Em C, podemos classificar os OPERADORES em cinco grande categorias: Atribuies Aritmticos Lgicos e Relacionais Bit-a-Bit Especiais

Atribuies
Forma geral:

VARIVEL

= EXPRESSO;

23 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atribuies mltiplas:

VAR1 = VAR2 = .... = VARn = EXPRESSO;

C Reduzido: (para todo operador op binrio)

VAR = VAR op EXPRESSO;


equivalente a:

VAR OP= EXPRESSO;

Operadores Aritmticos

Obs.: operadores com o mesmo nvel de PRECEDNCIA so avaliados pelo compilador da ESQUERDA PARA a DIREITA

Exemplo 1
Em :

int a = 3; int b = 2; int c = a + -b * 3 / 2 + a % 3 * 4;

24 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Quanto vale a VAR c? Resposta: operadores de maior precedncia so avaliados primeiro operadores de mesma precedncia so associados da esquerda para a direita ento, a expresso acima seria avaliada assim:

int c = ((a + (((-b)*3)/2)) + ((a%3)*4));

Exemplo 2
Quanto valem i e j abaixo, aps cada atribuio???

int i , j = 2; i = j++; i = -- j; i = --j++;


Resposta:

i = j++; i = -- j; i = --j++;

/* i == 2, j == 3; primeiro armazena o valor de j em i, depois increm /* i == 2, j == 2; primeiro decrementa j, depois armazena o valor de /* expresso invlida */

A ltima expresso invlida pois incremento e decremento DEVEM sempre operar sobre variveis e no sobre expresses!

Exemplo 3
Em :

int c = 3; c = c-- + c;
Quanto vale a VAR c? Resposta: Ateno: O uso de operadores de incremento ( ++) e decremento ( --) em EXPRESSES frequentemente AMBGUO! Evite-o SEMPRE!!! Assim, dependendo da ordem em que o compilador avalia as sub-expresses entre o operador + podemos ter resultados diversos para o valor da varivel c!

Exemplo 4
Veja esse exemplo retirado de um livro:

Quando eu rodo o exemplo acima no meu computador o resultado result == 8 !!! J o livro diz: Avaliando da esquerda para a direita:

25 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Avaliando da direita para a esquerda:

Operadores Lgicos e Relacionais

26 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atividade 1: operadores lgicos implica e ouexcl


Em C, os operadores &&, || e ! correspondem respectivamente aos conectivos E, OU e NO da lgica Booleana. Na lgica booleana, alm destes conectivos, existem vrios outros. Por exemplo: IMPLICAO

A B A -> B ----------------0 0 1 0 1 1 1 0 0 1 1 1
OU EXCLUSIVO

A B A OUEXCL B ----------------0 0 0 0 1 1 1 0 1 1 1 0

Nesta atividade, implemente estes dois operadores como duas funes em C!

int implica(int a, int b) { ... } int ouexcl(int a, int b) { ... }

27 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Aps criar as funes acima, teste-as por meio da funo main abaixo:

int main() { printf("teste printf("%i -> printf("%i -> printf("%i -> printf("%i ->

implica:\n" %i = %i\n", %i = %i\n", %i = %i\n", %i = %i\n",

1, 3, 0, 0,

7, 0, 1, 0,

implica(1,7)); implica(3,0)); implica(0,1)); implica(0,0));

printf("teste ouexcl:\n" printf("%i xor %i = %i\n", printf("%i xor %i = %i\n", printf("%i xor %i = %i\n", printf("%i xor %i = %i\n", }

3, 1, 0, 0,

4, 0, 5, 0,

ouexcl(3,4)); ouexcl(1,0)); ouexcl(0,5)); ouexcl(0,0));

Leituras Recomendadas
CCT captulo 2 K&R captulos 2 http:/ / pt.wikipedia.org/ wiki/ Operadores_em_C_e_C% 2B% 2B http:/ / www.mspc.eng.br/ info/ cpp_oper_10.shtml

Exerccios
1. Diga a ordem de clculo e o resultado das expresses constantes abaixo: a. x = 5 * 4 / 6 + 7 ; b. x = 5 * 4.0 / 6 + 7 ; c. x = 5 * 4 % 6 + 7 ; d. x = ((4 / 2) + (3.0 * 5)) ; e. x = 3 + 2* 4% 3/ 2 1 ; f. x = 3 > = 2 && ! 2 | | 0 ; g. x = 2 && 0 | | 1 ; 2. Escreva um programa que imprima a tabela verdade da funcao ou exclusivo. 3. Escreva um programa que leia um ngulo em segundos e imprima quantos graus, minutos e segundos h neste ngulo. 4. Escreva um programa que leia um tempo em segundos e imprima quantas horas, minutos e segundos h neste tempo. 5. Escreva um programa que leia um comprimento em centmetros e imprima quantos metros, decmetros e centmetros h neste comprimento.

Operadores e Expresses: bit-a-bit e especiais


lrc , 10 April 2008 (created 31 March 2008)
no tags

Objetivos
Em C, OPERADORES e EXPRESSES podem ser classificados em cinco grande categorias: Atribuies Aritmticos Lgicos e Relacionais Bit-a-Bit Especiais Na ltima aula, disticutimos as trs primeiras categorias acima. HOJE, iremos dar prosseguimento ao estudo apresentado os OPERADORES e EXPRESSES:

28 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Bit-a-Bit Especiais Ao final, concluiremos o assunto mostrando um quadro que resume e compara os OPERADORES da linguagem C por ordem de precedncia e associatividade.

Manipulao de Bits
OPERADORES e EXPRESSES de manipulao de bits ( bit-a-bit ) referem-se a testar, atribuir ou deslocar os bits efetivos em um byte ou palavra que correspondem aos tipos bsicos char, int e variantes. OBS.: Operaes bit-a-bit no podem ser feitas sobre float, double, long double, void ou outros tipos mais complexos.

Significados: Os operadores &, | e ~ tm a mesma tabela verdade que &&, || e ! (respectivamente), com a diferena que operam sobre os bits individuais da representao de dois nmeros (ou apenas um, no caso de ~) e no sobre expresses numricas. o operador ^ tem a mesma tabela verdade que a funo xor() discutida na aula passada (novamente operando sobre bits individuais e no sobre expresses numricas). o operador >> desloca os bits de um nmero k casas para esquerda fazendo com que os k bits mais esquerda se percam e os k bits mais direita sejam '0' o operador << desloca os bits de um nmero k casas para direita fazendo com que os k bits mais direita se percam e os k bits mais esquerda sejam '0' Exemplo 1 ( << e >>): Considere:

unsigned int

x = 7;

Se pudssemos olhar a representao do valor 7 (decimal) 'dentro' da varivel x, veramos os seguinte padro de bits: x =

0...00000111 ( a quantidade total de bits depende de quantos bytes so utilizados para armazenar um unsigned int, quantidade que depende da mquina alvo e compilador ).
A EXPRESSO abaixo (deslocamento esquerda):

x = x << 2;
faz com que o padro de bits representando o valor inicial 7 se transforme em x = 0...00011100. Quer dizer, os bits, todos foram deslocados para a esquerda dois bits! Assim, o valor agora reresentado na varivel x 28 ! De maneira geral, se uma varivel tem o seguinte padro de bits: x = | bn-1 | bn-2 | ... | b2 | b1 | b0 | onde: a varivel representada por n bits cada um dos bi (para 0 i n-1 ) denota um bit com valor '0' ou '1' ento:

x << k, resulta em:


x = | bn-k-1 | bn-k-2 | ... | b2 | b1 | b0 | 0 | 0 | .. | 0 | 0 | 0 | onde a seq. final de '0's contm k '0's

29 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

x >> k, resulta em:


x = | 0 | 0 | ... | 0 | 0 | 0 | bn-1 | bn-2 | ... | bk-1 | bk | onde a seq. inicial de '0's contm k '0's

Exemplo 2 ( ~): Continuando o exemplo anterior, tem-se x = 0...00011100. A EXPRESSO abaixo ( complemento de 1 ):

x = ~ x;
tem o seguinte efeito na representao de x em binrio: x = 1...11100011 . Ou seja, os bits que so '0' passam a ser '1', os que so '1' tornam-se '0'. Exemplo 3 ( |): Continuando o exemplo anterior, tem-se x = 1...11100011. A EXPRESSO abaixo ( OR ):

x =

x | 8 ;

transforma x em : x = 1...11101011 . Quer dizer, muda o quarto bit (da direita para a esquerda) de '0' para '1'. Isto acontece por que:

x 4

= 1...11100011 = 0...00001000 -------------x | 4 = 1...11101011

/* OU bit a bit */

| frequentemente utilizado para LIGAR bits particulares

Exemplo 4 ( &): Continuando o exemplo anterior, tem-se x = 1...11101011. A EXPRESSO abaixo ( AND ):

x =

x & 0xf...f7 ;

transforma x em : x = 1...11100011 . Quer dizer, muda o quarto bit (da direita para a esquerda) de '1' para '0'. Isto acontece por que:

x 0xf...f7

= 1...11101011 = 1...11110111 -------------x | 0xf...f7 = 1...11100011

/* AND bit a bit */

& frequentemente utilizado para DESLIGAR bits particulares


Aplicaes Tpicas: rotinas de SO, drivers de dispositivos criptografia compactao de dados

Atividade 1
Tendo em vista os significados de | e & que so, respectivamente, similares aos de || e &&, descreva - atravs de um exemplo - o significado de ^ que similar funo xor() descrita na ltima aula.

Atividade 2

30 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Uma tabela binria uma tabela (matriz linhas x colunas ) onde cada clula armazena um dentre dois valores possveis. Por exemplo, a Freqncia deste curso em essncia uma tabela binria uma vez que cada clula s pode conter ou '0' (presente) ou '2' (ausente). Uma maneira simples de representar uma tabela binria atravs da seguinte estrutura:

char tabela1[40][10];
Nesta representao so gastos : 40* 10 = 400 bytes ( sizeof char = 1 byte ). Uma maneira mais eficiente (do ponto de vista da quantidade de memria utilizada) seria utilizar um mapa de bits para armazenar a tabela binria. Tal mapa de bits uma sequencia de bits mantidas pelos operadores bit a bit. Para a tabela acima de 40 linhas por 10 colunas poderamos ter a seguinte declarao:

char tabela2[ (40*10) / 8 ];


Nesta representao so gastos : (40* 10)/ 8 = 50 bytes. A idia aqui , ao invs de usar um char (1 byte) para armazenar 0 ou 1, usar um bit individual dentro de um char. Vejamos como isto pode ser feito. Atribuindo valor a uma determinada clula ( linha,coluna) Na primeira representao acima, uma dada clula pode ter seu valor modificado da seguinte maneira:

tabela1 [3][5] = 0; tabela1 [7][5] = 2;

/* aluno 3 esteve presente */ /* aluno 7 faltou */

Na segunda representao acima, o mesmo processo tem de ser simulado atravs de uma funo:

void set(unsigned x, unsigned y, int val) { unsigned pos = ( x* 10 + y ) / 8; unsigned des = ( x* 10 + y ) % 8; if (val) tabela2[pos] |= ( 1 << des ); else tabela2[pos] &= ~( 1 << des ); }

Recuperado o valor em uma determinada clula ( linha,coluna) A consultar do valor em uma dada clula feita de maneira direta para a primeira representao (utilizado ndices linha e coluna). J para a segunda representao devemos fazer uma funo de consulta.

/* retorna 0 se na pos x,y est armazenado 0 retona 1 se na pos x,y est armazenado 1 **/ int get(unsigned x, unsigned y) { ... }
Como exerccio, escreva a funo de consulta get().

Operadores Especiais
Operador Condicional ? : Operador sizeof Operadores de Converso de Tipo ou Casting (tipo) Operador Vrgula , Operadores () e []

31 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Sero vistos em mais detalhes em aulas futuras: Operadores de ponteiros * e & Operadores de estruturas . e ->

Operador Condicional
Uso

? :

EXP1 ? EXP2 : EXP3;


Significado EXP1 avaliada ... Se ela for verdadeira, ento EXP2 avaliada e se torna o valor da expresso como um todo. ... Se EXP1 for falsa, ento EXP3 avaliada e se torna o valor da expresso como um todo. Por exemplo, o comando condicional da funo set() da atividade 2 poderia ser reescrito assim:

tabela2[ pos ]

val tabela2[pos] | tabela2[pos] &

(1 << des) ~ (1 << des)

? : ;

b) Operador sizeof
Uso

sizeof sizeof

ID-VAR; (ESP-TIPO);

Significado sizeof um operador unrio em tempo de compilao que retorna o tamanho, em BYTES, de uma varivel ou de um especificador de tipo de dados, este ltimo escrito entre parnteses. Por exemplo, para tornar o cdigo da funo set() da atividade 2 mais PORTVEL, podemos fazer:

char tabela2 [ (40*10) / ((sizeof char)*8) + 1 ]; void set(unsigned x, unsigned y, int val) { unsigned pos = ( x* 10 + y ) / ((sizeof char)*8); unsigned des = ( x* 10 + y ) % ((sizeof char)*8); ... }

c) Converso Explcita de tipos (casting)


Uso

(ESPECIFICADOR-DE-TIPO) EXPRESSO;
Significado Fora - explicitamente - uma EXPRESSO a ser de um determinado tipo dado por ESPECIFICADOR-DE-TIPO. Por exemplo, para deixar claro que em:

tabela2 |= ( 1 << des);


o valor 1 se trata de um char ( 1 byte ) podemos fazer de forma explcita:

tabela2 |= (

((char) 1)

<< des );

32 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Alm de converses explcitas, o compilador realiza algumas converses implcitas ... Converses Automticas

Exemplo:

d) Operador vgula ,
Uso

EXP1, EXP2;
Significado O operador vgula usado para encadear diversas expresses. O lado esquerdo (EXP1) sempre avaliado como void. Assim, a expresso do lado direito (EXP2) torna-se o valor de toda a expresso separada por vrgula. Por exemplo:

int x,y; x = ( y = 3, y+1 );


primeiro o valor 3 atribudo a y e, em seguida, o valor 4 atribudo a x. Os parnteses so necessrios porque o operador vrgula tem a menor precedncia de todos os operadores de C.

33 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Um outro exemplo :

int i,x; for ( i = 0 , x = 1; ... } i < 10; i++ , x+=2) {

e) Operadores () e []
Parnteses () so operadores que aumentam a precedncia das operaes dentro deles. Colchetes [] realizam indexao de vetores e matrizes.

Quadro Geral de Operadores em C


A tabela 2.8 lista a precedncia de todos os operadores de C. Note que todos os operadores, exceto os operadores unrios e o ?, associam da esquerda para a direita. Os operadores unrios ( *, ! e ~) e o ternrio ? associam da direita para a esquerda.

Ordem de Avaliao
O padro C ANSI (C89) no estipula que as subexpresses de uma expresso devam ser avaliadas e uma ordem especfica. Assim, seu cdigo nunca deve contar com a ordem em que as subexpresses so avaliadas. Por exemplo, a expresso:

x =

f() + g();

no garante que f() ser chamada antes de g()!

Leituras Recomendadas
CCT captulo 2 K&R captulos 2 http:/ / pt.wikipedia.org/ wiki/ Operadores_em_C_e_C% 2B% 2B http:/ / www.mspc.eng.br/ info/ cpp_oper_10.shtml

Exerccios
1. Realize por completo a atividade 1 2. Realize por completo a atividade 2, escrevendo a funo get() e testando as funes set() e get() em um programa que l do usrio posies x e y, liga os bits nestas posies e ao final imprime a tabela completa. 3. Observe o padro abaixo:

34 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

( (0000 0001) 2 << 1 ) ( (0000 0010) 2 << 1 ) ( (0000 0100) 2 << 1 ) ( (0000 1000) 2 << 1 ) ( (0001 0000) 2 << 1 )

(0000 0010) 2 = 2 (0000 0100) 2 = 4 (0000 1000) 2 = 8 (0001 0000) 2 = 16 (0010 0000) 2 = 32

... a. desse padro, o que se pode concluir com relao operao de deslocamento esquerda? b. e com relao operao de deslocamento direita? c. em termos numricos o que significa x << k ? Quer dizer, se x vale 5 quanto ir valer x << k ? d. em termos numricos o que significa x >> k ? Quer dizer, se x vale 35 quanto ir valer x >> k ? 4. Para o programa abaixo, descreva como ele funciona e qual a sada gerada aps a sua execuo.

#include <stdio.h> int g(float a, float b) { static float f; return f += a > b ? a / b : b / a , (int) f; } int main() { printf("%i\n", g(7,2)); printf("%i\n", g(2,3)); }

Controle de Fluxo: Comandos de Seleo


lrc , 1 April 2008 (created 1 April 2008)
no tags

Objetivos
Nesta aula, iremos iniciar o estudo dos comandos e construo em C para o CONTROLE do FLUXO de EXECUO de um programa. Especificamente, abordaremos os comandos para realizao de DESVIOS CONDICIONAIS:

if ... else ... switch ... case ...


tambm conhecidos como COMANDOS DE SELEO.

Controle de Fluxo
Em C, bem como em toda linguagem moldada sob os princpios da PROGRAMAO ESTRUTURADA, o fluxo de execuo de um programa controlado de acordo com algumas idas simples e fundamentais: SEQNCIA e BLOCOS de comandos DESVIOS CONDICIONAIS INCONDICIONAIS ITERAES (LAOS)

Seqncia e Blocos de Comandos


Uma SEQNCIA de COMANDOS uma lista de COMANDOS delimitados por ; . Um BLOCO de COMANDOS qualquer SEQNCIA de COMANDOS delimitada por chaves {} .

35 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Em um BLOCO de COMANDOS, podem-se distinguir trs tipos bsicos de COMANDOS: 1. DECLARAO de VARIVEIS LOCAIS sempre no incio do BLOCO variveis declaradas dentro de um BLOCO podem ter o mesmo nome de uma outra varivel situada em um BLOCO mais externo; neste caso, a varivel dentro do BLOCO mais interno se sobrepe a varivel do BLOCO mais externo. 2. COMANDOS de EXPRESSO formados por uma expresso C vlida ATRIBUIES CHAMADAS de FUNO 3. COMANDOS de CONTROLE de FLUXO atuando sobre COMANDOS individuais ou ento outros BLOCOS de COMANDOS. DESVIOS CONDICIONAIS DESVIOS INCONDICIONAIS ITERAES

Por exemplo:

int f() { /* incio de BLOCO */ int a,b; /* DECLARAES LOCAIS */ a = 10; b = a % 3 ; /* comando de EXPRESSO /* comando de EXPRESSO */ */

if ( a > 2 ) /* comando de CONTROLE de FLUXO */ { /* incio de BLOCO */ int x,y; /* DECLARAES LOCAIS */ x = 2*a; /* comando de EXPRESSO */ for ( y =1; y < 10; y++ ) /* comando de CONTROLE de FLUXO */ x += y; /* comando de EXPRESSO */ ... } /* fim de BLOCO */ else printf("a menor que 2\n"); } /* fim de BLOCO */

/* comando de EXPRESSO */

Desvios Condicionais ( Comandos de SELEO )


Em C, h dois comandos para DESVIOS CONDICIONAIS:

if ... else switch ... case ... break ... default

O comando
Forma Geral

if ... else ...

if ( condio ) ao_se_no_zero else ao_se_zero


onde: tanto ao_se_no_zero quanto ao_se_zero podem ser: um nico comando de EXPRESSO ou um outro comando de CONTROLE de FLUXO ou um BLOCO de COMANDOS a parte else ao_se_zero opcional a condio deve ser uma EXPRESSO ESCALAR (ou seja, uma EXPRESSO que quando avaliada produza um inteiro, um

36 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

caracter ou ponto flutuante.)

Observao: em if ... else ... aninhados cada else se refere ao if mais prximo dentro do mesmo bloco.

O comando

switch ... case ... break ... default

Observaes: O comando switch s pode testar igualdade; j o comando if pode avaliar uma expresso lgica ou relacional; Duas constantes case no mesmo switch no podem ter valores idnticos; Constantes caracter so automaticamente convertidas para seus valores inteiros; Os comandos break dentro do switch so opcionais. Eles terminam a seqncia de comandos associados com cada constante. Se o comando break omitido, a execuo continua pelos prximos comandos case at que um break, ou o fim do switch, seja encontrado.

Atividade 1
Escreva um programa calculadora que leia dois nmeros double e em seguida realize uma dentre um conjunto de operaes disponveis. As operaes disponveis so: adio ( +) subtrao ( -) multiplicao ( *) diviso ( /) diviso inteira ( div) resto diviso inteira ( mod)

37 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

exponenciao inteira ( ^)

...

Leitura Recomendada
CCT captulo 3 K&R captulos 3

Exerccios
1. Complete as atividade 1 acima; 2. Extenda a atividade 1 para lidar com as operaes fat (fatorial), sen (seno), cos (coseno) e rq (raiz quadrada). Nestes casos, apenas um nmero deve ser lido.

Controle de Fluxo: Laos e Desvios I ncondicionais


lrc , 20 May 2008 (created 20 May 2008)
no tags

Laos
Em C, h trs comandos de ITERAO ou LAOS:

for while do ... while


Estes permitem que um conjunto de instrues seja executado at que ocorra uma certa condio. Esta condio pode ser pr-definida (como no lao for) ou com o final em aberto (como nos laos while e do ... while).

Lao for
FORMA GERAL

for( INICIALIZAO ;

CONDIO ; INCREMENTO )

COMANDO;

INICIALIZAO - geralmente um comando de atribuio para colocar um valor na varivel de controle do lao; CONDIO - uma expresso relacional que determina quando o lao acaba; INCREMENTO - define como a varivel de controle do lao varia cada vez que o lao repetido; COMANDO - um nico comando ou um bloco de comandos executados enquato a CONDIO verdadeira.
VARI AES 1. Operador Vgula - uma das variaes mais comuns o uso do operador vrgula para permitir que duas ou mais variveis controlem o lao:

for( x = 0 , y = 100 ; x < y ; x ++ , y -= x ) printf("x = %i, y = %i\n",x,y);

2. Lao infinito - Nenhuma das trs expresses que formam um lao for obrigatria. Assim, voc pode criar um lao infinito assim:

38 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

for ( ; ; ) printf(" Lao infinito \n");

3. Lao sem corpo - Um comando pode ser vazio. Isso significa que o corpo do lao for (ou qualquer outro lao) tambm pode ser vazio.

int pausa ( unsigned long int p) { for ( t = 0 ; t < p ; t++ ) ; }

Lao while
FORMA GERAL

while( CONDIO ) COMANDO; COMANDO executado enquanto a CONDIO for verdadeira ( diferente de zero ); quando for falsa, o controle passa para a linha aps COMANDO.
VARI AES 1. Lao infinito :

while ( 1 ) printf(" Lao infinito \n");

2. Lao sem corpo.

int pausa ( unsigned long int while ( p-- ) ; }

p) {

Lao do ... while


Ao contrrio dos laos for e while, que testam a condio do lao no comeo, o lao do ... while verifica a condio ao final do lao. Isso significa que um lao do ... while SEMPRE SER EXECUTADO AO MENOS UMA VEZ. FORMA GERAL

do

COMANDO; } while( CONDIO );

Embora as chaves no sejam necessrias quando apenas um comando est presente, elas so geralmente usadas para evitar confuso (para voc, no para o compilador) com o while. O lao do ... while repete at que a CONDIO se torne falsa.

39 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

VARI AES 1. Lao infinito :

do{ printf(" Lao infinito \n"); } while ( 1 )

2. Lao sem corpo.

int pausa ( unsigned long int do {} while ( p-- ); }

p) {

Desvios Incondicionais
return goto break continue

O comando

return

Este comando usado para retornar de uma funo. Ele um comando de desvio porque faz com que a execuo retorne (salte de volta) ao ponto em que a chamada funo foi feita. Se return tem um valor associado a ele, esse valor o valor de retorno da funo. Se nenhum valor de retorno especificado, assume-se que apenas lixo retornado (alguns compiladores iro automaticamente retornar 0 se nenhum valor for especificado, mas no conte com isso). FORMA GERAL

return

EXPRESSO;

O comando

goto

Na programao estruturada, no h nenhuma situao que necessite do goto. No entanto, o goto uma convenincia que, se usada com prudncia, pode ser uma vantagem em certas situaes. FORMA GERAL

goto ...

RTULO;

RTULO:

O comando goto requer um RTULO - um identificador vlido seguido por dois-pontos). O RTULO tem de estar na mesma funo do goto que o usa no permitido desvios entre funes.

O RTULO pode vir antes, e no apenas depois, do comando goto.

40 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

lao infinito

LOOP: printf("lao infinito\n"); goto LOOP;

O comando

break

O comando break tem dois usos. Voc pode us-lo para terminar um case em um comando switch (vide aula Controle de Fluxo: Comandos de Seleo). Voc pode tambm utiliz-lo para forar uma terminao imediata de um lao, evitando o teste condicional normal do lao. Quando o comando break encontrado dentro de um lao, o lao imediatamente terminado e o controle do programa retorna ao comando seguinte ao lao.

O comando

continue

O comando continue trabalha de uma forma pouco parecida com a do comando break. Porm, em vez de forar a terminao, continue fora que ocorra a prxima iterao do lao, pulando qualquer cdigo intermedirio. Para o lao for, o comando continue faz com que o incremento e o teste condicional sejam executados. Para os laos while e do ... while, o controle do programa passa para o teste condicional.

int conta_espacos(const char * str) { int i = 0, nesp = 0; while ( str[i] ) { if ( str[i] != ' ' ) continue; nesp ++; } return nesp; }

Leitura Recomendada
CCT captulo 3 K&R captulos 3

Funes: definio, declarao e chamada


lrc , 23 June 2008 (created 20 May 2008)
no tags

41 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Funes
Em C, um programa uma coleo de FUNES. Uma funo um bloco de cdigo que recebe um nome e que tem possivelmente PARMETROS. A partir do nome, o bloco de cdigo que forma a funo pode ser chamado. CHAMAR uma funo significa iniciar a execuo de um bloco de cdigo. Caso a funo possua parmetros, durante a CHAMADA dela devem ser indicados ARGUMENTOS que so valores ou variveis que iro corresponder aos parmetros da funo. Ao final da execuo, uma funo pode ainda retornar um valor para o cdigo que fez a chamada da funo.

Definio de Funo: Forma Geral


Uma funo deve ser definida conforme o esquema abaixo:

ESPEC-DECLARAO ID( DECL-ID-1, ..., DECL-ID-n ) CORPO_FUNO }

ID define o nome da funo. A lista de declaraes DECL-ID-1, ..., DECL-ID-n dita LISTA de PARMETROS da funo. Cada ID-i consiste em uma varivel com escopo local na funo e que ir receber, como valor inicial, o valor passado
como ARGUMENTO durante a chamada da funo. Se pensarmos no ID de uma funo como uma VARIVEL GLOBAL, os ESPEC-DECLARAO definem que caractersticas tem este ID: O tipo de dados ( void, int, char *, ... ) Classe de armazenamento ( static ou extern ) O tipo de acesso ( const ou volatile )

O CORPO_FUNO consiste em DECLARAES de VARIVEIS com escopo LOCAL seguidas de COMANDOS. Caso o tipo de dados constante nos ESPEC-DECLARAO seja diferente de void, deve haver ao menos um comando return ...; no CORPO_FUNO.

Definio de Funo: Formato Antigo


Por questes de compatibilidade, uma funo pode ainda ser definida seguindo o formato originalmente proposto pelos projetistas da linguagem. Neste formato original, o que muda a forma de se especificar os parmetros da funo:

ESPEC-DECLARAO ID( ID-1,...,ID-n ) DECL-ID-1; ...; DECL-ID-n; { CORPO_FUNO }

Declarao de Funes: Prottipos


O ideal que toda funo, antes de ser usada, deve ser declarada. Caso a funo encontra-se DEFINIDA no mesmo arquivo e em uma posio antes de seu uso, ento a prpria DEFINIO da funo serve como DECLARAO da funo. Caso contrrio, a DECLARAO da funo dever ser feita atravs de PROTTIPOS. Um prottipo como se fosse um CABEALHO para a funo, ou seja, o ID da funo os ESPEC do tipo retornado pelo funo e os ESPEC dos tipos de cada parmetro da funo:

ESPEC-DECLARAO

ID( ESPEC-DECL-1, ..., ESPEC-DECL-n );

Em uma situao onde uma funo f esteja sendo usada sem ter sido antes declarada, ento implicitamente o compilador declarada a funo como sendo:

42 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

int

f();

Um funo f() diferente de f(void) !


Um funo declarada como

int

f();

diferente de uma funo declarada como

int

f(void);

No primeiro caso, o compilador no sabe se a funo pode ou no receber argumentos durante a sua chamada. Quer dizer, perfeitamente vlido fazer:

int x = f(3.14); int y = f(2.7, 4); int z = f();

No segundo caso, o compilador informado explicitamente que a funo no deve receber nenhumar argumento. Assim, as duas primeiras linhas do cdigo acima gerariam uma mensagem de erro e apenas a ltima seria considerada como vlida.

Lista de Parmetros Varivel


Quando se quer especificar uma funo que possui uma lista de parmetros varivel em nmero e tipo, deve-se terminar a declarao dos parmetros utilizando trs pontos ... Por exemplo:

void f(int a, char * b, ... );

Qualquer funo que use um nmero varivel de parmetros deve ter ao menos um deles explicitamente declarado.

va_arg(), va_start() e va_end()

43 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Chamada de Funo
Chamar uma funo significa iniciar a execuo de seu corpo de cdigo. Caso a funo tenha sido declarada com PARAMETROS, durante a chamada deve ser passados ARGUMENTOS que correspondam em nmero e tipo com os PARAMETROS da funo. PARAMETROS so variveis locais funo que iro receber como valores iniciais os valores dos ARGUMENTOS utilizados na CHAMADA da funo.

OBS.: Em C, as chamadas de funo so feitas por VALOR. No entanto, o conceitos de chamada por referncia pode ser simulado em C atravs do uso de apontadores. Exemplo: CHAMADA por VALOR

44 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

unsigned modulo(int x) { x = x < 0 ? - x : x ; return x; } int main () { int a = - 2, ma = modulo(a); printf("| %d | = %d\n", }
Ao executar o programa acima, vc. ir perceber que o valor da varivel a no modificado pela funo mdulo. Ou seja, a varivel a e usada como ARGUMENTO em uma CHAMADA por VALOR de modulo(). Exemplo: simulando CHAMADA por REFERNCIA

a, ma);

unsigned modulo(int * x) { *x = *x < 0 ? - *x : *x ; return *x; } int main () { int a = - 2, ma = a; modulo(&ma); printf("| %d | = %d\n", a, ma); }

Chamadas de Funes com ARRANJOS


O ID de vetores, matrizes e strings so conceitualmente apontadores para o primeiro elemento do arranjo. Assim, ao se usar o nome de vetores, matrizes ou strings em uma chamada de funo est-se fazendo uma CHAMADA por REFERNCIA. Em outras palavras, vetores, matrizes ou strings quando passados como argumentos de funes e manipulados no interior dessas funes tm os seus valores modificados ao trmino da funo (vide tambm: Matrizes e Parmetros de Funes ). Para evitar que modificaes acidentais ocorram com vetores, matrizes e strings passados como argumentos de funes deve-se declar-los utilizando o qualificador const. Exemplos:

45 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* *str no deve ser modificado no interior de strlen */ int strlen(const char str[]) { int i; /* str[0] = 'a'; - qualquer tentativa de modificar o contedo da string apontada por str ir gerar uma mensagem de erro ! */

for(i =0; return i; } /* */

*str; i++, str++);

*str1 deve ser modificada no interior de strlen j, *str2 no

int strcpy(char * str1, const char * str2) { int i = 0; /* str2[0] = 'a'; - qualquer tentativa de modificar o contedo da string apontada por str2 ir gerar uma mensagem de erro ! */

do str1[i] = str2[i]; while ( str2[i++] ); return i - 1; }

Leituras Recomendadas
CCT cap 6 K&R

Exerccios
Obs.: Nos exerccios abaixo, escolha cinco e para estes mostre como as funes ficam quando definidas utilizando o formato antigo de definio de funes.

1. Em C, qual a diferena entre DECLARAO e DEFINIO de funes? 2. O que significam: a. passagem de argumentos por valor? b. passagem de argumentos por referncia? 3. Escreva uma funo que recebe um nmero inteiro n> 0 e devolve o nmero de dgitos de n e o primeiro dgito de n. 4. Escreva uma funo que recebe como parmetro um inteiro positivo ano e devolve 1 se ano for bissexto, 0 em caso contrrio. (Um ano bissexto se (ano % 4 = = 0 && (ano % 100 != 0 | | ano % 400 = = 0)).) 5. Escreva uma funo que tem como parmetros de entrada e sada trs nmeros inteiros, dia, mes e ano, representando uma data, e modifica esses inteiros de forma que eles representem o dia seguinte. 6. Escreva um programa que leia um inteiro positivo n e uma seqncia de n datas e imprime, para cada data, o dia seguinte. 7. Escreva uma funo de cabealho int divide (int *m, int *n, int d) que recebe trs inteiros positivos como parmetros e devolve 1 se d divide pelo menos um entre * m e * n, 0 caso contrrio. Fora isso, se d divide * m, divide * m por d, e o mesmo para o * n. 8. Escreva um programa que l dois inteiros positivos m e n e calcula, usando a funo acima, o mnimo mltiplo comum entre m e n, ou seja, mmc(m,n). 9. Escreva uma funo com prottipo void somabit (int b1, int b2, int *vaium, int *soma); que recebe trs bits (inteiros entre 0 e 1) b1, b2 e * vaium e devolve um bit soma representando a soma dos trs e o novo um bit "vai-um" em * vaium. 10. Escreva um programa que leia dois nmeros em binrio e calcula um nmero em binrio que a soma dos dois nmeros

46 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

dados. Utilize a funo acima. 11. Escreva uma funo com o prottipo void converte (char ch, int *tipo, char *valor); que recebe um caractere ch e devolve em * tipo 0, se o caractere for um nmero inteiro, 1 se for uma letra (maiscula ou minscula) e 2 caso contrrio; e alm disso, no caso de ser uma letra, converte para maiscula, seno devolve ch inalterado. Escreva um programa que leia uma seqncia de n caracteres e imprima a seqncia convertida para maiscula, eliminando os caracteres que no forem letras ou nmeros. Escreva uma funo que l, linha a linha, uma matriz real Amxn Escreva uma funo que imprime uma matriz real Amxn Escreva uma funo que calcula a soma dos elementos da linha i de uma matriz real Amxn. Escreva uma funo que calcula o produto dos elementos da coluna j de uma matriz real Amxn. Escreva uma funo que troca o contedo de duas variveis. Escreva uma funo que recebe dois inteiros, i e j, uma matriz real Amxne troca linha i pela linha j. Utilize a funo do item anterior. Um conjunto pode ser representado por um vetor da seguinte forma: V[ 0] o tamanho do conjunto; V[ 1] , V[ 2] , etc. so os elementos do conjunto (sem repeties). a. Faa uma funo chamada interseco que dados dois conjuntos de nmeros inteiros A e B, constri um terceiro conjunto C que a interseco de A e B. Lembre-se de que em C[ 0] a sua funo deve colocar o tamanho da interseco. b. Faa um programa que l um inteiro n > 1 e uma seqncia de n conjuntos de nmeros inteiros (cada um com no mximo 100 elementos) e constri e imprime um vetor INTER que representa a interseco dos n conjuntos. Por exemplo, se n= 3 e os conjuntos so { 1, 2, 4, 9} , { 2, 4, 7, 8, 9} e { 5, 4, 9} , a entrada ser:

12. 13. 14. 15. 16. 17. 18. 19.

O valor de n

4 V[0] = tamanho do primeiro conjunto 1 2 4 9 V[1] V[2] V[3] V[4] 5 V[0] = tamanho do segundo conjunto 2 4 7 8 9 V[1] V[2] V[3] V[4] V[5] 3 5 4 9 V[0] = tamanho do terceiro conjunto V[1] V[2] V[3]
E o vetor INTER construdo ser

INTER[0] = 2 INTER[1] = 4

tamanho do conjunto INTER[2] = 9 conjunto interseco

NOTE que no preciso ler todos os conjuntos de uma s vez. Voc pode ler os dois primeiros conjuntos e calcular a primeira interseco. Depois, leia o prximo conjunto e calcule uma nova inteseco entre esse conjunto lido e o conjunto da interseco anterior, e assim por diante. Use obrigatoriamente a funo do item anterior, mesmo que voc no a tenha feito.

Funes: main( ) e recurso


lrc , 20 May 2008 (created 20 May 2008)
no tags

A funo main()
O que main() devolve?
De acordo com o padro ANSI, a funo main() devolve um inteiro para o processo chamador, que , geralmente, o sistema operacional. Devolver um valor em main() equivalente a chamar exit() com o mesmo valor. Se main() no devolve explicitamente um valor, o valor passado para o processo chamador tecnicamente indefinido. Na prtica, a maioria dos compiladores C devolve 0, mas no conte sempre com isso! Pode-se tambm declarar main() como void. Alguns compiladores geram uma ADVERTENCIA, se a funo no declarada como void e tambm no devolve um valor.

47 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

argc e argv - argumentos para main()

int main ( int argc, char * argv[] ) { for( ; argc -- ; ) printf("arg[%d] = %s\n", argc, argv[argc]); }

Recurso
Em C, como virtualmente em todo linguagem de programao, funes podem chamar a si mesmas, direta ou indiretamente. Uma funo dita recursiva se em seu corpo a uma chamada (direta ou indireta) para si mesma. Recurso o processo de definir algo em termos de si mesmo e , algumas vezes, chamado de definio circular. Exemplos:

48 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdlib.h> #include <string.h> char * gnu(int n) { static char buf[1024]; if (n == 0) strcpy(buf,"GNU"); else { gnu(n-1); strcat(buf," Not Unix"); } return buf; } char * gnu2(int n) { static char buf[1024]; if (n == 0) return "GNU"; else { char aux[1024]; strcpy(aux,gnu2(n-1)); sprintf(buf,"(%s %s)",aux,"Not Unix"); } return buf; } int main(int argc, char * argv[]) { printf("%s\n", gnu(atoi(argv[1])) ); printf("%s\n", gnu2(atoi(argv[1])) ); }

OBSERVAES: Quando uma funo chama a si mesma, novos parmetros e variveis locais - quando estas no so static - so alocados na pilha e o cdigo da funo executado com essas novas variveis. No caso de variveis locais static, todas as chamadas recursivas compartilham a mesma varivel ! Quando cada chamada recursiva retorna, as variveis locais (no static) e os parmetros so removidos da pilha e a execuo recomea do ponto da chamada funo dentro da funo.

Ao escrever funes recursivas, voc deve ter um comando if em algum lugar para forar a funo a retornar sem que a chamada recursiva seja executada mais uma vez !

Atividade 1 - Torres de HANOI


Em 1883, o matematico francesEdouard Lucas inventou o famoso quebra-cabea das Torres de Hanoi, tambem conhecido por Torres de Brahma e contado em forma de lenda:

"No grande templo de Brahma em Benares, numa bandeja de metal sob a cpula que marca o centro do mundo,

49 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

trs agulhas de diamante servem de pilar a sessenta e quatro discos de ouro puro. Incansavelmente, os sacerdotes transferem os discos, um de cada vez, de agulha para agulha, obedecendo sempre lei imutvel de Brahma: Nenhum disco se podera sobrepor a um menor. No in cio do mundo todos os sessenta e quatro discos de ouro, foram dispostos na primeira das trs agulhas, constituindo a Torre de Brahma. No momento em que o menor dos discos for colocado de tal modo que se forme uma vez mais a Torre de Brahma numa agulha diferente da inicial, tanto a torre como o templo sero transformados em p e o ribombar de um trovo assinalara o fim do mundo." [ http:/ / www2.mat.ua.pt/ rosalia/ cadeiras/ ADA/ THpaper.pdf]

Escreva um programa em C, que simule o trabalho dos sacerdotes conforme descrito acima! Na lenda, os sacerdotes movem 64 discos. No seu programa, trabalhe com n discos, onde n um nmero informado pelo usurio. Dica: usando recurso, o seu programa ficar bastante compacto.

int main(int c, char * v[]) { /* assuma que atoi(v[1]) o nmero n de discos a ser movido de um pilar para outro }

Atividade 2 - Combinaes
Quantos times de futebol diferentes podem ser feitos com uma turma de 26 alunos?! No segundo grau, voc DEVE ter aprendido que esta questo pode ser resolvida utilizando a frmula mgica de COMBINAES:

Sendo n= 26 e k= 11

26! / [11! (26 - 11)!] = 26*25*24*23*22*21*20*19*18*17*16 / 11*10*9*8*7*6*5*4*3*2*1 = 308403583488000/ 39916800 = 7726160

Bom, se voc for escrever um programa em C para calcular combinaes de n tomados k a k e utilizar a definio acima voc poder ter srios problemas de overflow! Repare que o nmero 308403583488000 quando escrito em binrio fica:

10

0011 000

0111 1101

1100 1110

0000 1010

1001 0000

0000 0000

Isto indica que so necessrio 7 bytes no mnimo para armazen-lo na memria do computador. Por outro lado, se observarmos o resultado final 7726160 que em binrio

111 0101

1110 0100

0101 0000

vemos que ele ocupa apenas 3 bytes! Em resumo, usando inteiros de 4bytes podemos armazenar o resultado final mas no poderemos armazenar resultados intermedirios como os acima apresentados! O que fazer? Vamos pensar um pouco: queremos formar times de 11 num universo de 26 alunos. Do ponto de vista de um aluno particular, os times a serem formados podem ser divididos em duas classes: os times nos quais o aluno participa e os times nos quais ele no participa. Os times nos quais um particular aluno participa so em nmero de COMB( 25, 10 ). Ou seja, o referido aluno mais dez dentre os 25 restantes. J os times nos quais o aluno no participa so em nmero de COMB( 25, 11 ). Ou seja, o aluno est excludo e so formados times de 11 dentre os 25 restantes. Este raciocnio pode ser repetido recursivamente agora para COMB( 25, 10 ) e COMB( 25, 11 ). O resultado final o seguinte padro recursivo:

50 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Agora, partindo da frmula acima podemos escrever um programa recursivo que calcular combinaes sem os problemas de overflow indicados acima quando usamos a definio tradicional de combinaes. Tal programa poderia usar a funo abaixo:

int comb(int n, int k) { if ( k > n ) return 0; if ( k == 0 || k == n ) return 1; else return comb(n-1,k-1) + comb(n-1,k); }

Resolvemos um problema mas tambm criamos um outro: o de tempo de execuo. Faa um teste. Tente calcular comb(36,11) usando a funo acima. Observe quanto tempo vai demorar para obter o resultado! O que fazer ento?! Na raiz do problema est o fato de que a funo recursiva proposta faz inumeras vezes o mesmo trabalho. Por exemplo: COMB(36,11) depende de COMB(35,10) e COMB(35,11). J COMB(35,11) depende de COMB(34,10) e COMB(34, 11); e, COMB(35,10) depende de COMB(34,9) e COMB(34,10). Observe que esta ltima combinao - COMB(34,10) - aparece em dois ramos distintos de recurso e por isso ir ser calculado duas vezes! Uma soluo para evitar este trabalho todo criar uma tabela para registrar clculos j feitos:

int comb(int n, int k) { static int tab[50][50]; if ( k > n ) return 0; if ( tab[n][k] == 0 ) { if ( k == 0 || k == n ) tab[n][k] = 1; else tab[n][k] = comb(n-1,k-1) + comb(n-1,k); } return tab[n][k]; }

Teste as funes apresentadas acima e verifique se realmente as idias discutidas fazem sentido.

Leitura Recomendada
CCT captulo 6

Exerccios
1. Complete a atividade 1 2. Na atividade 1, se cada disco pode ser movido de um lugar para outro em 1 nanosegundo (= 10-9 seg.), quanto tempo os monges iro levar para mover os 64 disco de uma torre para a outra?

51 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

3. Complete a atividade 2 4. Na atividade 2, qual os maiores k e n tais que comb(n,k) no estoure a representao baseada em int de 4 bytes? 5. Defina uma funo recursiva para determinar o maior divisor comum entre dois nmeros naturais x e y, baseando-se nas regras abaixo. Em seguida, napresente uma verso iterativa do algoritmo capaz de realizar a mesma tarefa. mdc(x,y) = x, se x = y mdc(x,y) = mdc(y,x), se x < y mdc(x.y) = mdc(x-y,y), se x > y 6. Escreva uma funo recursiva void fibo(int n); que gere os n primeiros termos da srie de Fibonacci. 7. Faa de conta que na linguagem C no existem operadores para adio, subtrao, multiplicao e nem diviso. Imagine que existam apenas os operadores de incremento ++N e decremento --N. Usando como base apenas estes dois operadores- ++ e -- (quer dizer, voc no deve usar os operadores +, -, * e /) -, defina funes recursivas para:

int int int int

soma(int subt(int mult(int divi(int

x,int x,int x,int x,int

y); - retorna soma x mais y; y); - retorna subtrao x menos y; y); - retorna multiplicao x vezes y; y); - retorna diviso inteira x dividido por y;

8. Defina uma rotina recursiva para, dado um natural n, imprimi-lo em base binria.

Vetores, matrizes e strings


lrc , 20 May 2008 (created 20 May 2008)
no tags

Introduo
Um ARRANJO ( VETOR, MATRIZ ou STRING) uma coleo de variveis do mesmo tipo que referenciada por um nome comum. Um elemento especfico em um ARRANJO acessado por meio de um NDICE. VETORES e STRINGS so ARRANJOS unidimensionais. Isto , necessita-se apenas um NDICE para acessar um elemento. MATRIZES so ARRANJOS multidimensionais. Ou seja, dois ou mais NDICES so necessrios para acessar um elemento de uma MATRIZ. Em C, ARRAJOS so armazenados em posies de memria contguas. O endereo mais baixo corresponde ao primeiro elemento e mais alto, ao ltimo elemento.

VETORES
Declarao ESPECIFICADORES ID[ TAMANHO ] = { LISTA_INICIALIZADORES } ; Onde os elementos em vermelho so opcionais. Obs.: indices comeam em 0 e vo at TAMANHO - 1 ID[ 0] - primeiro elemento ID[ 1] - segundo elemento ... ID[ TAMANHO - 1] - ultimo elemento no h verificao automtica se o acesso aos elementos ocorre dentro da faixa 0 .. TAMANHO -1; o programador tem de tomar esta tarefa para si!

MATRIZES
Declarao ESPECIFICADORES ID[ TAMANHO1 ] [ TAMANHO2] ... [ TAMANHOn] = { LISTA_INICIALIZADORES } ; Onde os elementos em vermelho so opcionais. Obs.: os indices de cada dimenso i comeam em 0 e vo at TAMANHOi - 1 ID[ 0] [ 0] ...[ 0] - primeiro elemento ...

52 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

ID[ TAMANHO1 - 1] [ TAMANHO2 - 1] ... [ TAMANHOn -1] - ultimo elemento no h verificao automtica se o acesso aos elementos ocorre dentro da faixa 0 .. TAMANHOi -1; o programador tem de tomar esta tarefa para si!

STRINGS
Em C, strings so VETORES de caracteres terminadas pelo caracter '\ 0' (NULO). Declarao ESPECIFICADORES ID[ TAMANHO ] = { LISTA_INICIALIZADORES } ; ou ESPECIFICADORES ID[ TAMANHO ] = CONST_STRING;

Onde os elementos em vermelho so opcionais.

Obs.: Para armazenar um string com n caracteres no nulos voc deve reservar n+ 1 posies. Uma a mais para o caracter '\ 0' !

#include <string.h>

Leitura Recomendada
CCT cap4

Exerccios
1. Escreva um programa que leia uma linha de at 80 caracteres do teclado e imprima quantos caracteres foram lidos. 2. Escreva um programa que leia uma linha de caracteres do teclado e imprima quantas vezes um caracter, tambm fornecido pelo teclado, aparece nesta linha. O programa tambm deve imprimir em que posies o caracter foi encontrado. 3. Escreva um programa que leia uma linha do teclado e em seguida um par de caracteres. O programa deve procurar este par na linha e imprimir em que posies o par foi encontrado.

53 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

4. Escreva um programa que leia uma linha do teclado e imprima todas as vogais encontradas no texto e o total de vezes que elas aparecem. Obs: Tamanho maximo da linha deve ser 40 caracteres. 5. Oimperador romano Cesar usava um sistema simples para codificar as mensagens que enviava aos seus generais. Neste sistema cada letra era substituda por trs letras a frente no alfabeto. A sua misso mais simples ainda, escrever um programa que converta cada letra, e somente as letras, de uma mensagem de at 80 caracteres para a letra imediatamente posterior. Note que a letra 'z' deve ser convertida para a letra 'a', e a letra 'Z' para 'A'. 6. Escreva um programa que leia uma frase de 80 caracteres e a imprime retirando os espaos em branco. 7. Escreva um programa que leia uma linha do teclado de tamanho 80 caracteres. A linha somente contm letras. Divida a linha em blocos de 5 letras. Dentro de cada bloco o seu programa deve trocar a primeira letra pela seguinte, a segunda letra por duas letras adiante, a terceira por trs letras e assim at a quinta. Os espaos em branco devem ser retirados da frase. Considere o seguinte exemplo. Frase lida: EVA VIU A UVA Retirada dos espaos em branco: EVAVIUAUVA Diviso em blocos de 5 (Espaos em branco mostrados para facilitar entendimento): EVAVI UAUVA Criptografia: FYDAN VCYAF O que ser impresso: FYDANVCYAF 8. Escreva um programa que leia uma matriz de 3x3 que contm somente caracteres 0 e X e procure linhas que contenham somente um dos dois caracteres. O caracter a ser procurado deve ser lido do teclado. 9. Escreva um programa que leia uma linha de caracteres do teclado e converta o primeiro caracter de cada palavra para maisculas. Assuma que as palavras so sempre separadas por um branco. 10. Escreva um programa que leia para um vetor um conjunto de nmeros inteiros. Assuma que o conjunto de nmeros lidos menor que o tamanho do vetor. O programa deve inserir no vetor em uma posio especificada pelo usurio um nmero lido do teclado. Assuma que a posio especificada pelo usurio corresponde ao ndice do vetor. 11. Faa um programa que inverta uma string. O programa deve ler a string com gets e armazen-la invertida em outra string. Use o comando for para varrer a string at o seu final. 12. Faa um programa que leia duas matrizes 3x3 e imprima seu produto. 13. Escreva um programa que leia um conjunto de nomes para uma matriz e imprima estes nomes em ordem alfabtica. Assuma que os nomes sero lidos somente em letras maisculas. Assuma tambm que os nomes tm no mximo 40 caracteres e sero lidos 10 nomes ao todo.

Ponteiros
lrc , 20 May 2008 (created 20 May 2008)
no tags

Conceito
Um PONTEIRO ou APONTADOR uma varivel usada para armazenar um endereo de memria. Normalmente, o endereo armazenado em um PONTEIRO a posio de uma outra varivel na memria. Se uma varivel contm o endereo e uma outra, ento a primeira varivel dita apontar para a segunda.

Declarao
De maneira geral, uma varivel ponteiro de nome ID declarada assim:

54 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

ESPECIFICADORES

ID = INICIALIZADOR;

onde, o = INICIALIZADOR opcional (como em toda declarao de varivel).

Operadores de Ponteiros
Existem dois operadores especiais para ponteiros: o * e o &.

Operador &
Um operador unrio que devolve o endereo na memria do seu operando.

int int * p = &m; ...

m; p; /* p recebe o endereo onde se localiza a var. m */

Operador *
o complemento de &. Quer dizer, devolve a varivel localizada no endereo armazenado em um apontador.

p = &m; m = 3; printf("%p", p); printf("%d", *p); ... /* imprime o endereo de m */ /* imprime 3 que o contedo de m */

Ponteiros e Arranjos
H uma estreita relao entre PONTEIROS e ARRANJOS (vetores, matrizes e strings). O nome de um ARRANJO (vetor, matriz ou string) sempre um PONTEIRO para o primeiro elemento do ARRANJO.

char str[80], pstr = str;

*pstr; /* pstr aponta para str[0] */

Assim, a dcima posio de um ARRANJO (vetor, matriz ou string) pode ser acessada de duas maneiras:

pstr = str;

/* pstr aponta para str[0] */ /* imprime o 10o elemento de str */ /* imprime o 10o elemento de str */

printf("%c", str[9] ); printf("%c",*(pstr + 9));

Aritmtica de Ponteiros
Existem apenas duas operaes aritmticas que podem ser usadas com ponteiros: adio e subtrao. Cada vez que um ponteiro incrementado, ele aponta para a posio de memria do prximo elementodo seu tipo base. Cada vez que um ponteiro decrementado, ele aponta para a posio de memria do elemento anterior.

55 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Aplicaes
O correto entendimento e uso de ponteiros crtico para uma programao bem-sucedida em C. H pelo menos trs razes para isto: ponteiros fornecem os meios pelos quais as funes podem modificar seus argumentos formam a base para a alocao dinmica (variveis no heap) aumenta a eficincia de certas rotinas

De agora em diante, at o final do curso, iremos explorar em variados graus de detalhes o conceito bsico de ponteiros.

Atividade 1
Aplicando os conhecimentos adquiridos na ltima aula e nesta, iremos agora implementar uma primeira verso de uma lista de strings. Dado o cdigo abaixo (que pode ser obtido como projeto Dev-Cpp neste link), complemente o cdigo do arquivo lista.c escrevendo as funes:

list_rem() list_get() list_set()

main.c

56 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* main.c **/ #include #include #include #include <stdio.h> <stdlib.h> "list.h" "xcpt.h"

int main(int argc, char *argv[]) { while (1) { char str[1024]; int pos; const char * xc; printf("\nAdicionar\n"); printf(" printf(" pos = "); scanf("%d",&pos); str = "); gets(str); gets(str);

list_add(str,pos); /* TRY(list_add(str,pos)); CATCH(INDEX_OUT_OF_BOUNDS_XCPT,xc) printf("\npos invalida!\n"); CATCH(LIST_FULL_XCPT,xc) printf("\nlista cheia!\n"); CATCH(LINE_TOO_LONG_XCPT,xc) printf("\nstr muito grande!\n"); */ printf("\nLista\n"); list_print(); } }

list.h, list.c

57 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #ifndef LIST_H #define LIST_H #define LIST_MAX_SIZE #define LINE_MAX_SIZE 99 60

#define LIST_FULL_XCPT "list full" #define LINE_TOO_LONG_XCPT "line too long" unsigned short list_size(void); void char * void char * void #endif list_add(const char * str, unsigned short pos); list_rem(unsigned short pos); list_set(const char * str, unsigned short pos); list_get(unsigned short pos); list_print(void);

58 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #include #include #include #include #include <stdlib.h> <stdio.h> <string.h> "list.h" "xcpt.h"

/** private data */ static char list[LIST_MAX_SIZE][LINE_MAX_SIZE+1]; static unsigned short size = 0; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];

/** public functions */ unsigned short list_size(void) { return size; } /* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT LIST_FULL_XCPT LINE_TOO_LONG_XCPT **/ void when pos is invalid ( > size +1 ) when the list size equals LIST_MAX_SIZE when str is greater than LINE_MAX_SIZE

list_add(const char * str, unsigned short pos) { sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n", __FILE__,__LINE__,str,pos); if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } if ( size + 1 > LIST_MAX_SIZE ) { THROW(LIST_FULL_XCPT,xcpt_cmsg); return ; } if ( strlen(str) > LINE_MAX_SIZE ) { THROW(LINE_TOO_LONG_XCPT,xcpt_cmsg); } if ( pos == 0 ) { strncpy(list[size],str,LINE_MAX_SIZE); } else { int i; for ( i = size ; i >= pos; i-- ) strcpy(list[i],list[i-1]);

59 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

xcpt.h, xcpt.c

/* xcpt.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #ifndef XCPT_H #define XCPT_H #define XCPT_NAME_MAX_SIZE #define XCPT_CMSG_MAX_SIZE #define THROW(e,m) #define TRY(f) #define CATCH(e,m) #define #define #define #define #define 32 1024

__throw((e),(m)) __begin_try();f;__end_try(); if(m=__catch(e)) "null pointer" "index out of bounds" "overflow" "underflow" "illegal argument"

NULL_POINTER_XCPT INDEX_OUT_OF_BOUNDS_XCPT OVERFLOW_XCPT UNDERFLOW_XCPT ILLEGAL_ARGUMENT_XCPT

void void const char * void #endif

__begin_try(void); __end_try(void); __catch(const char *name); __throw(const char *name, const char *cmsg);

60 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* xcpt.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "xcpt.h"

static char xcpt_name[XCPT_NAME_MAX_SIZE + 1]; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE + 1]; static int trying; /* Sets try_flag. **/ void __begin_try(void) { trying = 1; } /* UnSets try_flag. **/ void __end_try(void){ trying = 0; } /* From exception name, gets the exception message thown by __throw(n,m). Once cautch, the exception name is cleared . **/ const char * __catch(const char * name) { if ( strcmp(xcpt_name,name) == 0 ) { xcpt_name[0] = '\0'; return xcpt_cmsg; } else return NULL; } /* Stores an exception contextual message. When called outside a __begin_try(); ...; __end_try(); pair, the exception message is also printed to the stderr stream . **/ void __throw(const char * name,const char * cmsg) { strncpy(xcpt_name,name,XCPT_NAME_MAX_SIZE); strncpy(xcpt_cmsg,cmsg,XCPT_CMSG_MAX_SIZE); if ( !trying ) fprintf(stderr,"exception: %s: %s\n",xcpt_name,xcpt_cmsg); }

61 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Leitura recomendada
CCT Cap 5

Exerccios
1. Termine a atividade 1 acima, escrevendo as funes:

list_rem() list_get() list_set()

Exemplo: Lista de Strings


lrc , 20 May 2008 (created 20 May 2008) Dado o cdigo abaixo (que pode ser obtido como projeto Dev-Cpp neste link), complemente o cdigo do arquivo lista.c escrevendo as funes:
no tags

list_rem() list_get() list_set()

main.c

62 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* main.c **/ #include #include #include #include <stdio.h> <stdlib.h> "list.h" "xcpt.h"

int main(int argc, char *argv[]) { while (1) { char str[1024]; int pos; const char * xc; printf("\nAdicionar\n"); printf(" printf(" pos = "); scanf("%d",&pos); str = "); gets(str); gets(str);

list_add(str,pos); /* TRY(list_add(str,pos)); CATCH(INDEX_OUT_OF_BOUNDS_XCPT,xc) printf("\npos invalida!\n"); CATCH(LIST_FULL_XCPT,xc) printf("\nlista cheia!\n"); CATCH(LINE_TOO_LONG_XCPT,xc) printf("\nstr muito grande!\n"); */ printf("\nLista\n"); list_print(); } }

list.h, list.c

63 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #ifndef LIST_H #define LIST_H #define LIST_MAX_SIZE #define LINE_MAX_SIZE 99 60

#define LIST_FULL_XCPT "list full" #define LINE_TOO_LONG_XCPT "line too long" unsigned short list_size(void); void char * void char * void #endif list_add(const char * str, unsigned short pos); list_rem(unsigned short pos); list_set(const char * str, unsigned short pos); list_get(unsigned short pos); list_print(void);

64 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #include #include #include #include #include <stdlib.h> <stdio.h> <string.h> "list.h" "xcpt.h"

/** private data */ static char list[LIST_MAX_SIZE][LINE_MAX_SIZE+1]; static unsigned short size = 0; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];

/** public functions */ unsigned short list_size(void) { return size; } /* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT LIST_FULL_XCPT LINE_TOO_LONG_XCPT **/ void when pos is invalid ( > size +1 ) when the list size equals LIST_MAX_SIZE when str is greater than LINE_MAX_SIZE

list_add(const char * str, unsigned short pos) { sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n", __FILE__,__LINE__,str,pos); if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } if ( size + 1 > LIST_MAX_SIZE ) { THROW(LIST_FULL_XCPT,xcpt_cmsg); return ; } if ( strlen(str) > LINE_MAX_SIZE ) { THROW(LINE_TOO_LONG_XCPT,xcpt_cmsg); } if ( pos == 0 ) { strncpy(list[size],str,LINE_MAX_SIZE); } else { int i; for ( i = size ; i >= pos; i-- ) strcpy(list[i],list[i-1]);

65 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

xcpt.h, xcpt.c

/* xcpt.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #ifndef XCPT_H #define XCPT_H #define XCPT_NAME_MAX_SIZE #define XCPT_CMSG_MAX_SIZE #define THROW(e,m) #define TRY(f) #define CATCH(e,m) #define #define #define #define #define 32 1024

__throw((e),(m)) __begin_try();f;__end_try(); if(m=__catch(e)) "null pointer" "index out of bounds" "overflow" "underflow" "illegal argument"

NULL_POINTER_XCPT INDEX_OUT_OF_BOUNDS_XCPT OVERFLOW_XCPT UNDERFLOW_XCPT ILLEGAL_ARGUMENT_XCPT

void void const char * void #endif

__begin_try(void); __end_try(void); __catch(const char *name); __throw(const char *name, const char *cmsg);

66 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* xcpt.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "xcpt.h"

static char xcpt_name[XCPT_NAME_MAX_SIZE + 1]; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE + 1]; static int trying; /* Sets try_flag. **/ void __begin_try(void) { trying = 1; } /* UnSets try_flag. **/ void __end_try(void){ trying = 0; } /* From exception name, gets the exception message thown by __throw(n,m). Once cautch, the exception name is cleared . **/ const char * __catch(const char * name) { if ( strcmp(xcpt_name,name) == 0 ) { xcpt_name[0] = '\0'; return xcpt_cmsg; } else return NULL; } /* Stores an exception contextual message. When called outside a __begin_try(); ...; __end_try(); pair, the exception message is also printed to the stderr stream . **/ void __throw(const char * name,const char * cmsg) { strncpy(xcpt_name,name,XCPT_NAME_MAX_SIZE); strncpy(xcpt_cmsg,cmsg,XCPT_CMSG_MAX_SIZE); if ( !trying ) fprintf(stderr,"exception: %s: %s\n",xcpt_name,xcpt_cmsg); }

67 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Alocao Dinmica
lrc , 23 June 2008 (created 20 May 2008)
no tags

Definio
ALOCAO DINMICA o processo atravs do qual um programa pode criar novas variveis (reas de memria) em tempo de execuo. Variveis alocadas dinmicamente so criadas em uma rea de memria livre chamada de HEAP e so acessadas atravs de PONTEIROS.

Funes de Alocao Dinmica em C


Padro ANSI
#include <stdlib.h> void * calloc(size_t num, size_t size); Aloca uma quantidade de memria igual a num* size. Isto , aloca memria suficiente para um ARRANJO de num VARIVEIS de tamanho size.
Devolve o endereo para o primeiro byte da regio alocada. Se no houver memria suficiente para satisfazer a solicitao, devolvido NULL (endereo nulo).

void * malloc(size_t size);


Aloca uma quantidade de memria igual a size. Isto , aloca memria suficiente para uma VARIVEL de tamanho size. Devolve o endereo para o primeiro byte da regio alocada. Se no houver memria suficiente para satisfazer a solicitao, devolvido NULL (endereo nulo).

void * realloc(void * ptr, size_t size);


Modifica o tamanho da memria previamente alocada apontada por ptr para um novo tamanho especificado por

size. O valor size pode ser maior ou menor que o original.


Retorna o endereo para o primeiro byte da regio de memria redimensionada. Se no houver memria suficiente no HEAP para satisfazer a solicitao, devolvido NULL (endereo nulo) e o endereo originalmente em ptr deixado inalterado.

void free(void * ptr);


Devolve ao HEAP a memria apontada por ptr, tornando a memria disponvel para alocao futura. Deve ser chamada somente com um PONTEIRO ptr cujo endereo de memria foi previamente alocado por meio de uma das funes do sistema de alocao dinmica ( calloc(), malloc(), realloc()).

Outras
#include <string.h> char * strdup(const char * pstr); Duplica a STRING apontada por pstr. Ou seja, aloca no HEAP strlen(pstr)+1 bytes e copia a STRING comeando em pstr para o endereo alocado. Retorna o endereo alocado contendo uma cpia da STRING apontada por pstr ou NULL caso no haja memria
suficiente no HEAP.

68 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Ex.: O trecho de cdigo abaixo:

char str[] = "Teste"; char * pstr = strdup(str);


equivalente a:

char str[] = "Teste"; char * pstr = calloc(strlen(str) + 1, sizeof char); strcpy(pstr,str);

Atividade 1
Utilizando as funes de alocao dinmica em C, iremos agora implementar uma segunda verso do programa lista de strings estudado na aula Ponteiros.

list.h
/* list.h, Rev. 1.2 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #ifndef LIST_H #define LIST_H unsigned short list_size(void); void char * void char * void #endif list_add(const char * str, unsigned short pos); list_rem(unsigned short pos); list_set(const char * str, unsigned short pos); list_get(unsigned short pos); list_print(void);

list.c

69 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.c, Rev. 1.3 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #include #include #include #include #include <stdlib.h> <stdio.h> <string.h> "list.h" "xcpt.h"

/** private data */ static char ** list; static unsigned short static

size = 0;

char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];

/** public functions */ unsigned short list_size(void) { return size; } /* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT NULL_POINTER_XCPT **/ void when pos is invalid ( > size +1 ) when there is no memory available to add a new element to the list.

list_add(const char * str, unsigned short pos) { char * line = strdup(str); sprintf(xcpt_cmsg,"%s, %d: list_ins (\"%s\",%d);",__FILE__,__LINE__,str,pos) if ( line == NULL ) { THROW(NULL_POINTER_XCPT,xcpt_cmsg); return ; } if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } if ( size % 10 == 0 ) { char ** aux = (char **) realloc(list,(size + 10)*(sizeof (char**))); if ( aux == NULL ) { THROW(NULL_POINTER_XCPT,xcpt_cmsg); return ; } list = aux; }

70 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exerccios
1. Conclua a Atividade 1 implementando as funes:

char * list_rem(unsigned short pos); void list_set(const char * str, unsigned short pos); char * list_get(unsigned short pos); 2. Teste a nova implementao de list.h e list.c com o mesmo arquivo main.c apresentado na aula Ponteiros.

Vetores para Ponteiros, Ponteiros para Vetores e Ponteiros para Ponteiros


lrc , 20 May 2008 (created 20 May 2008) Considere as declaraes:
no tags

int * x [10]; int (* y)[10]; int * * z;


Questes: O que significam? Quais dos usos abaixo so vlidos?

int i,j,k[10],l[10][5],m[5][10]; x[1] = &i; x[3] = j; x[5] = k; x[7] = k[2]; x[9] = k + 5; x[0] x[2] x[4] x[6] x[8] = = = = = l[1]; l + 1; m[1]; &l[3][2]; m[3] + 2;

y = &i; y = k; y[2] = k; y = &k; y y y y = = = = l; m; l[1]; m + 2;

z = k; z = l; z = m;

Exerccios
Seja o seguinte trecho de programa:

71 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

int i=3,j=5; int *p, *q; p = &i; q = &j;


Qual o valor das seguintes expresses ?

p == &i *p - *q **&p 3* - *p/(*q)+7


Qual ser a sada do programa abaixo supondo que i ocupa o endereo 4094 na memria?

main() { int i=5, *p; p = &i; printf( %x %d }


Qual o resultado do seguinte programa?

%d

%d

%d \n , p,*p+2,**&p,3**p,**&p+4);

#include <conio.h> #include <stdio.h> void main(){ float vet[5] = {1.1,2.2,3.3,4.4,5.5}; float *f; int i; f = vet; printf("contador/valor/valor/endereco/endereco"); for(i = 0 ; i <= 4 ; i++){ printf("\ni = %d",i); printf(" vet[%d] = %.1f",i, vet[i]); printf(" *(f + %d) = %.1f",i, *(f+i)); printf(" &vet[%d] = %X",i, &vet[i]); printf(" (f + %d) = %X",i, f+i); } }
Considere os dois programas abaixo. O que fazem quando executados?

72 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <conio.h> #include <stdio.h> void main() { int vet[] = {4,9,12}; int i,*ptr; ptr = vet; for(i = 0 ; i < 3 ; i++) { printf("%d ",*ptr++); } }

#include <conio.h> #include <stdio.h> void main(){ int vet[] = {4,9,12}; int i,*ptr; ptr = vet; for(i = 0 ; i < 3 ; i++) { printf("%d ",(*ptr)++); } }
Seja vet um vetor de 4 elementos: TIPO vet[ 4] . Supor que depois da declarao, vet esteja armazenado no endereo de memria 4092 (ou seja, o endereo de vet[ 0] ). Qual o valor de vet+ 1, vet+ 2 e vet+ 3 se: TIPO = char? TIPO = int? TIPO = float? O que significam as seguintes declaraes:

int int int int int int

* pi; ** ppi; * vpi[5]; (* pvi)[3]; (* pmi)[3][5]; * mpi[5][3];

D exemplo de uma declarao de: vetor para ponteiros para matrizes ponteiro para vetor de matrizes matriz de vetores de ponteiros matriz de ponteiros para vetores Reescreva o programa abaixo, substituindo o comando while pelo comando for.

#include <stdio.h> #define NUMS 5 void main (void) { int nums[NUMS] = {16,54,7,43,-5}; int total = 0, *n_pt; n_pt = nums; /*armazena o endereo de nums[0] em n_pt*/ while (n_pt < nums + NUMS) total+=*n_pt++; printf( O total dos elementos do vetor %d , total); }
Determine a sada do seguinte programa:

73 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> void arr(int (*val)[3]) { printf( \n %d , printf( \n %d , printf( \n %d , printf( \n %d , }

*(*val)); *(*val +1)); *(*(val+1)+2)); *(*val)+1);

void main (void) { int nums[2][3]={{33,16,29},{54,67,99}}; arrs(nums); }


Dada a declarao para val na funo arr, a referncia val[ 1] [ 2] vlida dentro da funo?

Estruturas
lrc , 23 June 2008 (created 23 June 2008)
no tags

Tipos de Dados
Em aulas anteriores dissemos que os TIPOS de DADO podem ser classificados em: bsicos ou primitivos compostos ou construdos

Tipos compostos
Arranjos (matrizes e vetores) Ponteiros Definidos pelo usurio Estruturas Unies Enumeraes Campos de bits typedefs

Estruturas

74 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atividade : asciimap

1. Crie um projeto C chamado asciimap 2. Salve os arquivos abaixo no projeto

/* asciimap.h */ #define LAR_MAX 40 #define ALT_MAX 20

void ler_pontos(char asciimap[ALT_MAX][LAR_MAX]); void imprimir(char asciimap[ALT_MAX][LAR_MAX]);

NOTA : Sobre o uso de ARRANJOS em parametros de funes videL Matrizes e Parmetros de Funes.

75 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* asciimap.c */ #include "asciimap.h"

void ler_pontos(char asciimap[ALT_MAX][LAR_MAX]) { char opc[10] = "sim"; while( strcmp(opc,"nao") != 0 ) { unsigned short x,y; char c; printf("Ponto:\n"); printf(" x = "); scanf("%hu",&x); printf(" y = "); scanf("%hu",&y); if ( x >= LAR_MAX || y >= ALT_MAX ) { printf("erro: Max x = %hu e Max y = %hu\n", LAR_MAX -1, ALT_MAX -1); continue; } printf(" c = "); scanf(" %c" ,&c); asciimap[y][x] = c; printf("Outro? [sim|nao]\n"); scanf("%s",opc); } } void imprimir(char asciimap[ALT_MAX][LAR_MAX]) { int x,y; for( y=0; y < ALT_MAX; y++ ) { for( x=0; x < LAR_MAX; x++ ) printf("%c",asciimap[y][x]); printf("\n"); } }

76 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* asciimap-teste.c */ #include "asciimap.h" main() { char map[ALT_MAX][LAR_MAX]; memset(map,' ',LAR_MAX * ALT_MAX); ler_pontos(map); imprimir(map); }

Atividade 2 : retangulo
1. crie um projeto C e salve com o nome de retangulo 2. crie os arquivos abaixo no projeto retangulo

/* retangulo.h */ #include "asciimap.h" struct ponto { unsigned short x,y; char c; }; struct retangulo { struct ponto ini; unsigned short dx,dy; }; #define min(a,b) ((a) < (b) ? (a) : (b))

void desenhar(char asciimap[ALT_MAX][LAR_MAX], struct retangulo ret);

77 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* retangulo.c */ #include "retangulo.h" void desenhar(char asciimap[ALT_MAX][LAR_MAX], struct retangulo ret) { int x,xf,y,yf; xf = min(ret.ini.x + ret.dx, LAR_MAX); for ( x = ret.ini.x ; x < xf; x++ ) asciimap[ret.ini.y][x] = ret.ini.c; yf = min(ret.ini.y + ret.dy, ALT_MAX); for ( y = ret.ini.y; y < yf; y++ ) asciimap[y][ret.ini.x] = ret.ini.c; if ( ret.ini.y + ret.dy <= ALT_MAX ) for ( x = ret.ini.x ; x < xf; x++ ) asciimap[yf-1][x] = ret.ini.c; if ( ret.ini.x + ret.dx <= LAR_MAX ) for ( y = ret.ini.y ; y < yf; y++ ) asciimap[y][xf-1] = ret.ini.c; }

/* retangulo-teste.c */ #include "retangulo.h"

main() { struct ponto struct retangulo struct retangulo p = {0, 0, '.'}; r = { p, 10, 4 }; r2= { {10,4,'-'}, 10, 10};

char map[ALT_MAX][LAR_MAX]; memset(map,' ', ALT_MAX*LAR_MAX); desenhar(map,r); desenhar(map,r2); imprimir(map); }

Leitura Recomendada
CCT cap 7 http:/ / www.di.ufpe.br/ ~ if097/ lprog1-p10/ sld001.htm

78 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exerccios
1. Estenda o programa da atividade 2 para incluir o desenho de : retas (definida por dois pontos distintos; ) circulos (definido por um ponto central e um raio ); 2. Escreva uma funo que use as mesmas estruturas da atividade 2 para descobrir se um ponto est dentro de um retngulo. 3. Defina uma estrutura que permita representar um tringulo, atravs das coordenadas dos seus vrtices. Em seguida, escreva uma funo que leia as coordenadas dos vrtices de um tringulo e preencha a estrutura definida cujo endereo lhe passado como parmetro. Depois, escreva funes que determinem o permetro e a rea de um tringulo representado pela estrutura definida. Por fim, desenvolva um programa de teste de todas as funes criadas. 4. Considere que uma empresa precisa armazenar os seguintes dados de um cliente: DADOS Nome completo com no mximo 50 caracteres; renda mensado do cliente; ano de nascimento; possui ou no carro. Defina um tipo e uma estrutura para armazenarem estes dados e escreva um programa que leia estes dados armazene-os em uma varivel e em seguida os imprima. 5. Considerando a mesma estrutura do exerccio anterior, escreva um programa que leia os dados de 100 clientes e imprima: quantos clientes tm renda mensal acima da mdia; quantos clientes tm carro; quantos clientes nasceram entre 1960 (inclusive) e 1980 (exclusive). 6. Considere que foi definida a seguinte estrutura:

typedef struct _frac } FRACAO;

{ int numerador, denominador;

Escreva um programa em C que calcule as quatro operaes (+ , -, * e / ) usando fraes definidas com estruturas do tipo FRACAO. O programa deve ler duas fraes e imprimir o resultado de cada uma das quatro operaes.

typedef, ponteiros para funes e union


lrc , 23 June 2008 (created 23 June 2008)
no tags

Exemplo

79 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#ifndef MENU_H #define MENU_H typedef struct char * void(* struct struct struct struct } Item; item { str; fun)(void); item * sub; item * sup; item * nxt; item * prv;

void addMenuItem (const char * str, void(* fun)(void)); void addMenuSubItem (const char * str_i,const char * str_si, void(* fun)(void)); void loopMenu(void); #endif

/** menu.c */ #include #include #include #include #include <stdlib.h> <stdio.h> <conio.h> "buffer.h" "menu.h"

Item * menu; Item * menu_sel; int sub_items_visible; ...

Exemplo

80 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** menu.c */ ... void addMenuItem (const char * str, void(* fun)(void)) { Item * ptr; /** PARAM PONT. FUNCAO */

if ( menu == NULL ) { menu = (Item *) malloc(sizeof (Item)); ptr = menu; ptr->prv = NULL; } else { ptr = menu; while ( ptr->nxt ) { if ( strcmp(ptr->str,str) == 0 ) return; ptr = ptr->nxt; } ptr->nxt = (Item *) malloc(sizeof (Item)); ptr->nxt->prv = ptr; ptr = ptr->nxt; } ptr->str = strdup(str); ptr->fun = fun; /** ATRIBUICAO PONTEIRO FUNCAO **/ ptr->sub = NULL; ptr->sup = NULL; ptr->nxt = NULL; }

... { ... case ENTER: if ( menu_sel->fun ) (*(menu_sel->fun))(); else ... }

/** CHAMADA FUNCAO VIA PONTEIRO **/

81 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#define #define #define #define #define #define union

ENTER ESC RTARR LTARR UPARR DWARR

13 27 77 75 72 80

u_type{ int i; char ch;

} ich;

void loopMenu() { while ( 1 ) { ich.i = getch(); switch ( ich.ch ) { case ENTER: ....

CDIGO COMPLETO
O cdigo abaixo implementa um sistema de menus para um programa de controle acadmico.

82 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** main.c */ #include <stdio.h> #include <stdlib.h> #include "menu.h"

void f() { printf("function activation!"); getch(); } extern Item * menu; extern Item * menu_sel; extern int sub_items_visible; int main(int argc, char *argv[]) { addMenuItem("CADASTRO",NULL); addMenuItem("MATRICULA",NULL); addMenuItem("RELATORIO",NULL); addMenuSubItem("CADASTRO","Alunos",f); addMenuSubItem("CADASTRO","Professores",f); addMenuSubItem("CADASTRO","Disciplinas",f); addMenuSubItem("MATRICULA","Matriculas",f); addMenuSubItem("MATRICULA","Turma",f); loopMenu(); return 0; }

#ifndef MENU_H #define MENU_H typedef struct char * void(* struct struct struct struct } Item; item { str; fun)(void); item * sub; item * sup; item * nxt; item * prv;

void addMenuItem (const char * str, void(* fun)(void)); void addMenuSubItem (const char * str_i,const char * str_si, void(* fun)(void)); void loopMenu(void); #endif

83 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** menu.c */ #include #include #include #include #include <stdlib.h> <stdio.h> <conio.h> "buffer.h" "menu.h"

Item * menu; Item * menu_sel; int sub_items_visible;

void addMenuItem (const char * str, void(* fun)(void)) { Item * ptr; if ( menu == NULL ) { menu = (Item *) malloc(sizeof (Item)); ptr = menu; ptr->prv = NULL; } else { ptr = menu; while ( ptr->nxt ) { if ( strcmp(ptr->str,str) == 0 ) return; ptr = ptr->nxt; } ptr->nxt = (Item *) malloc(sizeof (Item)); ptr->nxt->prv = ptr; ptr = ptr->nxt; } ptr->str = strdup(str); ptr->fun = fun; ptr->sub = NULL; ptr->sup = NULL; ptr->nxt = NULL; } void addMenuSubItem (const char * str_i,const char * str_si, void(* fun)(void)) { Item * ptr; ptr = menu; while ( ptr ) { if ( strcmp(ptr->str,str_i) == 0 ) break; ptr = ptr->nxt; } if ( ptr == NULL ) return; if ( ptr->sub == NULL ) { ptr->sub = (Item *) malloc(sizeof (Item)); ptr->sub->prv = NULL; ptr->sub->sup = ptr; ptr = ptr->sub; } else { ptr = ptr->sub;

84 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** buffer.h */ #ifndef BUFFER_H #define BUFFER_H void clearBuf(void); void xyputs(unsigned short x, unsigned short y, const char * str); void displayBuf(void);

#endif

85 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** buffer.c */ #include <stdlib.h> #include <stdio.h> #include <conio.h> #define BUFW #define BUFH 80 24

char buf[BUFH][BUFW]; void clearBuf(void){ int x,y; for( y = 0; y < BUFH; y++ ) { for( x = 0; x < BUFW; x++ ) buf[y][x] = ' '; } } void xyputs(unsigned short x, unsigned short y, const char * str) { x %= BUFW; y %= BUFH; for ( ; *str ; str++ ) { switch( *str ) { case '\n' : x = 0, y = (y + 1) % BUFH; break; case '\b' : if ( x == 0 ) { x = BUFW - 1; y = y == 0 ? BUFH - 1 : y -1; } else x --; break; default : buf[y][x] = *str; x = (x+1)%BUFW; y = x == 0 ? (y+1)%BUFH : y; } } } void displayBuf(void) { //fseek(stdout,sizeof buf,SEEK_END); system("cls"); fwrite(&buf,sizeof buf ,1,stdout); }

Enumeraes e Campos de Bits


lrc , 23 June 2008 (created 23 June 2008)

86 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

no tags

Enumeraes
Uma enumerao uma extenso da linguagem C acrescentada pelo padro ANSI. Uma enumerao uma declarao de um novo tipo de dados que consiste em um conjunto de constantes inteiras que especficam todos os valores legais que uma varivel desse tipo pode ter. Enumeraes so definidas de forma semelhante a estruturas; no entanto, utiliza-se a palavra-chave enum para assinalar o incio de um tipo de enumerao. FORMA GERAL:

enum identificador { Simbolo_1, Simbolo_2, ... Simbolo_n } var_1, var_2, ..., var_n;

Em uma enumarao cada Simbolo_i representa um valor inteiro. Cada smbolo recebe um valor maior em uma unidade do precedente. Por default, o valor do primeiro smbolo 0. No entanto, voc pode especificar o valor de um ou mais smbolos usando um inicializador. O smbolos que aparecem aps os inicializadores recebem valores maiores que o da inicializao 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

87 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo
struct { unsigned unsigned unsigned unsigned } bitf; mday : 5; month: 4; year :22; isBCE: 1;

Exemplo Completo
O programa abaixo ilustra todos os mecanismos de definio de novos tipos estruturados pelo usurio: estruturas struct definio de novos nomes para tipos typedef enumeraes enum unies union campos de bits struct Alm disso, o exemplo tambm aborda o uso de funes da biblioteca <time.h>. Para o entedimento do exemplo que trata de datas do calendrio gregoriano voc pode consultar: http:/ / en.wikipedia.org/ wiki/ Gregorian_calendar Para implementao do algoritmo DOOMSDAY para o clculo do dia da semana de uma data, consulte: http:/ / en.wikipedia.org/ wiki/ Doomsday_algorithm

88 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** 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 unsigned unsigned unsigned unsigned enum dt_month long unsigned long };

, , , , , ,

, , , , , , , , , , ,

wday; mday; yday; mweek; yweek; month; year; isBCE; serial;

/* /* /* /* /* /* /* /* /*

day of the week : 0 .. day of the month : 1 .. days since Jan. 1 : 1 .. week of the month : 0 .. week of the year : 0 .. month : 1 .. year : -2^22 .. is Before Common Era ? number of days

6 31 366 5 53 12 2^22

*/ */ */ */ */ */ */ */ */

date_t date_t

date(date_t *); mkdate(struct dt *);

/* get current date */ /* code struct dt* in a date_t */

89 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

90 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** date.c Author: Luciano R. Coutinho, 2007. lrc@deinf.ufma.br */ #include #include #include #include <stdio.h> <stdlib.h> <time.h> "date.h"

union date_t { date_t ival; struct { unsigned unsigned unsigned unsigned } bitf; }; /* Global Shared */ static static int 0 , /* 31, /* 28, /* 31, /* 30, 31, 30, 31, 31, 30, 31, 30, 31 /* };

mday : 5; month: 4; year :22; isBCE: 1;

struct dt dt_buf; num_days[13] = { skiped */ January */ February */ Mars */

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 = ud.bitf.month= ud.bitf.year = ud.bitf.isBCE= tm_now->tm_mday; tm_now->tm_mon + 1; tm_now->tm_year + 1900; 0;

if ( d ) *d = ud.ival; return ud.ival; } /* Gregorian Calendar

91 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> #include <stdlib.h> #include "date.h" union date_t { date_t ival; struct { unsigned unsigned unsigned unsigned } bitf; }; char

mday : 5; month: 4; year :22; isBCE: 1;

* 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,sdud.bitf.mday = 7; ud.bitf.month = September; ud.bitf.year = 1822; ud.bitf.isBCE = 0; sd = gcdate(ud.ival); printf("a idependncia ocorreu num(a) %s

\n",wday_name[sd->wday]);

//system("PAUSE"); return 0; }

Exerccios
1. Conclua o exemplo date.h/ date.c; Escreva as funes

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*);
2. Escreva um programa que teste todas as funes criadas acima.

92 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Entrada/ Sada: console


lrc , 23 June 2008 (created 23 June 2008)
no tags

Lendo e Escrevendo Caracteres


#include <stdio.h> int getchar(void); int putchar(int c); #include <conio.h> int getch(void) int getche(void)

Lendo e Escrevendo Strings


#include <stdio.h> char * gets(char *str); int puts(const char *str);

Exemplo 1

#include <stdio.h> #include <ctype.h>

main() { char ch; printf("Digite algum texto (termine com ponto para sair)\n"); do { ch = getchar(); if ( islower(ch) ) ch = toupper(ch); else ch = tolower(ch); putchar(ch); } while ( ch != '.' ); }

93 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atividade 1
Refaa o programa acima utilizando getch() e getche().

Entrada/Sada Formatada
#include <stdio.h> int printf(const char * string_de_controle, ...); int scanf(const char * string_de_controle, ...);

printf(): Formato Geral

printf(): Formato Detalhado

94 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo 2
printf ("\nResultado :%3.2f",num); printf ("Frase : %s\nContador = %x",string,cont); printf ("a : %-5d b : %-5d c : %-5d",a,b,c);

Atividade 1
Teste o trecho de cdigo acima em um programa.

scanf(): Formato

95 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Leitura Recomendada
CCT Cap 8. http:/ / www.dee.feis.unesp.br/ graduacao/ disciplinas/ langc/ modulo_linguagemc/ modulo4.htm

Entrada/ Sada: arquivos


lrc , 23 June 2008 (created 23 June 2008)
no tags

fopen(), fclose()

96 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> FILE * fopen(const char * nomearq, const char * modo); int fclose(FILE * fp);

putc(), fputc(), getc(), fgetc()


#include <stdio.h> int putc(int char, FILE * fp); int fputc(int char, FILE * fp); int getc(FILE * fp); int fgetc(FILE * fp);

Exemplo 1

97 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** ktod.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char * argv[]) { FILE * fp; char ch; if ( argc != 2 ) { printf("sintaxe:\n"); printf(" %s NOME_ARQ\n",argv[0]); exit (1); } fp = fopen(argv[1],"w"); if ( fp == NULL ) { printf("O arquivo exit(1); } do { ch = getchar(); putc(ch, fp); } while ( ch != '$' ); fclose(fp); }

%s

no pode ser aberto.\n",argv[1]);

Exemplo 2

98 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** dtos.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char * argv[]) { FILE * fp; char ch; if ( argc != 2 ) { printf("sintaxe:\n"); printf(" %s NOME_ARQ\n",argv[0]); exit (1); } fp = fopen(argv[1],"r"); if ( fp == NULL ) { printf("O arquivo exit(1); } ch = getc(fp); while ( ch != EOF ) { putchar(ch); ch = getc(fp); } fclose(fp); }

%s

no pode ser aberto.\n",argv[1]);

fputs() , fgets()
#include <stdio.h> int fputs(const char * str, FILE * fp); char * fgets(char *str, int length, FILE * fp);

fread() , fwrite()
#include <stdio.h> size_t fread(void * buffer, size_t num_bytes, size_t count, FILE * fp); size_t fwrite(const void * buffer, size_t num_bytes, size_t count, FILE * fp);

Leitura Recomendada
CCT Cap 9 http:/ / www.dee.feis.unesp.br/ graduacao/ disciplinas/ langc/ modulo_linguagemc/ modulo8.htm

99 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exerccios
1. Refaa os programas dos exemplos 3 e 4 utilizando fputs() e fgets(). 2. Escreva um programa que abra um arquivo texto e conte o nmero de caracteres presentes nele. Imprima o nmero de caracteres na tela. 3. Considere um arquivo de dados do tipo texto com o seguinte contedo:

3 ZE SA 8.5 10.0 ANTONIO SANTOS 7.5 8.5 SEBASTIAO OLIVEIRA 5.0 6.0
O arquivo acima apenas um exemplo. Nestes arquivos de alunos a primeira linha contm o nmero de alunos no arquivo. As linhas seguintes contm os seguintes dados: nome do aluno com no mximo 50 caracteres; nota da primeira prova; nota da segunda prova. Escreva um programa que imprima os nomes de todos os alunos que tm a mdia das duas notas menor que 7.0

4. Escreva um programa que grave os dados lidos no exerccio anterior em um arquivo do tipo binrio de acesso aleatrio. O nmero que indica quantos alunos devem ser lidos (primeira linha do arquivo) no deve ser gravado no arquivo binrio. Nesta questo os dados devem estar obrigatoriamente armazenados em um vetor de estruturas do seguinte tipo:

typedef struc _aluno { char nome[81]; float n1, n2; } ALUNO;

5. Escreva um programa que leia de um arquivo, cujo nome sera fornecido pelo usuario, um conjunto de numeros reais e armazena em um vetor. O tamanho mximo do vetor e dado pela constante TAM_MAX. A quantidade de numeros no arquivo varia entre 0 e TAM_MAX. O programa ao final calcula a media dos numeros lidos. 6. Faa um programa que leia 10 caracteres e armazene em um arquivo 10 cpias de cada um. Exiba o contedo do arquivo. 7. Crie uma funo que receba duas strings como parmetros, uma com um endereo de arquivo e outra com um texto qualquer, e adicione o texto no fim do arquivo. 8. Utilizando a funo do exerccio anterior faa um programa que gere 10 arquivos com o nome "Teste" e extenses "01", ..., "10". Cada um contendo o texto "Texto do arquivo [ NMERO DO ARQUIVO] ". 9. Escreva um programa para armazenar o telefone de 5 amigos atravez da estrutura

struct pessoa{ char nome[50]; int idade; float altura; char telefone[10]; } amigos[5];
a ser preenchida pelo usurio antes do armazenamento de cada registro. 10. Faa um programa que leia os dados do arquivo gerado no exerccio anterior e salve-os num novo arquivo utilizando uma sada formatada.

100 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

FORMATO: -------[nome] tem [idade] anos e [altura] de altura. Tel.: [telefone]. --------

11. Escreva um programa que leia um arquivo texto contendo linhas de dados. Em cada linha do arquivo h o nome de um aluno e duas notas. Estes dados esto separados por ponto e vrgula. Existe um ponto e vrgula ao final de cada linha. O formato dos dados e o seguinte:

ze sa; 10.0; 9.0; antonio silva: 9.0; 7.0;


O programa deve ler estes dados e imprimir os valores lidos, a mdia das duas notas e se o aluno foi aprovado ou no (media > = 5). O formato de saida e:

ze sa 10.0 8.0 9.0 aprovado antonio silva 9.0 7.0 8.0 aprovado

12. Faa um programa que ao receber o nome de um arquivo, gere uma cpia deste. 13. Escreva um programa que compare dois arquivos especificados pelo usurio e imprima sempre que os caracteres dos dois arquivos coincidirem. Por exemplo:

arquivo1.c Ol, pessoal! arquivo2.c Oi, como vai?


Neste caso, os caracteres na primeira e dcima primeira posio so iguais nos dois arquivos. A sada do seu programa deve ser algo como:

1 - O (79) 11 - a (97)
Os valores entre parenteses so os respectivos cdigos ASCII dos caracteres.

Pr-processador C
lrc , 23 June 2008 (created 23 June 2008)
no tags

Leitura Recomendada
CCT-cap10

Introduo
Um programa em C transformado em cdigo objeto em duas etapas: uma de PRE-PROCESSAMENTO e a outra de COMPILAO propriamente dita. Na primeira etapa, as DIRETIVAS de PRE-PROCESSAMENTO so convertidas em cdigo C; na segunda etapa, o cdigo C resultante compilado. Abaixo iremos estudar o PRE-PROCESSADOR de C e suas DIRETIVAS. Ao longo da explicao utilizaremos como exemplo os arquivos de programa main.c, list.c, list.h, xcpt.c e xcpt.h discutidos ao final da aula Ponteiros.

101 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include

Exemplo

102 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* main.c **/ #include <stdio.h> #include <stdlib.h> #include "list.h" #include "xcpt.h" int main(int argc, char *argv[]) { ... } /* arquivos de cabealho padro */

/* arquivos de cabealho do projeto */

#define

103 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo
/* xcpt.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #ifndef XCPT_H #define XCPT_H #define XCPT_NAME_MAX_SIZE #define XCPT_CMSG_MAX_SIZE #define THROW(e,m) #define TRY(f) #define CATCH(e,m) #define #define #define #define #define 32 1024

__throw((e),(m)) __begin_try();f;__end_try(); if(m=__catch(e)) "null pointer" "index out of bounds" "overflow" "underflow" "illegal argument"

NULL_POINTER_XCPT INDEX_OUT_OF_BOUNDS_XCPT OVERFLOW_XCPT UNDERFLOW_XCPT ILLEGAL_ARGUMENT_XCPT

void void const char * void #endif

__begin_try(void); __end_try(void); __catch(const char *name); __throw(const char *name, const char *cmsg);

#if, #else, #elif e #endif

104 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo-1

105 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo-2
/** 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 ...

#ifdef

Exemplo
Vide inicio dos exemplos anteriores. Eles comeam assim:

106 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#ifndef FILENAME_H #define FILENAME_H ... #endif

#undef

#line

Macros pr-definidas

107 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo
Veja um exemplo de uso de __LINE__ e __FILE__ no trecho de programa abaixo que foi apresentado na aula Ponteiros:

/* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT LIST_FULL_XCPT LINE_TOO_LONG_XCPT **/ void when pos is invalid ( > size +1 ) when the list size equals LIST_MAX_SIZE when str is greater than LINE_MAX_SIZE

list_add(const char * str, unsigned short pos) { sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n", __FILE__,__LINE__,str,pos); if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } ...

#pragma

108 de 109

14/10/2009 10:46

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

TiddlyWiki Osmosoft

109 de 109

14/10/2009 10:46

This document was created with Win2PDF available at http://www.win2pdf.com. The unregistered version of Win2PDF is for evaluation or non-commercial use only. This page will not be added after purchasing Win2PDF.

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

search

Prof. Luciano R. Coutinho email:lrc@deinf.ufma.br

Apresentao
lrc , 16 March 2008 (created 16 March 2008)
no tags

Ementa
Conceitos Gerais. Tipos de linguagens. Linguagem de programao estruturada. Variveis e tipos de dados. Estruturas de controle de fluxo de execuo. Modularizao. Tipos complexos de dados. Operaes com arquivos. Aplicaes.

Objetivos
Apresentao de uma linguagem de programao que ser usada no aprendizado de tcnicas de programao e na modelagem de problemas.

Programa
1 Introduo s linguagens de programao 2 Viso Geral de C 2.1 Padronizaes 2.2 Caractersticas 2.3 Estrutura geral de um programa em linguagem C 3 Tipos de dados e tipos de variveis 3.1 Variveis inteiras, caracter, e ponto flutuante 3.2 Definio de variveis globais, externas, locais e estticas 4 Operadores e expresses 4.1 Operadores aritmticos, relacionais, lgicos, bit a bit 4.2 Operador de atribuio condicional e operador de moldagem 4.3 Expresses em C 5 Controle de fluxo de execuo 5.1 Desvios incondicionais 5.2 Desvios condicionais 5.3 Comandos de malha 6 Funes 6.1 Tipos de funes 6.2 Passagem de parmetros por valor e por endereo 6.3 Construo de funes e funes padronizadas 7 Vetores e ponteiros 7.1 Alocao esttica e dinmica 7.2 Definio e inicializao de vetores 7.3 Ponteiros em C 7.4 Aplicaes de ponteiros 8 Estruturas, unies e tipos definidos pelo usurio 8.1 Definio de estruturas

1 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

8.2 Vetor de estruturas 8.3 Passagem de estruturas como parmetros 8.4 Definio de Unies 8.5 Tipos definidos pelo usurio 9 Entrada e sada em arquivos 9.1 Conceitos de arquivos 9.2 Arquivos no MSDOS e UNIX 9.3 Arquivos textos e binrios 9.4 Operaes de leitura e escrita em arquivos 9.5 Funes da biblioteca C para manipulao de arquivos 10 Pre - Processador C 10.1 Diretivas de Compilao

Procedimentos de Ensino/Aprendizagem
Recursos Didticos
Uso de computadores, ambiente desenvolvimento em C, quadro-branco, marcador, notas de aulas.

Metodologia
Aulas terico - prticas em laboratrio, desenvolvimento e discusso de programas, trabalhos de programao pelos alunos.

Sistema de Avaliao
Trs Avaliaes (A1, A2 e A3), seguidas de uma Reposio (R) (para aqueles cuja mdia (A1+ A2+ A3)/ 3 < 7,0) e uma Final (F) (para aqueles cuja mdia corrigida pela Reposio seja > = 4,0 e < 7,0). Seguindo as normas da UFMA, ser APROVADO o aluno que: tiver mdia ao fim da ltima avaliao maior ou igual a SETE media = (A1+ A2+ A3)/ 3 > = 7,0 OU tiver mdia aps a reposio maior ou igual a SETE mediaRep = (A1+ A2+ A3 - min{ A1,A2,A3} + R)/ 3 > = 7,0 OU tiver mdia aps a reposio MAIS nota da Final maior ou igual a 12 mediaRep + Final > = 12,0

Avaliaes
A1 e A2
Feitas a partir de: PROVAS ESCRITAS INDIVIDUAL (P1 e P2) LISTAS de EXERCCIOS INDIVIDUAIS (L1 e L2) Calculo: Avaliao A1 = ( 2* P1 + L1 ) / 3 Avaliao A2 = ( 2* P2 + L2 ) / 3

A3
Feita a partir de: PROVA ESCRITA INDIVIDUAL (P3) PROJETO de PROGRAMAO em GRUPO (T3) Calculo:

2 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Avaliao A3 = (2* T3 + P3) / 3

Reposio
Consistir em uma PROVA ESCRITA INDIVIDUAL. A nota da Reposio ir substituir a menor nota dentre A1, A2 e A3. O assunto da Reposio ser o contedo correspondente ao contedo da menor nota sendo substituda.

Final
Consiste em uma PROVA ESCRITA INDIVIDUAL. O assunto da Final ser todo o contedo ministrado durante o curso.

Bibliografia

Cronograma
lrc , 9 March 2009 (created 16 March 2008) Data Assunto 25/ 08 I ntroduo; viso geral de C 27/ 08 Declaraes: I dentificadores e Tipos de Dados Bsicos 01/ 09 Declaraes: Variveis e Classe de Memria 03/ 09 Declaraes: Tipo de Acesso, I nicializao e Constantes 08/ 09 sem aula; viajando S. Paulo 10/ 09 sem aula; viajando S. Paulo 15/ 09 Operadores e Expresses: atribuies, aritmtica e lgica 17/ 09 Operadores e Expresses: atribuies, aritmtica e lgica 22/ 09 Operadores e Expresses: bit-a-bit e especiais 24/ 09 Controle de Fluxo: Comandos de Seleo 29/ 09 Controle de Fluxo: Laos e Desvios I ncondicionais 01/ 10 1a. Prova 06/ 10 Funes: definio, declarao e chamada 08/ 10 Funes: main( ) e recurso 13/ 10 Vetores, matrizes e strings 15/ 10 Vetores, matrizes e strings 20/ 10 Ponteiros 22/ 10 Ponteiros 27/ 10 Exemplo: Lista de Strings 29/ 10 Alocao Dinmica 03/ 11 Vetores para Ponteiros, Ponteiros para Vetores e Ponteiros para Ponteiros 05/ 11 2a Prova Escrita 10/ 11 Estruturas 12/ 11 typedef, ponteiros para funes e union 17/ 11 typedef, ponteiros para funes e union 19/ 11 Enumeraes e Campos de Bits 24/ 11 Entrada/ Sada: console 26/ 11 Entrada/ Sada: arquivos 01/ 12 03/ 12 08/ 12 Pr-processador C 10/ 12 3a Prova Escrita 15/ 12 Reposio
no tags

3 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

17/ 12 Final

I ntroduo; viso geral de C


lrc , 16 March 2008 (created 16 March 2008)
no tags

Tpicos
As Origens de C C - Caractersticas Nvel Mdio Estruturada Para programadores Programao de sistemas Estrutura Geral de um programa em C Edio, compilao e Link Edio C versus C+ +

As Origens de C
Ken Thompson e Dennis Ritchie (da esquerda pra direita), os criadores das linguagens B e C, respectivamente:

Para detalhes, leia: D. M. Ritchie; O Desenvolvimento da Linguagem C http:/ / www.caloni.com.br/ blog/ archives/ historia-da-linguagem-c-parte-1 http:/ / www.caloni.com.br/ blog/ archives/ historia-da-linguagem-c-parte-2

Evoluo das Linguagem de Programao


Ref: History of programming languages Computer Languages History

4 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Padronizao ANSI
Ref: Jones, Derek M. (2008) "The New C Standard: An Economic and Cultural Commentary."

5 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

6 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

C - Caractersticas
Nvel Mdio Estruturada Para programadores Programao de sistemas

Linguagem de Nvel Mdio

Linguagem Estruturada

Linguagem para Programadores

Linguagem para Programao de Sistemas

7 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Estrutura geral de um programa


Palavras Reservadas

Funes

Exemplo

8 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Edio, compilao e Link Edio

IDE - Integrated Developmente Environments


DevCpp Code::Blocks + gcc

9 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

jGRASP + gcc TurboC

Termos
Compilao Separada Biblioteca Padro ANSI

C versus C++

Leitura Recomendada
CCT captulo 1 K&R captulo 1 D. Ritche, O Desenvolvimento da Linguagem C* . Histrico das Linguagens de Programao Wikipedia: Ling. C

Exerccios
1. A linguagem C considerada uma linguagem de nvel mdio. Explique o que isto significa e quais as implicaes em termos prticos. 2. Programas escritos em C so ditos possuir alto grau de portabilidade. Explique o que isto significa e quais as implicaes em termos prticos. 3. A linguagem C, a exemplo de Pascal dito ser uma linguagem estruturada. Pesquise e descreva as principais diferenas entre a programao estruturada em Pascal e a programao estruturada em C. 4. Faa um resumo esquemticos das datas e principais acontecimentos relatados no artigo O Desenvolvimento da Linguagem C* de D. Ritchie. 5. A linguagem C uma linguagem compacta com apenas 32 palavras reservadas. Pesquise e liste as palavras reservadas de C. Classifique-as em: especificadores de tipos controle de fluxo especificadores de classe de memria outros 6. Modifique o programa media.c para exibir o nome do vetores P e T durante a leitura dos dados. Dica: redefina a funo

ler para aceitar como parametro o nome do vetor sendo lido, alm do prprio vetor. De posse do nome do vetor sendo
lido, exiba este nome antes da leitura de cada posio.

10 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Declaraes: I dentificadores e Tipos de Dados Bsicos


lrc , 29 March 2008 (created 24 March 2008)
no tags

Objetivos
Na primeira aula, vimos que um programa em C pode ser visto como uma seqncia de DECLARAES. De maneira geral, uma DECLARAO introduz um novo nome - um IDENTIFICADOR - e associa a este uma interpretao. Tome como exemplo o seguinte trecho de cdigo:

00: 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14:

#include <stdio.h> double x; void p(float b, int e) { short int i; x = b; ... } int main() { p(3.1415, 5); printf("%f",x); return 0; }

Na linha 1, vemos uma DECLARAO de VARIVEL GLOBAL. Nas linhas 3 a 8, temos uma DECLARAO de FUNO que, por sua vez, formada por uma DECLARAO de PARMETROS (linha 3), uma DECLARAO de VARIVEL LOCAL (linha 4) e uma seqncia de comandos (linhas 5-7). Em cada uma dessas DECLARAES um novo IDENTIFICADOR introduzido com uma interpretao particular! Na declarao da linha 1, o IDENTIFICADOR introduzido x e sua interpretao VARIVEL GLOBAL do TIPO BSICO double. Na declarao das linhas 3 a 8, o IDENTIFICADOR p e sua interpretao FUNO que recebe como PARMETROS um valor do TIPO BSICO float e um valor do TIPO BSICO int; tem uma VARIVEL LOCAL do TIPO BSICO short int, executa os comandos das linhas 6-7 e ao final nada retorna ( TIPO BSICO void). Note que, nesses exemplos, a interpretao dada a um IDENTIFICADOR est ligada de maneira ntima com um TIPO de DADOS BSICO. Nesta aula, nosso objetivo mostrar atravs de exemplos o que um IDENTIFICADOR vlido e quais so os TIPOS de DADOS BSICOS - os dois ingredientes fundamentais de toda DECLARAO em um programa C.

IDENTIFICADORES
Em C, um IDENTIFICADOR uma seqncia de LETRAS ou DGITOS onde: O primeiro caracter deve ser uma LETRA ( 'a',...,'z','A',...,'Z','_' ) O caracter '_' contado como uma LETRA LETRAS maisculas (e.g., 'A') so consideradas diferentes de letras minsculas (e.g., 'a') isto implica que o IDENTIFICADOR aux diferente de Aux que diferente de AUX PALAVRAS RESERVADAS tais como if, else, char, int, ... no podem ser usadas como IDENTIFICADORES.

Pelo padro C ANSI, um IDENTIFICADOR pode ter qualquer tamanho. Observaes Para IDENTIFICADORES INTERNOS (i.e., nomes restritos a uma nica UNIDADE de COMPILAO), pelo menos os primeiros 31 caracteres so significativos; algumas implementaes podem utilizar um conjunto maior de caracteres

11 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

significativos. J os IDENTIFICADORES EXTERNOS (i.e., nomes de de VARIVEIS GLOBAIS e FUNES compartilhados entre vrias UNIDADES de COMPILAO) so mais restritos: as implementaes podem considerar em casos extremos apenas 6 caracteres como significativos, e podem ignorar as distines entre letras maisculas e minsculas.

Atividade 1: Validando Indentificadores


Vamos escrever um programa em C ( id.c) que dado uma palavra (cadeia de caracteres) imprima na tela um

identificador! ou no um identificador! caso a palavra obedea ou no a definio de identificador dada


acima. DICA - comee o programa assim:

#include <stdio.h> char str[80]; /* armazena uma cadeia de at 79 caracteres */

int main() { printf("Digite uma palavra: "); scanf("%s", str); /* le do usrio uma cadeia de caracteres */ ... }

TIPOS de DADOS BSICOS


H cinco tipos de dados bsicos em C:

char : um nico byte, capaz de conter um caracter no conjunto de caracteres local; int : um inteiro, normalmente refletindo o tamanho natural dos inteiros da mquina hospedeira; float : ponto flutuante em preciso simples; double : ponto flutuante em dupla preciso; void : conjunto vazio de valores.
Todos os outros tipos de dados em C so baseados em um desses tipos bsicos.

Modificadores
Exceto void, os tipos de dados bsicos podem ter vrios MODIFICADORES precedendo-os. Um MODIFICADOR usado para alterar o significado de um tipo bsico para adapt-lo necessidade de diversas situaes. So MODIFICADORES de tipos:

long short signed unsigned

short ou long - referem-se a diferentes tipos de inteiros: A palavra int pode ser omitida e normalmente o ! short = short int long = long int
Obs.: Alguns compiladores permitem long long int ! (Fora do Padro ANSI)

long pode tambm ser aplicado a double de tal modo que: float double long double signed ou unsigned - podem ser aplicados a char, ou a short ou long ( int ).
Equivalencias char = signed char ou char = unsigned char, a depender da mquina hospedeira;

signed int = int = signed signed long = long

12 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

signed short = short unsigned int = unsigned


Obs.: Alguns compiladores podem permitir unsigned double ! (Fora do Padro ANSI)

Tamanho e Faixa de Valores


O tamanho e faixa de valores dos tipos bsicos de dados variam de acordo com: tipo do processador implementao do compilador No entanto, o padro ANSI C estipula valores mnimos:

Atividade 2: Explorando <limits.h>


Nos arquivos de cabealho <limits.h> e <float.h> encontram-se definidas constantes simblicas para a faixa de valores e tamanho em bytes dos tipos de dados bsicos e modificados da linguagem C, conforme foram implementados em um dado compilador/ mquina. Nesta atividade, o seu objetivo escrever um programa tipos.c que inclua os arquivos de cabealho <limits.h> e

<float.h> e imprima - para os tipos mostrados na tabela 2.1 - as seguintes informaes : TIPO char unsigned char signed char ... VALOR_MIN -128 0 -128 VALOR_MAX 127 255 127 TAMANHO em BYTES 1 1 1

Como ponto de partida, voc pode iniciar o seu programa assim:

13 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <limits.h> #include <float.h> char c; unsigned char uc; signed char sc; int i; ... int main(void) { printf("TIPO\t\t\tVALOR_MIN\t\tVALOR_MAX\tTAMANHO em BYTES\n"); printf("char\t\t\t%i\t\t\t%i\t\t%i\n", CHAR_MIN, CHAR_MAX, sizeof c); printf("unsigned char\t\t%i\t\t\t%i\t\t%i\n", 0, UCHAR_MAX, sizeof uc); printf("signed char\t\t%i\t\t\t%i\t\t%i\n", SCHAR_MIN, SCHAR_MAX, sizeof sc); ... }

Leitura Recomendada
CCT captulo 2 K&R captulos 2 Seebach, "Everything You Ever Wanted to Know about C Types" What's in a type? Floating point and derived types Implementation details Portability and pitfalls http:/ / pt.wikipedia.org/ wiki/ Tipo_de_dado

Para detalhes sobre representacao de caracteres: http:/ / www.ime.usp.br/ ~ pf/ algoritmos/ aulas/ char.html Para detalhes sobre representao de nmeros: inteiros ( int) http:/ / www.ime.usp.br/ ~ pf/ algoritmos/ aulas/ int.html ponto flutuante ( float, double) http:/ / en.wikipedia.org/ wiki/ Floating_point http:/ / en.wikipedia.org/ wiki/ Double_precision http:/ / en.wikipedia.org/ wiki/ IEEE_754

Para detalhes sobre o padro ANSI C: Jones, Derek M. (2008) "The New C Standard: An Economic and Cultural Commentary."

Exerccios
1. Faa por completo a atividade 1 2. Faa por completo a atividade 2 3. Utilizando os TIPOS inteiros em C, escreva programas para: a. Dado um nmero inteiro positivo n, calcular a soma dos n primeiros nmeros naturais. b. Dado um nmero inteiro positivo n, imprimir os n primeiros naturais mpares. Exemplo: Para n= 4 a sada dever ser 1,3,5,7. c. Dados n e dois nmeros inteiros positivos i e j diferentes de 0, imprimir em ordem crescente os n primeiros naturais que so mltiplos de i ou de j e ou de ambos. Exemplo: Para n = 6 , i = 2 e j = 3 a sada dever ser : 0,2,3,4,6,8. d. Dizemos que um nmero natural triangular se ele produto de trs nmeros naturais consecutivos. Exemplo: 120 triangular, pois 4.5.6 = 120. Dado um inteiro no-negativo n, verificar se n triangular. e. Dado um inteiro positivo p, verificar se p primo. f. Dados trs nmeros naturais, verificar se eles formam os lados de um tringulo retngulo. 4. Utilizando os TIPOS ponto flutuante em C, faa programas para os seguintes enunciados: a. Um programa que leia uma temperatura em graus celsius e a converta para fahrenheit.

14 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

b. Uma pessoa aplicou um capital de x complexos (1) a juros mensais de z durante 1 ano. Deseja-se um programa que determine o montante de cada ms durante este perodo. c. Dados nmeros reais a, b e c, calcular as razes de uma equao do 2o grau da forma ax^ 2 + b^ x + c = 0. 5. Utilizando o TIPO char, re-escreva os programas anteriores para ao final perguntar ao usrio: deseja processar

outro valor? [s/n]. Se o usurio digitar 's' ou 'S' o programa deve continuar processando uma nova entrada;
caso contrrio deve terminar.

Declaraes: Variveis e Classe de Memria


lrc , 29 March 2008 (created 24 March 2008)
no tags

Objetivo
Na ltima aula, vimos que uma DECLARAO introduz um novo IDENTIFICADOR e associa a este uma interpretao. Dentre as interpretaes possveis, um IDENTIFICADOR pode ser declarado para ser o nome smblico de uma VARIVEL. Neste caso, temos um dos mais importantes tipos de DECLARAO - a DECLARAO de VARIVEIS. Nesta aula, nosso objetivo estudar: a forma geral de DECLARAES de VARIVEIS em C a noo de CLASSE de MEMRIA associada a uma VARIVEL

Variveis
VARIVEIS so abstraes de locais de armazenamento de dados. Os dados armazenados em uma VARIVEL podem mudar ao longo da execuo de um programa. Da o nome VARIVEL. Uma VARIVEL possui dois atributos principais: um TIPO de DADO : determina o significado dos valores achados em uma VARIVEL. uma CLASSE de MEMRIA (ou CLASSE de ARMAZENAMENTO) : determina o tempo de vida e a rea de memria na qual a VARIVEL alocada. Variveis tambm podem ter: um TIPO de ACESSO : determinam a maneira como as variveis podem ser acessadas ou modificadas.

Variveis podem ser declaradas tanto fora quando dentro de funes. No primiro caso as variveis so ditas GLOBAIS; no segundo caso, LOCAIS.

Declarao de Variveis
Em C, uma DECLARAO de VARIVEL assume a seguinte forma geral:

ESPEC-DECLARAO DECLARADOR-1 = INICIALIZADOR-1, ..., DECLARADOR-n = INCIALIZADOR-n;


Onde: ESPEC-DECLARAO e cada DECLARADOR-i so obrigatrios; cada = INICIALIZADOR-i opcional.

ESPEC-DECLARAO uma sequncia composta de pelo menos um dentre trs categorias de ESPECIFICADOR: ESPECIFICADOR do TIPO de DADO; int, char, float, double e seus MODIFICADORES long, short, signed e unsigned ESPECIFICADOR da CLASSE de MEMRIA; auto, register, static e extern ESPECIFICADOR do TIPO de ACESSO; const e volatile

15 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

A forma mais simples de um DECLARADOR um IDENTIFICADOR. Nesta aula, iremos considerar como DECLARADOR apenas IDENTIFICADORES. Um INICIALIZADOR, de maneira geral, consiste em uma EXPRESSO.

Ambiente de Execuo C
Em C, h quatro locais onde uma varivel pode ser alocada: na REA de DADOS ESTTICA na PILHA de EXECUO em REGISTRADORES no HEAP

Especificadores da Classe de MEMRIA


Em C, h quatro PALAVRAS RESERVADAS que funcionam como ESPECIFICADORES da CLASSE de MEMRIA durante a DECLARAO de uma VARIVEL:

auto - define variveis automticas na PILHA de EXECUO


so sempre variveis locais a um BLOCO e que so descartados na sada do BLOCO;

register - define variveis automticas em REGISTRADORES


so sempre variveis locais a um BLOCO e que so descartados na sada do BLOCO;

static
podem ser variveis locais a um BLOCO ou externas a todos os BLOCOS retm seus valores durante toda execuo do programa pois so alocadas na REA de DADOS ESTTICA quando em DECLARAES LOCAIS, DEFINE variveis estticas (escopo de BLOCO) quando em DECLARAES GLOBAIS, DEFINE variveis estticas com ligao interna (escopo de UNIDADE DE COMPILAO)

extern
podem ser variveis locais a um BLOCO ou externas a todos os BLOCOS quando em DECLARAES LOCAIS, DECLARA variveis estticas que foram definidas fora do BLOCO das declaraes quando em DECLARAES GLOBAIS, DECLARA variveis estticas com ligao externa, i.e, que foram definidas fora da UNIDADE DE COMPILAO das declaraes

Observao um BLOCO qualquer parte de um programa delimitada por { } ; um BLOCO pode ser o corpo de funo bem como o corpo

16 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

de um comando composto como if, while, etc.

A seguir ilustram-se a utilizao de Variveis auto, register e static LOCAIS. Variveis static GLOBAIS e variveis

extern sero discutidas em aulas futuras.

Atividade 1: Variveis auto e register


Para ilustrar o uso de auto e register, compile e execute o programa abaixo.

/* teste_fat.c ( rev 1.1 ) **/ /* funo fat: calcula fatorial de x **/ unsigned long fat(unsigned short x) { register int i; /* acesso o mais rpido possvel; se no possvel em pilha */ unsigned long ret; /* alocada na pilha; se possvel acesso o mais rpido possve ret = 1; for ( i = 1; i <= x; i++ ) ret = ret * i; return ret; } /* funo main: testa a funo fat acima **/ int main() { auto int i;

/* alocada na pilha */

for( i = 0; i < 20; i++ ) printf("fat(%i) = %lu \n",i,fat(i)); }

A Fazer - No programa acima: declare uma VARIVEL GLOBAL especificando auto como CLASSE de ARMAZENAMENTO, compile e observe as mensagens geradas pelo compilador; declare uma VARIVEL GLOBAL especificando register como CLASSE de ARMAZENAMENTO, compile e observe as mensagens geradas pelo compilador;

Que concluses podemos tirar sobre o uso de auto e register em DECLARAES GLOBAIS?

Atividade 2: Variveis static em DECLARAES LOCAIS


Para ilustrar o uso dos ESPECIFICADORES static em DECLARAES LOCAIS podemos refatorar o programa anterior da seguinte maneira: para n > 12, fat(n) estoura a representao unsigned long int assim, uma primeira medida deve ser barrar o clculo de fat(n) para n> 12 dado que o nmero de valores possveis pequeno, uma segunda idia armazenar os valores j calcular para evitar repetir clculos em chamadas futuras.

17 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* teste_fat.c **/

(rev 1.2)

/* funo fat: para x <=12, calcula fatorial de x para x > 12, retorna 0 **/ unsigned long fat(unsigned short x) { register int i; static unsigned long ret[13]; if ( x > 12 ) return 0; if ( ret[x] != 0 ) return ret[x]; ret[x] = 1; for ( i = 1; i <= x; i++ ) ret[x] = ret[x] * i; return ret[x]; } /* funo main: testa a funo fat acima **/ int main() { int i; for( i = 0; i < 20; i++ ) printf("fat(%i) = %lu \n",i,fat(i)); }

Em DECLARAES LOCAIS, o especificador static usado para indicar uma varivel que DECLARADA LOCALmente mas que ir residir na rea de VARIVEIS GLOBAIS. H duas conseqncias: por se tratar de uma declarao local, a varivel s visvel no BLOCO onde foi declarada por exemplo, a varivel static unsigned long ret[12] s visvel dentro da funo fat por residir na rea de variveis globais, a varivel reter seu valor entre ativaes sucessivas do BLOCO onde foi declarada por exemplo, a varivel static unsigned long ret[12] retm seus valores mesmo quando a funo fat no est executando. Assim, na primeira vez que se chama fat(5), o valor correspondente calculado e armazenado em ret[5]. Em uma segunda chamada fat(5), ao invs de se realizar o mesmo clculo novamente, o valor recuperado de ret[5]. Em outras palavras, a funo passa a "lembrar" clculos anteriores!

A Fazer - No programa acima: na DECLARAO da varivel ret, elimine o ESPECIFICADOR static, compile, execute o programa e verifique o funcionamento do programa. Explique a sada gerada!

Leitura Recomendada
CCT captulo 2 K&R captulos 2 e 4

18 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Franek, Frantisek (2003) "Memory as a Programming Concept in C and C+ + ." Cambridge University Press.

Exerccios
Conside o seguinte programa

int i; void g() { static int j; j = i; i = i * 2; printf("g(){ i = %d }

j = %d }\n",i,j);

void f() { i = 2; g(); printf("f() { i = %d }\n",i); } int main() { int i; i = 3; f(); g(); printf("main() { i = %d }\n",i); return 0; }
Qual a sada gerada na tela quando o programa executado? Descreva passo a passo como o ambiente de execuo (rea esttica de dados + pilha de execuo) evolui durante a execuo do programa. Utilizando variveis auto e register, escreva programas para calcular: exponenciao inteira, i.e, a ^ b, onde b um nmero inteiro. raiz quadrada de x, utilizando o mtodo de newton ( onde r(x) representa a raiz de x)

cosseno, utilizando a srie

utilize a funo fat() desenvolvida na atividade 2 veja como exemplo o Programa seno discutido em sala de aula

Declaraes: Tipo de Acesso, I nicializao e Constantes


lrc , 29 March 2008 (created 28 March 2008)
no tags

Objetivo
Nas ltimas aulas, estudamos a forma geral de uma DECLARAO de VARIVEIS ( global ou local ):

19 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

ESPEC-DECLARAO DECLARADOR-1 = INICIALIZADOR-1, ..., DECLARADOR-n = INCIALIZADOR-n;


Recapitulando, o ESPEC-DECLARAO uma seqncia composta de: OBRIGATORIAMENTE, um ESPECIFICADOR de TIPO de DADO ( acompanhado ou no de MODIFICADORES )

char signed e unsigned int signed e unsigned long e short float, double e long double
OPCIONALMENTE, um ESPECIFICADOR da CLASSE de MEMRIA

auto register static extern


cada DECLARADOR-i (em sua forma mais simples) consiste em um IDENTIFICADOR cada = INICIALIZADOR-i OPCIONAL e (em sua forma mais simples) consiste em uma CONSTANTE

Na aula de HOJE, nosso objetivo tornar este quadro mais completo apresentando um terceiro e ltimo tipo de ESPECIFICADOR que pode ser utilizado em declaraes: ESPECIFICADOR de TIPO de ACESSO const e volatile Alm disso, discutiremos as regras gerais do processo de INICIALIZAO de VARIVEIS e ao final apresentaremos a forma das CONSTANTES associadas aos tipos bsicos de dados em C.

ESPECIFICADOR de TIPO de ACESSO


Em uma declarao de variveis (globais ou locais), um ESPECIFICADOR de TIPO de ACESSO pode ser utilizado para estabelecer a maneira como as variveis podem ser acessadas ou modificadas. Em C, h duas PALAVRAS RESERVADAS que funcionam como ESPECIFICADORES de TIPO de ACESSO durante uma declarao de variveis:

const volatile

const variveis declaradas const podem ser inicializadas mas no modificadas usar const til quando vc. quer ter certeza que (parte do) seu cdigo no ir alterar valores de certas variveis; uma situao tpica na declarao de CONSTANTES SIMBLICAS, como em:

const double PI = 3.1415927;


Uma outra situao quando vc. passa um argumento a uma funo atravs de um parmetro e deseja que o valor do argumento no seja em hiptese alguma modificado pelo cdigo da funo ... Mais detalhes somente em aulas futuras ...

volatile este ESPECIFICADOR indica que a varivel pode sofrer modificaes de maneira no especificada pelo programa. Em outras palavras, uma varivel volatile pode ter seu contedo alterado (via apontadores e endereos) por comandos que fazem parte de outros programas. Na prtica, volatile indica ao compilador para no realizar otimizao de EXPRESSES contendo tais variveis.

Observao

20 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Os ESPECIFICADORES const e volatile podem ser utilizados juntos! Exemplo:

const volatile

unsigned short int

port = 80;

Neste exemplo, a varivel port no pode ser modificado pelo programa sendo escrito mas pode ter seu valor modificado por comandos externos ao programa!

Atividade 1: Variveis const


Teste o cdigo abaixo e observe o Erro de Compilao !

const int x = 100; int main() { x = x + 1; }

/* Isto ir gerar um erro de compilao */

Inicializao de Variveis
Inicializar uma varivel significa dar varivel um valor, no mesmo momento em que ela declarada. De maneira geral, o valor inicial de uma varivel pode ser o resultado de uma EXPRESSO envolvendo dentre outros CONSTANTES, OPERADORES e outras VARIVEIS. Regras de I nicializao Variveis GLOBAIS e variveis LOCAIS static declaradas COM =INICIALIZADOR so inicializadas com o valor de

INICIALIZADOR apenas uma vez no comeo do programa Variveis GLOBAIS e variveis LOCAIS static declaradas SEM =INICIALIZADOR so inicializadas com ZERO apenas
uma vez no comeo do programa Variveis LOCAIS auto e register declaradas COM =INICIALIZADOR so inicializadas com o valor de

INICIALIZADOR toda vez que o BLOCO no qual foram declaradas for ativado Variveis LOCAIS auto e register declaradas SEM =INICIALIZADOR tm valor DESCONHECIDO antes de ser
efetuada uma primeira atribuio a elas Apenas DECLARAES que so DEFINIES podem conter =INICIALIZADOR. Assim, variveis declaradas extern no podem ser inicializadas no momento de suas declaraes!

Atividade 2 : Inicializao de Variveis


Compile, execute e compare a sada do programa abaixo com o que foi dito acima sobre inicializao de variveis:

21 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> int Gi = 3, G_; void f(); /* variveis GLOBAIS */

/* DEClARAAO de f() */

void g() { /*DECLARACAO/DEFINICAO de g() */ char ga_; printf("\n. g():\n"); printf(" ga_ = %i\n", ga_); printf("\n > para terminar digite 't' < "); scanf(" %c",&ga_); if (ga_ != 't' ) f(); /* ativa funo f() */ printf("\n# g():\n"); } void f() { /* DEFINICAO de f() */ static int fsi = 3, fs_; int fai = 3, fa_; printf("\n. printf(" printf(" printf(" printf(" fsi fs_ fai fa_ ++; ++; ++; ++; Aps incremento:\n\n"); fsi = %i\n", fsi); fs_ = %i\n", fs_); fai = %i\n", fai); fa_ = %i\n", fa_); f():\n"); fsi = %i\n", fs_ = %i\n", fai = %i\n", fa_ = %i\n",

fsi); fs_); fai); fa_);

printf("\n printf(" printf(" printf(" printf(" g();

/* ativa funo g() */

printf("\n# f():\n"); } int main () { int m_; printf("\n. printf(" printf(" printf(" f(); main()\n"); Gi = %i\n",Gi); G_ = %i\n",G_); m_ = %i\n",m_);

/* Ativa funo f() */

printf("\n# main()\n"); }

22 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Constantes
Um dos elementos principais na INICIALIZAO de VARIVEIS (e de EXPRESSES em geral) so as constantes. Constantes so VALORES ESPECFICOS de qualquer um dos TIPOS de DADOS bsicos.

Observaes Nas constantes caracter e string, alm dos caracteres comuns, caracteres de controle (no imprimveis) so escritos atravs de um 'cdigo de barra invertida' (veja tabela abaixo) No confunda constantes caracter com string! Uma constante de um nico caracter colocada entre aspas simples; constantes string so colocadas entre aspas duplas. Ou seja, 'a' (constante char) diferente de "a" (constante string)

23 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Leitura Recomendada
CCT captulo 2 K&R captulos 2 e 4

Exerccios
1. Considere o programa da atividade 2. Descreva passo a passo como o ambiente de execuo (rea esttica de dados + pilha de execuo) evolui durante a execuo do programa. Na sua descrio localize onde so alocadas as variveis do programa. 2. Explique qual a diferena entre '0', '\ 0', "0" . 3. A matemtica e a fsica repleta de exemplos de constantes fundamentais. Utilizando variveis decladas com o ESPECIFICADOR const, mostre como voc representaria as seguintes constantes abaixo: razo urea ( ); nmero de Euler (e); velocidade da luz no vcuo (c); massa do eltron em repouso (me); nmero de Avogadro (L); 4. Escreva um programa que converta nmeros de decimais para hexadecimal e octal. Dica: uma maneira simples de fazer o programa ler os nmeros em decimal e os imprimir na tela como constantes inteiras escritas em hexadecimal e octal. Para saber como usar a funo printf para imprimir inteiros em hexadecimal e octal cosulte os livros ou a internet. Veja por exemplo, a pgina abaixo: http:/ / www.dca.fee.unicamp.br/ cursos/ EA876/ apostila/ HTML/ node131.html 5. O programa abaixo, quando compilado, gera uma mensagem de erro. a. Que mensagem de erro essa? b. Como o programa pode ser corrigido para eliminar a mensagem de erro? c. Aps o programa ter sido corrigido e compilado com sucesso, que valores sero impressos na tela ?

24 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Operadores e Expresses: atribuies, aritmtica e lgica


lrc , 9 April 2008 (created 29 March 2008)
no tags

Objetivo
Na aula de HOJE iremos dar incio ao estudo dos OPERADORES da linguagem C. Os OPERADORES, em conjunto com CONSTANTES e VARIVEIS, so os constituintes bsicos de EXPRESSES. Sero detalhados os operadores utilizadoes em expresses: de atribuio aritmtica e lgica

Operadores
Em C, podemos classificar os OPERADORES em cinco grande categorias: Atribuies Aritmticos Lgicos e Relacionais Bit-a-Bit Especiais

Atribuies
Forma geral:

VARIVEL

= EXPRESSO;

25 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atribuies mltiplas:

VAR1 = VAR2 = .... = VARn = EXPRESSO;

C Reduzido: (para todo operador op binrio)

VAR = VAR op EXPRESSO;


equivalente a:

VAR OP= EXPRESSO;

Operadores Aritmticos

Obs.: operadores com o mesmo nvel de PRECEDNCIA so avaliados pelo compilador da ESQUERDA PARA a DIREITA

Exemplo 1
Em :

int a = 3; int b = 2; int c = a + -b * 3 / 2 + a % 3 * 4;

26 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Quanto vale a VAR c? Resposta: operadores de maior precedncia so avaliados primeiro operadores de mesma precedncia so associados da esquerda para a direita ento, a expresso acima seria avaliada assim:

int c = ((a + (((-b)*3)/2)) + ((a%3)*4));

Exemplo 2
Quanto valem i e j abaixo, aps cada atribuio???

int i , j = 2; i = j++; i = -- j; i = --j++;


Resposta:

i = j++; i = -- j; i = --j++;

/* i == 2, j == 3; primeiro armazena o valor de j em i, depois increm /* i == 2, j == 2; primeiro decrementa j, depois armazena o valor de /* expresso invlida */

A ltima expresso invlida pois incremento e decremento DEVEM sempre operar sobre variveis e no sobre expresses!

Exemplo 3
Em :

int c = 3; c = c-- + c;
Quanto vale a VAR c? Resposta: Ateno: O uso de operadores de incremento ( ++) e decremento ( --) em EXPRESSES frequentemente AMBGUO! Evite-o SEMPRE!!! Assim, dependendo da ordem em que o compilador avalia as sub-expresses entre o operador + podemos ter resultados diversos para o valor da varivel c!

Exemplo 4
Veja esse exemplo retirado de um livro:

Quando eu rodo o exemplo acima no meu computador o resultado result == 8 !!! J o livro diz: Avaliando da esquerda para a direita:

27 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Avaliando da direita para a esquerda:

Operadores Lgicos e Relacionais

28 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atividade 1: operadores lgicos implica e ouexcl


Em C, os operadores &&, || e ! correspondem respectivamente aos conectivos E, OU e NO da lgica Booleana. Na lgica booleana, alm destes conectivos, existem vrios outros. Por exemplo: IMPLICAO

A B A -> B ----------------0 0 1 0 1 1 1 0 0 1 1 1
OU EXCLUSIVO

A B A OUEXCL B ----------------0 0 0 0 1 1 1 0 1 1 1 0

Nesta atividade, implemente estes dois operadores como duas funes em C!

int implica(int a, int b) { ... } int ouexcl(int a, int b) { ... }

29 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Aps criar as funes acima, teste-as por meio da funo main abaixo:

int main() { printf("teste printf("%i -> printf("%i -> printf("%i -> printf("%i ->

implica:\n" %i = %i\n", %i = %i\n", %i = %i\n", %i = %i\n",

1, 3, 0, 0,

7, 0, 1, 0,

implica(1,7)); implica(3,0)); implica(0,1)); implica(0,0));

printf("teste ouexcl:\n" printf("%i xor %i = %i\n", printf("%i xor %i = %i\n", printf("%i xor %i = %i\n", printf("%i xor %i = %i\n", }

3, 1, 0, 0,

4, 0, 5, 0,

ouexcl(3,4)); ouexcl(1,0)); ouexcl(0,5)); ouexcl(0,0));

Leituras Recomendadas
CCT captulo 2 K&R captulos 2 http:/ / pt.wikipedia.org/ wiki/ Operadores_em_C_e_C% 2B% 2B http:/ / www.mspc.eng.br/ info/ cpp_oper_10.shtml

Exerccios
1. Diga a ordem de clculo e o resultado das expresses constantes abaixo: a. x = 5 * 4 / 6 + 7 ; b. x = 5 * 4.0 / 6 + 7 ; c. x = 5 * 4 % 6 + 7 ; d. x = ((4 / 2) + (3.0 * 5)) ; e. x = 3 + 2* 4% 3/ 2 1 ; f. x = 3 > = 2 && ! 2 | | 0 ; g. x = 2 && 0 | | 1 ; 2. Escreva um programa que imprima a tabela verdade da funcao ou exclusivo. 3. Escreva um programa que leia um ngulo em segundos e imprima quantos graus, minutos e segundos h neste ngulo. 4. Escreva um programa que leia um tempo em segundos e imprima quantas horas, minutos e segundos h neste tempo. 5. Escreva um programa que leia um comprimento em centmetros e imprima quantos metros, decmetros e centmetros h neste comprimento.

Operadores e Expresses: bit-a-bit e especiais


lrc , 10 April 2008 (created 31 March 2008)
no tags

Objetivos
Em C, OPERADORES e EXPRESSES podem ser classificados em cinco grande categorias: Atribuies Aritmticos Lgicos e Relacionais Bit-a-Bit Especiais Na ltima aula, disticutimos as trs primeiras categorias acima. HOJE, iremos dar prosseguimento ao estudo apresentado os OPERADORES e EXPRESSES:

30 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Bit-a-Bit Especiais Ao final, concluiremos o assunto mostrando um quadro que resume e compara os OPERADORES da linguagem C por ordem de precedncia e associatividade.

Manipulao de Bits
OPERADORES e EXPRESSES de manipulao de bits ( bit-a-bit ) referem-se a testar, atribuir ou deslocar os bits efetivos em um byte ou palavra que correspondem aos tipos bsicos char, int e variantes. OBS.: Operaes bit-a-bit no podem ser feitas sobre float, double, long double, void ou outros tipos mais complexos.

Significados: Os operadores &, | e ~ tm a mesma tabela verdade que &&, || e ! (respectivamente), com a diferena que operam sobre os bits individuais da representao de dois nmeros (ou apenas um, no caso de ~) e no sobre expresses numricas. o operador ^ tem a mesma tabela verdade que a funo xor() discutida na aula passada (novamente operando sobre bits individuais e no sobre expresses numricas). o operador >> desloca os bits de um nmero k casas para esquerda fazendo com que os k bits mais esquerda se percam e os k bits mais direita sejam '0' o operador << desloca os bits de um nmero k casas para direita fazendo com que os k bits mais direita se percam e os k bits mais esquerda sejam '0' Exemplo 1 ( << e >>): Considere:

unsigned int

x = 7;

Se pudssemos olhar a representao do valor 7 (decimal) 'dentro' da varivel x, veramos os seguinte padro de bits: x =

0...00000111 ( a quantidade total de bits depende de quantos bytes so utilizados para armazenar um unsigned int, quantidade que depende da mquina alvo e compilador ).
A EXPRESSO abaixo (deslocamento esquerda):

x = x << 2;
faz com que o padro de bits representando o valor inicial 7 se transforme em x = 0...00011100. Quer dizer, os bits, todos foram deslocados para a esquerda dois bits! Assim, o valor agora reresentado na varivel x 28 ! De maneira geral, se uma varivel tem o seguinte padro de bits: x = | bn-1 | bn-2 | ... | b2 | b1 | b0 | onde: a varivel representada por n bits cada um dos bi (para 0 i n-1 ) denota um bit com valor '0' ou '1' ento:

x << k, resulta em:


x = | bn-k-1 | bn-k-2 | ... | b2 | b1 | b0 | 0 | 0 | .. | 0 | 0 | 0 | onde a seq. final de '0's contm k '0's

31 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

x >> k, resulta em:


x = | 0 | 0 | ... | 0 | 0 | 0 | bn-1 | bn-2 | ... | bk-1 | bk | onde a seq. inicial de '0's contm k '0's

Exemplo 2 ( ~): Continuando o exemplo anterior, tem-se x = 0...00011100. A EXPRESSO abaixo ( complemento de 1 ):

x = ~ x;
tem o seguinte efeito na representao de x em binrio: x = 1...11100011 . Ou seja, os bits que so '0' passam a ser '1', os que so '1' tornam-se '0'. Exemplo 3 ( |): Continuando o exemplo anterior, tem-se x = 1...11100011. A EXPRESSO abaixo ( OR ):

x =

x | 8 ;

transforma x em : x = 1...11101011 . Quer dizer, muda o quarto bit (da direita para a esquerda) de '0' para '1'. Isto acontece por que:

x 4

= 1...11100011 = 0...00001000 -------------x | 4 = 1...11101011

/* OU bit a bit */

| frequentemente utilizado para LIGAR bits particulares

Exemplo 4 ( &): Continuando o exemplo anterior, tem-se x = 1...11101011. A EXPRESSO abaixo ( AND ):

x =

x & 0xf...f7 ;

transforma x em : x = 1...11100011 . Quer dizer, muda o quarto bit (da direita para a esquerda) de '1' para '0'. Isto acontece por que:

x 0xf...f7

= 1...11101011 = 1...11110111 -------------x | 0xf...f7 = 1...11100011

/* AND bit a bit */

& frequentemente utilizado para DESLIGAR bits particulares


Aplicaes Tpicas: rotinas de SO, drivers de dispositivos criptografia compactao de dados

Atividade 1
Tendo em vista os significados de | e & que so, respectivamente, similares aos de || e &&, descreva - atravs de um exemplo - o significado de ^ que similar funo xor() descrita na ltima aula.

Atividade 2

32 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Uma tabela binria uma tabela (matriz linhas x colunas ) onde cada clula armazena um dentre dois valores possveis. Por exemplo, a Freqncia deste curso em essncia uma tabela binria uma vez que cada clula s pode conter ou '0' (presente) ou '2' (ausente). Uma maneira simples de representar uma tabela binria atravs da seguinte estrutura:

char tabela1[40][10];
Nesta representao so gastos : 40* 10 = 400 bytes ( sizeof char = 1 byte ). Uma maneira mais eficiente (do ponto de vista da quantidade de memria utilizada) seria utilizar um mapa de bits para armazenar a tabela binria. Tal mapa de bits uma sequencia de bits mantidas pelos operadores bit a bit. Para a tabela acima de 40 linhas por 10 colunas poderamos ter a seguinte declarao:

char tabela2[ (40*10) / 8 ];


Nesta representao so gastos : (40* 10)/ 8 = 50 bytes. A idia aqui , ao invs de usar um char (1 byte) para armazenar 0 ou 1, usar um bit individual dentro de um char. Vejamos como isto pode ser feito. Atribuindo valor a uma determinada clula ( linha,coluna) Na primeira representao acima, uma dada clula pode ter seu valor modificado da seguinte maneira:

tabela1 [3][5] = 0; tabela1 [7][5] = 2;

/* aluno 3 esteve presente */ /* aluno 7 faltou */

Na segunda representao acima, o mesmo processo tem de ser simulado atravs de uma funo:

void set(unsigned x, unsigned y, int val) { unsigned pos = ( x* 10 + y ) / 8; unsigned des = ( x* 10 + y ) % 8; if (val) tabela2[pos] |= ( 1 << des ); else tabela2[pos] &= ~( 1 << des ); }

Recuperado o valor em uma determinada clula ( linha,coluna) A consultar do valor em uma dada clula feita de maneira direta para a primeira representao (utilizado ndices linha e coluna). J para a segunda representao devemos fazer uma funo de consulta.

/* retorna 0 se na pos x,y est armazenado 0 retona 1 se na pos x,y est armazenado 1 **/ int get(unsigned x, unsigned y) { ... }
Como exerccio, escreva a funo de consulta get().

Operadores Especiais
Operador Condicional ? : Operador sizeof Operadores de Converso de Tipo ou Casting (tipo) Operador Vrgula , Operadores () e []

33 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Sero vistos em mais detalhes em aulas futuras: Operadores de ponteiros * e & Operadores de estruturas . e ->

Operador Condicional
Uso

? :

EXP1 ? EXP2 : EXP3;


Significado EXP1 avaliada ... Se ela for verdadeira, ento EXP2 avaliada e se torna o valor da expresso como um todo. ... Se EXP1 for falsa, ento EXP3 avaliada e se torna o valor da expresso como um todo. Por exemplo, o comando condicional da funo set() da atividade 2 poderia ser reescrito assim:

tabela2[ pos ]

val tabela2[pos] | tabela2[pos] &

(1 << des) ~ (1 << des)

? : ;

b) Operador sizeof
Uso

sizeof sizeof

ID-VAR; (ESP-TIPO);

Significado sizeof um operador unrio em tempo de compilao que retorna o tamanho, em BYTES, de uma varivel ou de um especificador de tipo de dados, este ltimo escrito entre parnteses. Por exemplo, para tornar o cdigo da funo set() da atividade 2 mais PORTVEL, podemos fazer:

char tabela2 [ (40*10) / ((sizeof char)*8) + 1 ]; void set(unsigned x, unsigned y, int val) { unsigned pos = ( x* 10 + y ) / ((sizeof char)*8); unsigned des = ( x* 10 + y ) % ((sizeof char)*8); ... }

c) Converso Explcita de tipos (casting)


Uso

(ESPECIFICADOR-DE-TIPO) EXPRESSO;
Significado Fora - explicitamente - uma EXPRESSO a ser de um determinado tipo dado por ESPECIFICADOR-DE-TIPO. Por exemplo, para deixar claro que em:

tabela2 |= ( 1 << des);


o valor 1 se trata de um char ( 1 byte ) podemos fazer de forma explcita:

tabela2 |= (

((char) 1)

<< des );

34 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Alm de converses explcitas, o compilador realiza algumas converses implcitas ... Converses Automticas

Exemplo:

d) Operador vgula ,
Uso

EXP1, EXP2;
Significado O operador vgula usado para encadear diversas expresses. O lado esquerdo (EXP1) sempre avaliado como void. Assim, a expresso do lado direito (EXP2) torna-se o valor de toda a expresso separada por vrgula. Por exemplo:

int x,y; x = ( y = 3, y+1 );


primeiro o valor 3 atribudo a y e, em seguida, o valor 4 atribudo a x. Os parnteses so necessrios porque o operador vrgula tem a menor precedncia de todos os operadores de C.

35 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Um outro exemplo :

int i,x; for ( i = 0 , x = 1; ... } i < 10; i++ , x+=2) {

e) Operadores () e []
Parnteses () so operadores que aumentam a precedncia das operaes dentro deles. Colchetes [] realizam indexao de vetores e matrizes.

Quadro Geral de Operadores em C


A tabela 2.8 lista a precedncia de todos os operadores de C. Note que todos os operadores, exceto os operadores unrios e o ?, associam da esquerda para a direita. Os operadores unrios ( *, ! e ~) e o ternrio ? associam da direita para a esquerda.

Ordem de Avaliao
O padro C ANSI (C89) no estipula que as subexpresses de uma expresso devam ser avaliadas e uma ordem especfica. Assim, seu cdigo nunca deve contar com a ordem em que as subexpresses so avaliadas. Por exemplo, a expresso:

x =

f() + g();

no garante que f() ser chamada antes de g()!

Leituras Recomendadas
CCT captulo 2 K&R captulos 2 http:/ / pt.wikipedia.org/ wiki/ Operadores_em_C_e_C% 2B% 2B http:/ / www.mspc.eng.br/ info/ cpp_oper_10.shtml

Exerccios
1. Realize por completo a atividade 1 2. Realize por completo a atividade 2, escrevendo a funo get() e testando as funes set() e get() em um programa que l do usrio posies x e y, liga os bits nestas posies e ao final imprime a tabela completa. 3. Observe o padro abaixo:

36 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

( (0000 0001) 2 << 1 ) ( (0000 0010) 2 << 1 ) ( (0000 0100) 2 << 1 ) ( (0000 1000) 2 << 1 ) ( (0001 0000) 2 << 1 )

(0000 0010) 2 = 2 (0000 0100) 2 = 4 (0000 1000) 2 = 8 (0001 0000) 2 = 16 (0010 0000) 2 = 32

... a. desse padro, o que se pode concluir com relao operao de deslocamento esquerda? b. e com relao operao de deslocamento direita? c. em termos numricos o que significa x << k ? Quer dizer, se x vale 5 quanto ir valer x << k ? d. em termos numricos o que significa x >> k ? Quer dizer, se x vale 35 quanto ir valer x >> k ? 4. Para o programa abaixo, descreva como ele funciona e qual a sada gerada aps a sua execuo.

#include <stdio.h> int g(float a, float b) { static float f; return f += a > b ? a / b : b / a , (int) f; } int main() { printf("%i\n", g(7,2)); printf("%i\n", g(2,3)); }

Controle de Fluxo: Comandos de Seleo


lrc , 1 April 2008 (created 1 April 2008)
no tags

Objetivos
Nesta aula, iremos iniciar o estudo dos comandos e construo em C para o CONTROLE do FLUXO de EXECUO de um programa. Especificamente, abordaremos os comandos para realizao de DESVIOS CONDICIONAIS:

if ... else ... switch ... case ...


tambm conhecidos como COMANDOS DE SELEO.

Controle de Fluxo
Em C, bem como em toda linguagem moldada sob os princpios da PROGRAMAO ESTRUTURADA, o fluxo de execuo de um programa controlado de acordo com algumas idas simples e fundamentais: SEQNCIA e BLOCOS de comandos DESVIOS CONDICIONAIS INCONDICIONAIS ITERAES (LAOS)

Seqncia e Blocos de Comandos


Uma SEQNCIA de COMANDOS uma lista de COMANDOS delimitados por ; . Um BLOCO de COMANDOS qualquer SEQNCIA de COMANDOS delimitada por chaves {} .

37 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Em um BLOCO de COMANDOS, podem-se distinguir trs tipos bsicos de COMANDOS: 1. DECLARAO de VARIVEIS LOCAIS sempre no incio do BLOCO variveis declaradas dentro de um BLOCO podem ter o mesmo nome de uma outra varivel situada em um BLOCO mais externo; neste caso, a varivel dentro do BLOCO mais interno se sobrepe a varivel do BLOCO mais externo. 2. COMANDOS de EXPRESSO formados por uma expresso C vlida ATRIBUIES CHAMADAS de FUNO 3. COMANDOS de CONTROLE de FLUXO atuando sobre COMANDOS individuais ou ento outros BLOCOS de COMANDOS. DESVIOS CONDICIONAIS DESVIOS INCONDICIONAIS ITERAES

Por exemplo:

int f() { /* incio de BLOCO */ int a,b; /* DECLARAES LOCAIS */ a = 10; b = a % 3 ; /* comando de EXPRESSO /* comando de EXPRESSO */ */

if ( a > 2 ) /* comando de CONTROLE de FLUXO */ { /* incio de BLOCO */ int x,y; /* DECLARAES LOCAIS */ x = 2*a; /* comando de EXPRESSO */ for ( y =1; y < 10; y++ ) /* comando de CONTROLE de FLUXO */ x += y; /* comando de EXPRESSO */ ... } /* fim de BLOCO */ else printf("a menor que 2\n"); } /* fim de BLOCO */

/* comando de EXPRESSO */

Desvios Condicionais ( Comandos de SELEO )


Em C, h dois comandos para DESVIOS CONDICIONAIS:

if ... else switch ... case ... break ... default

O comando
Forma Geral

if ... else ...

if ( condio ) ao_se_no_zero else ao_se_zero


onde: tanto ao_se_no_zero quanto ao_se_zero podem ser: um nico comando de EXPRESSO ou um outro comando de CONTROLE de FLUXO ou um BLOCO de COMANDOS a parte else ao_se_zero opcional a condio deve ser uma EXPRESSO ESCALAR (ou seja, uma EXPRESSO que quando avaliada produza um inteiro, um

38 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

caracter ou ponto flutuante.)

Observao: em if ... else ... aninhados cada else se refere ao if mais prximo dentro do mesmo bloco.

O comando

switch ... case ... break ... default

Observaes: O comando switch s pode testar igualdade; j o comando if pode avaliar uma expresso lgica ou relacional; Duas constantes case no mesmo switch no podem ter valores idnticos; Constantes caracter so automaticamente convertidas para seus valores inteiros; Os comandos break dentro do switch so opcionais. Eles terminam a seqncia de comandos associados com cada constante. Se o comando break omitido, a execuo continua pelos prximos comandos case at que um break, ou o fim do switch, seja encontrado.

Atividade 1
Escreva um programa calculadora que leia dois nmeros double e em seguida realize uma dentre um conjunto de operaes disponveis. As operaes disponveis so: adio ( +) subtrao ( -) multiplicao ( *) diviso ( /) diviso inteira ( div) resto diviso inteira ( mod)

39 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

exponenciao inteira ( ^)

...

Leitura Recomendada
CCT captulo 3 K&R captulos 3

Exerccios
1. Complete as atividade 1 acima; 2. Extenda a atividade 1 para lidar com as operaes fat (fatorial), sen (seno), cos (coseno) e rq (raiz quadrada). Nestes casos, apenas um nmero deve ser lido.

Controle de Fluxo: Laos e Desvios I ncondicionais


lrc , 20 May 2008 (created 20 May 2008)
no tags

Laos
Em C, h trs comandos de ITERAO ou LAOS:

for while do ... while


Estes permitem que um conjunto de instrues seja executado at que ocorra uma certa condio. Esta condio pode ser pr-definida (como no lao for) ou com o final em aberto (como nos laos while e do ... while).

Lao for
FORMA GERAL

for( INICIALIZAO ;

CONDIO ; INCREMENTO )

COMANDO;

INICIALIZAO - geralmente um comando de atribuio para colocar um valor na varivel de controle do lao; CONDIO - uma expresso relacional que determina quando o lao acaba; INCREMENTO - define como a varivel de controle do lao varia cada vez que o lao repetido; COMANDO - um nico comando ou um bloco de comandos executados enquato a CONDIO verdadeira.
VARI AES 1. Operador Vgula - uma das variaes mais comuns o uso do operador vrgula para permitir que duas ou mais variveis controlem o lao:

for( x = 0 , y = 100 ; x < y ; x ++ , y -= x ) printf("x = %i, y = %i\n",x,y);

2. Lao infinito - Nenhuma das trs expresses que formam um lao for obrigatria. Assim, voc pode criar um lao infinito assim:

40 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

for ( ; ; ) printf(" Lao infinito \n");

3. Lao sem corpo - Um comando pode ser vazio. Isso significa que o corpo do lao for (ou qualquer outro lao) tambm pode ser vazio.

int pausa ( unsigned long int p) { for ( t = 0 ; t < p ; t++ ) ; }

Lao while
FORMA GERAL

while( CONDIO ) COMANDO; COMANDO executado enquanto a CONDIO for verdadeira ( diferente de zero ); quando for falsa, o controle passa para a linha aps COMANDO.
VARI AES 1. Lao infinito :

while ( 1 ) printf(" Lao infinito \n");

2. Lao sem corpo.

int pausa ( unsigned long int while ( p-- ) ; }

p) {

Lao do ... while


Ao contrrio dos laos for e while, que testam a condio do lao no comeo, o lao do ... while verifica a condio ao final do lao. Isso significa que um lao do ... while SEMPRE SER EXECUTADO AO MENOS UMA VEZ. FORMA GERAL

do

COMANDO; } while( CONDIO );

Embora as chaves no sejam necessrias quando apenas um comando est presente, elas so geralmente usadas para evitar confuso (para voc, no para o compilador) com o while. O lao do ... while repete at que a CONDIO se torne falsa.

41 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

VARI AES 1. Lao infinito :

do{ printf(" Lao infinito \n"); } while ( 1 )

2. Lao sem corpo.

int pausa ( unsigned long int do {} while ( p-- ); }

p) {

Desvios Incondicionais
return goto break continue

O comando

return

Este comando usado para retornar de uma funo. Ele um comando de desvio porque faz com que a execuo retorne (salte de volta) ao ponto em que a chamada funo foi feita. Se return tem um valor associado a ele, esse valor o valor de retorno da funo. Se nenhum valor de retorno especificado, assume-se que apenas lixo retornado (alguns compiladores iro automaticamente retornar 0 se nenhum valor for especificado, mas no conte com isso). FORMA GERAL

return

EXPRESSO;

O comando

goto

Na programao estruturada, no h nenhuma situao que necessite do goto. No entanto, o goto uma convenincia que, se usada com prudncia, pode ser uma vantagem em certas situaes. FORMA GERAL

goto ...

RTULO;

RTULO:

O comando goto requer um RTULO - um identificador vlido seguido por dois-pontos). O RTULO tem de estar na mesma funo do goto que o usa no permitido desvios entre funes.

O RTULO pode vir antes, e no apenas depois, do comando goto.

42 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

lao infinito

LOOP: printf("lao infinito\n"); goto LOOP;

O comando

break

O comando break tem dois usos. Voc pode us-lo para terminar um case em um comando switch (vide aula Controle de Fluxo: Comandos de Seleo). Voc pode tambm utiliz-lo para forar uma terminao imediata de um lao, evitando o teste condicional normal do lao. Quando o comando break encontrado dentro de um lao, o lao imediatamente terminado e o controle do programa retorna ao comando seguinte ao lao.

O comando

continue

O comando continue trabalha de uma forma pouco parecida com a do comando break. Porm, em vez de forar a terminao, continue fora que ocorra a prxima iterao do lao, pulando qualquer cdigo intermedirio. Para o lao for, o comando continue faz com que o incremento e o teste condicional sejam executados. Para os laos while e do ... while, o controle do programa passa para o teste condicional.

int conta_espacos(const char * str) { int i = 0, nesp = 0; while ( str[i] ) { if ( str[i] != ' ' ) continue; nesp ++; } return nesp; }

Leitura Recomendada
CCT captulo 3 K&R captulos 3

Funes: definio, declarao e chamada


lrc , 23 June 2008 (created 20 May 2008)
no tags

43 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Funes
Em C, um programa uma coleo de FUNES. Uma funo um bloco de cdigo que recebe um nome e que tem possivelmente PARMETROS. A partir do nome, o bloco de cdigo que forma a funo pode ser chamado. CHAMAR uma funo significa iniciar a execuo de um bloco de cdigo. Caso a funo possua parmetros, durante a CHAMADA dela devem ser indicados ARGUMENTOS que so valores ou variveis que iro corresponder aos parmetros da funo. Ao final da execuo, uma funo pode ainda retornar um valor para o cdigo que fez a chamada da funo.

Definio de Funo: Forma Geral


Uma funo deve ser definida conforme o esquema abaixo:

ESPEC-DECLARAO ID( DECL-ID-1, ..., DECL-ID-n ) CORPO_FUNO }

ID define o nome da funo. A lista de declaraes DECL-ID-1, ..., DECL-ID-n dita LISTA de PARMETROS da funo. Cada ID-i consiste em uma varivel com escopo local na funo e que ir receber, como valor inicial, o valor passado
como ARGUMENTO durante a chamada da funo. Se pensarmos no ID de uma funo como uma VARIVEL GLOBAL, os ESPEC-DECLARAO definem que caractersticas tem este ID: O tipo de dados ( void, int, char *, ... ) Classe de armazenamento ( static ou extern ) O tipo de acesso ( const ou volatile )

O CORPO_FUNO consiste em DECLARAES de VARIVEIS com escopo LOCAL seguidas de COMANDOS. Caso o tipo de dados constante nos ESPEC-DECLARAO seja diferente de void, deve haver ao menos um comando return ...; no CORPO_FUNO.

Definio de Funo: Formato Antigo


Por questes de compatibilidade, uma funo pode ainda ser definida seguindo o formato originalmente proposto pelos projetistas da linguagem. Neste formato original, o que muda a forma de se especificar os parmetros da funo:

ESPEC-DECLARAO ID( ID-1,...,ID-n ) DECL-ID-1; ...; DECL-ID-n; { CORPO_FUNO }

Declarao de Funes: Prottipos


O ideal que toda funo, antes de ser usada, deve ser declarada. Caso a funo encontra-se DEFINIDA no mesmo arquivo e em uma posio antes de seu uso, ento a prpria DEFINIO da funo serve como DECLARAO da funo. Caso contrrio, a DECLARAO da funo dever ser feita atravs de PROTTIPOS. Um prottipo como se fosse um CABEALHO para a funo, ou seja, o ID da funo os ESPEC do tipo retornado pelo funo e os ESPEC dos tipos de cada parmetro da funo:

ESPEC-DECLARAO

ID( ESPEC-DECL-1, ..., ESPEC-DECL-n );

Em uma situao onde uma funo f esteja sendo usada sem ter sido antes declarada, ento implicitamente o compilador declarada a funo como sendo:

44 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

int

f();

Um funo f() diferente de f(void) !


Um funo declarada como

int

f();

diferente de uma funo declarada como

int

f(void);

No primeiro caso, o compilador no sabe se a funo pode ou no receber argumentos durante a sua chamada. Quer dizer, perfeitamente vlido fazer:

int x = f(3.14); int y = f(2.7, 4); int z = f();

No segundo caso, o compilador informado explicitamente que a funo no deve receber nenhumar argumento. Assim, as duas primeiras linhas do cdigo acima gerariam uma mensagem de erro e apenas a ltima seria considerada como vlida.

Lista de Parmetros Varivel


Quando se quer especificar uma funo que possui uma lista de parmetros varivel em nmero e tipo, deve-se terminar a declarao dos parmetros utilizando trs pontos ... Por exemplo:

void f(int a, char * b, ... );

Qualquer funo que use um nmero varivel de parmetros deve ter ao menos um deles explicitamente declarado.

va_arg(), va_start() e va_end()

45 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Chamada de Funo
Chamar uma funo significa iniciar a execuo de seu corpo de cdigo. Caso a funo tenha sido declarada com PARAMETROS, durante a chamada deve ser passados ARGUMENTOS que correspondam em nmero e tipo com os PARAMETROS da funo. PARAMETROS so variveis locais funo que iro receber como valores iniciais os valores dos ARGUMENTOS utilizados na CHAMADA da funo.

OBS.: Em C, as chamadas de funo so feitas por VALOR. No entanto, o conceitos de chamada por referncia pode ser simulado em C atravs do uso de apontadores. Exemplo: CHAMADA por VALOR

46 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

unsigned modulo(int x) { x = x < 0 ? - x : x ; return x; } int main () { int a = - 2, ma = modulo(a); printf("| %d | = %d\n", }
Ao executar o programa acima, vc. ir perceber que o valor da varivel a no modificado pela funo mdulo. Ou seja, a varivel a e usada como ARGUMENTO em uma CHAMADA por VALOR de modulo(). Exemplo: simulando CHAMADA por REFERNCIA

a, ma);

unsigned modulo(int * x) { *x = *x < 0 ? - *x : *x ; return *x; } int main () { int a = - 2, ma = a; modulo(&ma); printf("| %d | = %d\n", a, ma); }

Chamadas de Funes com ARRANJOS


O ID de vetores, matrizes e strings so conceitualmente apontadores para o primeiro elemento do arranjo. Assim, ao se usar o nome de vetores, matrizes ou strings em uma chamada de funo est-se fazendo uma CHAMADA por REFERNCIA. Em outras palavras, vetores, matrizes ou strings quando passados como argumentos de funes e manipulados no interior dessas funes tm os seus valores modificados ao trmino da funo (vide tambm: Matrizes e Parmetros de Funes ). Para evitar que modificaes acidentais ocorram com vetores, matrizes e strings passados como argumentos de funes deve-se declar-los utilizando o qualificador const. Exemplos:

47 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* *str no deve ser modificado no interior de strlen */ int strlen(const char str[]) { int i; /* str[0] = 'a'; - qualquer tentativa de modificar o contedo da string apontada por str ir gerar uma mensagem de erro ! */

for(i =0; return i; } /* */

*str; i++, str++);

*str1 deve ser modificada no interior de strlen j, *str2 no

int strcpy(char * str1, const char * str2) { int i = 0; /* str2[0] = 'a'; - qualquer tentativa de modificar o contedo da string apontada por str2 ir gerar uma mensagem de erro ! */

do str1[i] = str2[i]; while ( str2[i++] ); return i - 1; }

Leituras Recomendadas
CCT cap 6 K&R

Exerccios
Obs.: Nos exerccios abaixo, escolha cinco e para estes mostre como as funes ficam quando definidas utilizando o formato antigo de definio de funes.

1. Em C, qual a diferena entre DECLARAO e DEFINIO de funes? 2. O que significam: a. passagem de argumentos por valor? b. passagem de argumentos por referncia? 3. Escreva uma funo que recebe um nmero inteiro n> 0 e devolve o nmero de dgitos de n e o primeiro dgito de n. 4. Escreva uma funo que recebe como parmetro um inteiro positivo ano e devolve 1 se ano for bissexto, 0 em caso contrrio. (Um ano bissexto se (ano % 4 = = 0 && (ano % 100 != 0 | | ano % 400 = = 0)).) 5. Escreva uma funo que tem como parmetros de entrada e sada trs nmeros inteiros, dia, mes e ano, representando uma data, e modifica esses inteiros de forma que eles representem o dia seguinte. 6. Escreva um programa que leia um inteiro positivo n e uma seqncia de n datas e imprime, para cada data, o dia seguinte. 7. Escreva uma funo de cabealho int divide (int *m, int *n, int d) que recebe trs inteiros positivos como parmetros e devolve 1 se d divide pelo menos um entre * m e * n, 0 caso contrrio. Fora isso, se d divide * m, divide * m por d, e o mesmo para o * n. 8. Escreva um programa que l dois inteiros positivos m e n e calcula, usando a funo acima, o mnimo mltiplo comum entre m e n, ou seja, mmc(m,n). 9. Escreva uma funo com prottipo void somabit (int b1, int b2, int *vaium, int *soma); que recebe trs bits (inteiros entre 0 e 1) b1, b2 e * vaium e devolve um bit soma representando a soma dos trs e o novo um bit "vai-um" em * vaium. 10. Escreva um programa que leia dois nmeros em binrio e calcula um nmero em binrio que a soma dos dois nmeros

48 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

dados. Utilize a funo acima. 11. Escreva uma funo com o prottipo void converte (char ch, int *tipo, char *valor); que recebe um caractere ch e devolve em * tipo 0, se o caractere for um nmero inteiro, 1 se for uma letra (maiscula ou minscula) e 2 caso contrrio; e alm disso, no caso de ser uma letra, converte para maiscula, seno devolve ch inalterado. Escreva um programa que leia uma seqncia de n caracteres e imprima a seqncia convertida para maiscula, eliminando os caracteres que no forem letras ou nmeros. Escreva uma funo que l, linha a linha, uma matriz real Amxn Escreva uma funo que imprime uma matriz real Amxn Escreva uma funo que calcula a soma dos elementos da linha i de uma matriz real Amxn. Escreva uma funo que calcula o produto dos elementos da coluna j de uma matriz real Amxn. Escreva uma funo que troca o contedo de duas variveis. Escreva uma funo que recebe dois inteiros, i e j, uma matriz real Amxne troca linha i pela linha j. Utilize a funo do item anterior. Um conjunto pode ser representado por um vetor da seguinte forma: V[ 0] o tamanho do conjunto; V[ 1] , V[ 2] , etc. so os elementos do conjunto (sem repeties). a. Faa uma funo chamada interseco que dados dois conjuntos de nmeros inteiros A e B, constri um terceiro conjunto C que a interseco de A e B. Lembre-se de que em C[ 0] a sua funo deve colocar o tamanho da interseco. b. Faa um programa que l um inteiro n > 1 e uma seqncia de n conjuntos de nmeros inteiros (cada um com no mximo 100 elementos) e constri e imprime um vetor INTER que representa a interseco dos n conjuntos. Por exemplo, se n= 3 e os conjuntos so { 1, 2, 4, 9} , { 2, 4, 7, 8, 9} e { 5, 4, 9} , a entrada ser:

12. 13. 14. 15. 16. 17. 18. 19.

O valor de n

4 V[0] = tamanho do primeiro conjunto 1 2 4 9 V[1] V[2] V[3] V[4] 5 V[0] = tamanho do segundo conjunto 2 4 7 8 9 V[1] V[2] V[3] V[4] V[5] 3 5 4 9 V[0] = tamanho do terceiro conjunto V[1] V[2] V[3]
E o vetor INTER construdo ser

INTER[0] = 2 INTER[1] = 4

tamanho do conjunto INTER[2] = 9 conjunto interseco

NOTE que no preciso ler todos os conjuntos de uma s vez. Voc pode ler os dois primeiros conjuntos e calcular a primeira interseco. Depois, leia o prximo conjunto e calcule uma nova inteseco entre esse conjunto lido e o conjunto da interseco anterior, e assim por diante. Use obrigatoriamente a funo do item anterior, mesmo que voc no a tenha feito.

Funes: main( ) e recurso


lrc , 20 May 2008 (created 20 May 2008)
no tags

A funo main()
O que main() devolve?
De acordo com o padro ANSI, a funo main() devolve um inteiro para o processo chamador, que , geralmente, o sistema operacional. Devolver um valor em main() equivalente a chamar exit() com o mesmo valor. Se main() no devolve explicitamente um valor, o valor passado para o processo chamador tecnicamente indefinido. Na prtica, a maioria dos compiladores C devolve 0, mas no conte sempre com isso! Pode-se tambm declarar main() como void. Alguns compiladores geram uma ADVERTENCIA, se a funo no declarada como void e tambm no devolve um valor.

49 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

argc e argv - argumentos para main()

int main ( int argc, char * argv[] ) { for( ; argc -- ; ) printf("arg[%d] = %s\n", argc, argv[argc]); }

Recurso
Em C, como virtualmente em todo linguagem de programao, funes podem chamar a si mesmas, direta ou indiretamente. Uma funo dita recursiva se em seu corpo a uma chamada (direta ou indireta) para si mesma. Recurso o processo de definir algo em termos de si mesmo e , algumas vezes, chamado de definio circular. Exemplos:

50 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdlib.h> #include <string.h> char * gnu(int n) { static char buf[1024]; if (n == 0) strcpy(buf,"GNU"); else { gnu(n-1); strcat(buf," Not Unix"); } return buf; } char * gnu2(int n) { static char buf[1024]; if (n == 0) return "GNU"; else { char aux[1024]; strcpy(aux,gnu2(n-1)); sprintf(buf,"(%s %s)",aux,"Not Unix"); } return buf; } int main(int argc, char * argv[]) { printf("%s\n", gnu(atoi(argv[1])) ); printf("%s\n", gnu2(atoi(argv[1])) ); }

OBSERVAES: Quando uma funo chama a si mesma, novos parmetros e variveis locais - quando estas no so static - so alocados na pilha e o cdigo da funo executado com essas novas variveis. No caso de variveis locais static, todas as chamadas recursivas compartilham a mesma varivel ! Quando cada chamada recursiva retorna, as variveis locais (no static) e os parmetros so removidos da pilha e a execuo recomea do ponto da chamada funo dentro da funo.

Ao escrever funes recursivas, voc deve ter um comando if em algum lugar para forar a funo a retornar sem que a chamada recursiva seja executada mais uma vez !

Atividade 1 - Torres de HANOI


Em 1883, o matematico francesEdouard Lucas inventou o famoso quebra-cabea das Torres de Hanoi, tambem conhecido por Torres de Brahma e contado em forma de lenda:

"No grande templo de Brahma em Benares, numa bandeja de metal sob a cpula que marca o centro do mundo,

51 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

trs agulhas de diamante servem de pilar a sessenta e quatro discos de ouro puro. Incansavelmente, os sacerdotes transferem os discos, um de cada vez, de agulha para agulha, obedecendo sempre lei imutvel de Brahma: Nenhum disco se podera sobrepor a um menor.

No in cio do mundo todos os sessenta e quatro discos de ouro, foram dispostos na primeira das trs agulhas, constituindo a Torre de Brahma. No momento em que o menor dos discos for colocado de tal modo que se forme uma vez mais a Torre de Brahma numa agulha diferente da inicial, tanto a torre como o templo sero transformados em p e o ribombar de um trovo assinalara o fim do mundo." [ http:/ / www2.mat.ua.pt/ rosalia/ cadeiras/ ADA/ THpaper.pdf]

Escreva um programa em C, que simule o trabalho dos sacerdotes conforme descrito acima! Na lenda, os sacerdotes movem 64 discos. No seu programa, trabalhe com n discos, onde n um nmero informado pelo usurio. Dica: usando recurso, o seu programa ficar bastante compacto.

int main(int c, char * v[]) { /* assuma que atoi(v[1]) o nmero n de discos a ser movido de um pilar para outro }

Atividade 2 - Combinaes
Quantos times de futebol diferentes podem ser feitos com uma turma de 26 alunos?! No segundo grau, voc DEVE ter aprendido que esta questo pode ser resolvida utilizando a frmula mgica de COMBINAES:

Sendo n= 26 e k= 11

26! / [11! (26 - 11)!] = 26*25*24*23*22*21*20*19*18*17*16 / 11*10*9*8*7*6*5*4*3*2*1 = 308403583488000/ 39916800 = 7726160

Bom, se voc for escrever um programa em C para calcular combinaes de n tomados k a k e utilizar a definio acima voc poder ter srios problemas de overflow! Repare que o nmero 308403583488000 quando escrito em binrio fica:

10

0011 000

0111 1101

1100 1110

0000 1010

1001 0000

0000 0000

Isto indica que so necessrio 7 bytes no mnimo para armazen-lo na memria do computador. Por outro lado, se observarmos o resultado final 7726160 que em binrio

111 0101

1110 0100

0101 0000

vemos que ele ocupa apenas 3 bytes! Em resumo, usando inteiros de 4bytes podemos armazenar o resultado final mas no poderemos armazenar resultados intermedirios como os acima apresentados! O que fazer? Vamos pensar um pouco: queremos formar times de 11 num universo de 26 alunos. Do ponto de vista de um aluno particular, os times a serem formados podem ser divididos em duas classes: os times nos quais o aluno participa e os times nos quais ele no participa. Os times nos quais um particular aluno participa so em nmero de COMB( 25, 10 ). Ou seja, o referido aluno mais dez dentre os 25 restantes. J os times nos quais o aluno no participa so em nmero de COMB( 25, 11 ). Ou seja, o aluno est excludo e so formados times de 11 dentre os 25 restantes. Este raciocnio pode ser repetido recursivamente agora para COMB( 25, 10 ) e COMB( 25, 11 ). O resultado final o seguinte

52 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

padro recursivo:

Agora, partindo da frmula acima podemos escrever um programa recursivo que calcular combinaes sem os problemas de overflow indicados acima quando usamos a definio tradicional de combinaes. Tal programa poderia usar a funo abaixo:

int comb(int n, int k) { if ( k > n ) return 0; if ( k == 0 || k == n ) return 1; else return comb(n-1,k-1) + comb(n-1,k); }

Resolvemos um problema mas tambm criamos um outro: o de tempo de execuo. Faa um teste. Tente calcular comb(36,11) usando a funo acima. Observe quanto tempo vai demorar para obter o resultado! O que fazer ento?! Na raiz do problema est o fato de que a funo recursiva proposta faz inumeras vezes o mesmo trabalho. Por exemplo: COMB(36,11) depende de COMB(35,10) e COMB(35,11). J COMB(35,11) depende de COMB(34,10) e COMB(34, 11); e, COMB(35,10) depende de COMB(34,9) e COMB(34,10). Observe que esta ltima combinao - COMB(34,10) - aparece em dois ramos distintos de recurso e por isso ir ser calculado duas vezes! Uma soluo para evitar este trabalho todo criar uma tabela para registrar clculos j feitos:

int comb(int n, int k) { static int tab[50][50]; if ( k > n ) return 0; if ( tab[n][k] == 0 ) { if ( k == 0 || k == n ) tab[n][k] = 1; else tab[n][k] = comb(n-1,k-1) + comb(n-1,k); } return tab[n][k]; }

Teste as funes apresentadas acima e verifique se realmente as idias discutidas fazem sentido.

Leitura Recomendada
CCT captulo 6

Exerccios
1. Complete a atividade 1

53 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

2. Na atividade 1, se cada disco pode ser movido de um lugar para outro em 1 nanosegundo (= 10-9 seg.), quanto tempo os monges iro levar para mover os 64 disco de uma torre para a outra? 3. Complete a atividade 2 4. Na atividade 2, qual os maiores k e n tais que comb(n,k) no estoure a representao baseada em int de 4 bytes? 5. Defina uma funo recursiva para determinar o maior divisor comum entre dois nmeros naturais x e y, baseando-se nas regras abaixo. Em seguida, napresente uma verso iterativa do algoritmo capaz de realizar a mesma tarefa. mdc(x,y) = x, se x = y mdc(x,y) = mdc(y,x), se x < y mdc(x.y) = mdc(x-y,y), se x > y 6. Escreva uma funo recursiva void fibo(int n); que gere os n primeiros termos da srie de Fibonacci. 7. Faa de conta que na linguagem C no existem operadores para adio, subtrao, multiplicao e nem diviso. Imagine que existam apenas os operadores de incremento ++N e decremento --N. Usando como base apenas estes dois operadores- ++ e -- (quer dizer, voc no deve usar os operadores +, -, * e /) -, defina funes recursivas para:

int int int int

soma(int subt(int mult(int divi(int

x,int x,int x,int x,int

y); - retorna soma x mais y; y); - retorna subtrao x menos y; y); - retorna multiplicao x vezes y; y); - retorna diviso inteira x dividido por y;

8. Defina uma rotina recursiva para, dado um natural n, imprimi-lo em base binria.

Vetores, matrizes e strings


lrc , 20 May 2008 (created 20 May 2008)
no tags

Introduo
Um ARRANJO ( VETOR, MATRIZ ou STRING) uma coleo de variveis do mesmo tipo que referenciada por um nome comum. Um elemento especfico em um ARRANJO acessado por meio de um NDICE. VETORES e STRINGS so ARRANJOS unidimensionais. Isto , necessita-se apenas um NDICE para acessar um elemento. MATRIZES so ARRANJOS multidimensionais. Ou seja, dois ou mais NDICES so necessrios para acessar um elemento de uma MATRIZ. Em C, ARRAJOS so armazenados em posies de memria contguas. O endereo mais baixo corresponde ao primeiro elemento e mais alto, ao ltimo elemento.

VETORES
Declarao ESPECIFICADORES ID[ TAMANHO ] = { LISTA_INICIALIZADORES } ; Onde os elementos em vermelho so opcionais. Obs.: indices comeam em 0 e vo at TAMANHO - 1 ID[ 0] - primeiro elemento ID[ 1] - segundo elemento ... ID[ TAMANHO - 1] - ultimo elemento no h verificao automtica se o acesso aos elementos ocorre dentro da faixa 0 .. TAMANHO -1; o programador tem de tomar esta tarefa para si!

MATRIZES
Declarao ESPECIFICADORES ID[ TAMANHO1 ] [ TAMANHO2] ... [ TAMANHOn] = { LISTA_INICIALIZADORES } ; Onde os elementos em vermelho so opcionais. Obs.: os indices de cada dimenso i comeam em 0 e vo at TAMANHOi - 1

54 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

ID[ 0] [ 0] ...[ 0] - primeiro elemento ... ID[ TAMANHO1 - 1] [ TAMANHO2 - 1] ... [ TAMANHOn -1] - ultimo elemento no h verificao automtica se o acesso aos elementos ocorre dentro da faixa 0 .. TAMANHOi -1; o programador tem de tomar esta tarefa para si!

STRINGS
Em C, strings so VETORES de caracteres terminadas pelo caracter '\ 0' (NULO). Declarao ESPECIFICADORES ID[ TAMANHO ] = { LISTA_INICIALIZADORES } ; ou ESPECIFICADORES ID[ TAMANHO ] = CONST_STRING;

Onde os elementos em vermelho so opcionais.

Obs.: Para armazenar um string com n caracteres no nulos voc deve reservar n+ 1 posies. Uma a mais para o caracter '\ 0' !

#include <string.h>

Leitura Recomendada
CCT cap4

Exerccios
1. Escreva um programa que leia uma linha de at 80 caracteres do teclado e imprima quantos caracteres foram lidos. 2. Escreva um programa que leia uma linha de caracteres do teclado e imprima quantas vezes um caracter, tambm fornecido pelo teclado, aparece nesta linha. O programa tambm deve imprimir em que posies o caracter foi encontrado.

55 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

3. Escreva um programa que leia uma linha do teclado e em seguida um par de caracteres. O programa deve procurar este par na linha e imprimir em que posies o par foi encontrado. 4. Escreva um programa que leia uma linha do teclado e imprima todas as vogais encontradas no texto e o total de vezes que elas aparecem. Obs: Tamanho maximo da linha deve ser 40 caracteres. 5. Oimperador romano Cesar usava um sistema simples para codificar as mensagens que enviava aos seus generais. Neste sistema cada letra era substituda por trs letras a frente no alfabeto. A sua misso mais simples ainda, escrever um programa que converta cada letra, e somente as letras, de uma mensagem de at 80 caracteres para a letra imediatamente posterior. Note que a letra 'z' deve ser convertida para a letra 'a', e a letra 'Z' para 'A'. 6. Escreva um programa que leia uma frase de 80 caracteres e a imprime retirando os espaos em branco. 7. Escreva um programa que leia uma linha do teclado de tamanho 80 caracteres. A linha somente contm letras. Divida a linha em blocos de 5 letras. Dentro de cada bloco o seu programa deve trocar a primeira letra pela seguinte, a segunda letra por duas letras adiante, a terceira por trs letras e assim at a quinta. Os espaos em branco devem ser retirados da frase. Considere o seguinte exemplo. Frase lida: EVA VIU A UVA Retirada dos espaos em branco: EVAVIUAUVA Diviso em blocos de 5 (Espaos em branco mostrados para facilitar entendimento): EVAVI UAUVA Criptografia: FYDAN VCYAF O que ser impresso: FYDANVCYAF 8. Escreva um programa que leia uma matriz de 3x3 que contm somente caracteres 0 e X e procure linhas que contenham somente um dos dois caracteres. O caracter a ser procurado deve ser lido do teclado. 9. Escreva um programa que leia uma linha de caracteres do teclado e converta o primeiro caracter de cada palavra para maisculas. Assuma que as palavras so sempre separadas por um branco. 10. Escreva um programa que leia para um vetor um conjunto de nmeros inteiros. Assuma que o conjunto de nmeros lidos menor que o tamanho do vetor. O programa deve inserir no vetor em uma posio especificada pelo usurio um nmero lido do teclado. Assuma que a posio especificada pelo usurio corresponde ao ndice do vetor. 11. Faa um programa que inverta uma string. O programa deve ler a string com gets e armazen-la invertida em outra string. Use o comando for para varrer a string at o seu final. 12. Faa um programa que leia duas matrizes 3x3 e imprima seu produto. 13. Escreva um programa que leia um conjunto de nomes para uma matriz e imprima estes nomes em ordem alfabtica. Assuma que os nomes sero lidos somente em letras maisculas. Assuma tambm que os nomes tm no mximo 40 caracteres e sero lidos 10 nomes ao todo.

Ponteiros
lrc , 20 May 2008 (created 20 May 2008)
no tags

Conceito
Um PONTEIRO ou APONTADOR uma varivel usada para armazenar um endereo de memria. Normalmente, o endereo armazenado em um PONTEIRO a posio de uma outra varivel na memria. Se uma varivel contm o endereo e uma outra, ento a primeira varivel dita apontar para a segunda.

Declarao

56 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

De maneira geral, uma varivel ponteiro de nome ID declarada assim:

ESPECIFICADORES

ID = INICIALIZADOR;

onde, o = INICIALIZADOR opcional (como em toda declarao de varivel).

Operadores de Ponteiros
Existem dois operadores especiais para ponteiros: o * e o &.

Operador &
Um operador unrio que devolve o endereo na memria do seu operando.

int int * p = &m; ...

m; p; /* p recebe o endereo onde se localiza a var. m */

Operador *
o complemento de &. Quer dizer, devolve a varivel localizada no endereo armazenado em um apontador.

p = &m; m = 3; printf("%p", p); printf("%d", *p); ... /* imprime o endereo de m */ /* imprime 3 que o contedo de m */

Ponteiros e Arranjos
H uma estreita relao entre PONTEIROS e ARRANJOS (vetores, matrizes e strings). O nome de um ARRANJO (vetor, matriz ou string) sempre um PONTEIRO para o primeiro elemento do ARRANJO.

char str[80], pstr = str;

*pstr; /* pstr aponta para str[0] */

Assim, a dcima posio de um ARRANJO (vetor, matriz ou string) pode ser acessada de duas maneiras:

pstr = str;

/* pstr aponta para str[0] */ /* imprime o 10o elemento de str */ /* imprime o 10o elemento de str */

printf("%c", str[9] ); printf("%c",*(pstr + 9));

Aritmtica de Ponteiros
Existem apenas duas operaes aritmticas que podem ser usadas com ponteiros: adio e subtrao. Cada vez que um ponteiro incrementado, ele aponta para a posio de memria do prximo elementodo seu tipo base. Cada vez que um ponteiro decrementado, ele aponta para a posio de memria do elemento anterior.

57 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Aplicaes
O correto entendimento e uso de ponteiros crtico para uma programao bem-sucedida em C. H pelo menos trs razes para isto: ponteiros fornecem os meios pelos quais as funes podem modificar seus argumentos formam a base para a alocao dinmica (variveis no heap) aumenta a eficincia de certas rotinas

De agora em diante, at o final do curso, iremos explorar em variados graus de detalhes o conceito bsico de ponteiros.

Atividade 1
Aplicando os conhecimentos adquiridos na ltima aula e nesta, iremos agora implementar uma primeira verso de uma lista de strings. Dado o cdigo abaixo (que pode ser obtido como projeto Dev-Cpp neste link), complemente o cdigo do arquivo lista.c escrevendo as funes:

list_rem() list_get() list_set()

main.c

58 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* main.c **/ #include #include #include #include <stdio.h> <stdlib.h> "list.h" "xcpt.h"

int main(int argc, char *argv[]) { while (1) { char str[1024]; int pos; const char * xc; printf("\nAdicionar\n"); printf(" printf(" pos = "); scanf("%d",&pos); str = "); gets(str); gets(str);

list_add(str,pos); /* TRY(list_add(str,pos)); CATCH(INDEX_OUT_OF_BOUNDS_XCPT,xc) printf("\npos invalida!\n"); CATCH(LIST_FULL_XCPT,xc) printf("\nlista cheia!\n"); CATCH(LINE_TOO_LONG_XCPT,xc) printf("\nstr muito grande!\n"); */ printf("\nLista\n"); list_print(); } }

list.h, list.c

59 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #ifndef LIST_H #define LIST_H #define LIST_MAX_SIZE #define LINE_MAX_SIZE 99 60

#define LIST_FULL_XCPT "list full" #define LINE_TOO_LONG_XCPT "line too long" unsigned short list_size(void); void char * void char * void #endif list_add(const char * str, unsigned short pos); list_rem(unsigned short pos); list_set(const char * str, unsigned short pos); list_get(unsigned short pos); list_print(void);

60 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #include #include #include #include #include <stdlib.h> <stdio.h> <string.h> "list.h" "xcpt.h"

/** private data */ static char list[LIST_MAX_SIZE][LINE_MAX_SIZE+1]; static unsigned short size = 0; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];

/** public functions */ unsigned short list_size(void) { return size; } /* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT LIST_FULL_XCPT LINE_TOO_LONG_XCPT **/ void when pos is invalid ( > size +1 ) when the list size equals LIST_MAX_SIZE when str is greater than LINE_MAX_SIZE

list_add(const char * str, unsigned short pos) { sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n", __FILE__,__LINE__,str,pos); if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } if ( size + 1 > LIST_MAX_SIZE ) { THROW(LIST_FULL_XCPT,xcpt_cmsg); return ; } if ( strlen(str) > LINE_MAX_SIZE ) { THROW(LINE_TOO_LONG_XCPT,xcpt_cmsg); } if ( pos == 0 ) { strncpy(list[size],str,LINE_MAX_SIZE); } else { int i; for ( i = size ; i >= pos; i-- ) strcpy(list[i],list[i-1]);

61 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

xcpt.h, xcpt.c

/* xcpt.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #ifndef XCPT_H #define XCPT_H #define XCPT_NAME_MAX_SIZE #define XCPT_CMSG_MAX_SIZE #define THROW(e,m) #define TRY(f) #define CATCH(e,m) #define #define #define #define #define 32 1024

__throw((e),(m)) __begin_try();f;__end_try(); if(m=__catch(e)) "null pointer" "index out of bounds" "overflow" "underflow" "illegal argument"

NULL_POINTER_XCPT INDEX_OUT_OF_BOUNDS_XCPT OVERFLOW_XCPT UNDERFLOW_XCPT ILLEGAL_ARGUMENT_XCPT

void void const char * void #endif

__begin_try(void); __end_try(void); __catch(const char *name); __throw(const char *name, const char *cmsg);

62 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* xcpt.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "xcpt.h"

static char xcpt_name[XCPT_NAME_MAX_SIZE + 1]; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE + 1]; static int trying; /* Sets try_flag. **/ void __begin_try(void) { trying = 1; } /* UnSets try_flag. **/ void __end_try(void){ trying = 0; } /* From exception name, gets the exception message thown by __throw(n,m). Once cautch, the exception name is cleared . **/ const char * __catch(const char * name) { if ( strcmp(xcpt_name,name) == 0 ) { xcpt_name[0] = '\0'; return xcpt_cmsg; } else return NULL; } /* Stores an exception contextual message. When called outside a __begin_try(); ...; __end_try(); pair, the exception message is also printed to the stderr stream . **/ void __throw(const char * name,const char * cmsg) { strncpy(xcpt_name,name,XCPT_NAME_MAX_SIZE); strncpy(xcpt_cmsg,cmsg,XCPT_CMSG_MAX_SIZE); if ( !trying ) fprintf(stderr,"exception: %s: %s\n",xcpt_name,xcpt_cmsg); }

63 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Leitura recomendada
CCT Cap 5

Exerccios
1. Termine a atividade 1 acima, escrevendo as funes:

list_rem() list_get() list_set()

Exemplo: Lista de Strings


lrc , 20 May 2008 (created 20 May 2008) Dado o cdigo abaixo (que pode ser obtido como projeto Dev-Cpp neste link), complemente o cdigo do arquivo lista.c escrevendo as funes:
no tags

list_rem() list_get() list_set()

main.c

64 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* main.c **/ #include #include #include #include <stdio.h> <stdlib.h> "list.h" "xcpt.h"

int main(int argc, char *argv[]) { while (1) { char str[1024]; int pos; const char * xc; printf("\nAdicionar\n"); printf(" printf(" pos = "); scanf("%d",&pos); str = "); gets(str); gets(str);

list_add(str,pos); /* TRY(list_add(str,pos)); CATCH(INDEX_OUT_OF_BOUNDS_XCPT,xc) printf("\npos invalida!\n"); CATCH(LIST_FULL_XCPT,xc) printf("\nlista cheia!\n"); CATCH(LINE_TOO_LONG_XCPT,xc) printf("\nstr muito grande!\n"); */ printf("\nLista\n"); list_print(); } }

list.h, list.c

65 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #ifndef LIST_H #define LIST_H #define LIST_MAX_SIZE #define LINE_MAX_SIZE 99 60

#define LIST_FULL_XCPT "list full" #define LINE_TOO_LONG_XCPT "line too long" unsigned short list_size(void); void char * void char * void #endif list_add(const char * str, unsigned short pos); list_rem(unsigned short pos); list_set(const char * str, unsigned short pos); list_get(unsigned short pos); list_print(void);

66 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #include #include #include #include #include <stdlib.h> <stdio.h> <string.h> "list.h" "xcpt.h"

/** private data */ static char list[LIST_MAX_SIZE][LINE_MAX_SIZE+1]; static unsigned short size = 0; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];

/** public functions */ unsigned short list_size(void) { return size; } /* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT LIST_FULL_XCPT LINE_TOO_LONG_XCPT **/ void when pos is invalid ( > size +1 ) when the list size equals LIST_MAX_SIZE when str is greater than LINE_MAX_SIZE

list_add(const char * str, unsigned short pos) { sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n", __FILE__,__LINE__,str,pos); if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } if ( size + 1 > LIST_MAX_SIZE ) { THROW(LIST_FULL_XCPT,xcpt_cmsg); return ; } if ( strlen(str) > LINE_MAX_SIZE ) { THROW(LINE_TOO_LONG_XCPT,xcpt_cmsg); } if ( pos == 0 ) { strncpy(list[size],str,LINE_MAX_SIZE); } else { int i; for ( i = size ; i >= pos; i-- ) strcpy(list[i],list[i-1]);

67 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

xcpt.h, xcpt.c

/* xcpt.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #ifndef XCPT_H #define XCPT_H #define XCPT_NAME_MAX_SIZE #define XCPT_CMSG_MAX_SIZE #define THROW(e,m) #define TRY(f) #define CATCH(e,m) #define #define #define #define #define 32 1024

__throw((e),(m)) __begin_try();f;__end_try(); if(m=__catch(e)) "null pointer" "index out of bounds" "overflow" "underflow" "illegal argument"

NULL_POINTER_XCPT INDEX_OUT_OF_BOUNDS_XCPT OVERFLOW_XCPT UNDERFLOW_XCPT ILLEGAL_ARGUMENT_XCPT

void void const char * void #endif

__begin_try(void); __end_try(void); __catch(const char *name); __throw(const char *name, const char *cmsg);

68 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* xcpt.c, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "xcpt.h"

static char xcpt_name[XCPT_NAME_MAX_SIZE + 1]; static char xcpt_cmsg[XCPT_CMSG_MAX_SIZE + 1]; static int trying; /* Sets try_flag. **/ void __begin_try(void) { trying = 1; } /* UnSets try_flag. **/ void __end_try(void){ trying = 0; } /* From exception name, gets the exception message thown by __throw(n,m). Once cautch, the exception name is cleared . **/ const char * __catch(const char * name) { if ( strcmp(xcpt_name,name) == 0 ) { xcpt_name[0] = '\0'; return xcpt_cmsg; } else return NULL; } /* Stores an exception contextual message. When called outside a __begin_try(); ...; __end_try(); pair, the exception message is also printed to the stderr stream . **/ void __throw(const char * name,const char * cmsg) { strncpy(xcpt_name,name,XCPT_NAME_MAX_SIZE); strncpy(xcpt_cmsg,cmsg,XCPT_CMSG_MAX_SIZE); if ( !trying ) fprintf(stderr,"exception: %s: %s\n",xcpt_name,xcpt_cmsg); }

69 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Alocao Dinmica
lrc , 23 June 2008 (created 20 May 2008)
no tags

Definio
ALOCAO DINMICA o processo atravs do qual um programa pode criar novas variveis (reas de memria) em tempo de execuo. Variveis alocadas dinmicamente so criadas em uma rea de memria livre chamada de HEAP e so acessadas atravs de PONTEIROS.

Funes de Alocao Dinmica em C


Padro ANSI
#include <stdlib.h> void * calloc(size_t num, size_t size); Aloca uma quantidade de memria igual a num* size. Isto , aloca memria suficiente para um ARRANJO de num VARIVEIS de tamanho size.
Devolve o endereo para o primeiro byte da regio alocada. Se no houver memria suficiente para satisfazer a solicitao, devolvido NULL (endereo nulo).

void * malloc(size_t size);


Aloca uma quantidade de memria igual a size. Isto , aloca memria suficiente para uma VARIVEL de tamanho size. Devolve o endereo para o primeiro byte da regio alocada. Se no houver memria suficiente para satisfazer a solicitao, devolvido NULL (endereo nulo).

void * realloc(void * ptr, size_t size);


Modifica o tamanho da memria previamente alocada apontada por ptr para um novo tamanho especificado por

size. O valor size pode ser maior ou menor que o original.


Retorna o endereo para o primeiro byte da regio de memria redimensionada. Se no houver memria suficiente no HEAP para satisfazer a solicitao, devolvido NULL (endereo nulo) e o endereo originalmente em ptr deixado inalterado.

void free(void * ptr);


Devolve ao HEAP a memria apontada por ptr, tornando a memria disponvel para alocao futura. Deve ser chamada somente com um PONTEIRO ptr cujo endereo de memria foi previamente alocado por meio de uma das funes do sistema de alocao dinmica ( calloc(), malloc(), realloc()).

Outras
#include <string.h> char * strdup(const char * pstr); Duplica a STRING apontada por pstr. Ou seja, aloca no HEAP strlen(pstr)+1 bytes e copia a STRING comeando em pstr para o endereo alocado. Retorna o endereo alocado contendo uma cpia da STRING apontada por pstr ou NULL caso no haja memria
suficiente no HEAP.

70 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Ex.: O trecho de cdigo abaixo:

char str[] = "Teste"; char * pstr = strdup(str);


equivalente a:

char str[] = "Teste"; char * pstr = calloc(strlen(str) + 1, sizeof char); strcpy(pstr,str);

Atividade 1
Utilizando as funes de alocao dinmica em C, iremos agora implementar uma segunda verso do programa lista de strings estudado na aula Ponteiros.

list.h
/* list.h, Rev. 1.2 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #ifndef LIST_H #define LIST_H unsigned short list_size(void); void char * void char * void #endif list_add(const char * str, unsigned short pos); list_rem(unsigned short pos); list_set(const char * str, unsigned short pos); list_get(unsigned short pos); list_print(void);

list.c

71 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* list.c, Rev. 1.3 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements a list of strings. **/ #include #include #include #include #include <stdlib.h> <stdio.h> <string.h> "list.h" "xcpt.h"

/** private data */ static char ** list; static unsigned short static

size = 0;

char xcpt_cmsg[XCPT_CMSG_MAX_SIZE+1];

/** public functions */ unsigned short list_size(void) { return size; } /* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT NULL_POINTER_XCPT **/ void when pos is invalid ( > size +1 ) when there is no memory available to add a new element to the list.

list_add(const char * str, unsigned short pos) { char * line = strdup(str); sprintf(xcpt_cmsg,"%s, %d: list_ins (\"%s\",%d);",__FILE__,__LINE__,str,pos) if ( line == NULL ) { THROW(NULL_POINTER_XCPT,xcpt_cmsg); return ; } if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } if ( size % 10 == 0 ) { char ** aux = (char **) realloc(list,(size + 10)*(sizeof (char**))); if ( aux == NULL ) { THROW(NULL_POINTER_XCPT,xcpt_cmsg); return ; } list = aux; }

72 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exerccios
1. Conclua a Atividade 1 implementando as funes:

char * list_rem(unsigned short pos); void list_set(const char * str, unsigned short pos); char * list_get(unsigned short pos); 2. Teste a nova implementao de list.h e list.c com o mesmo arquivo main.c apresentado na aula Ponteiros.

Vetores para Ponteiros, Ponteiros para Vetores e Ponteiros para Ponteiros


lrc , 20 May 2008 (created 20 May 2008) Considere as declaraes:
no tags

int * x [10]; int (* y)[10]; int * * z;


Questes: O que significam? Quais dos usos abaixo so vlidos?

int i,j,k[10],l[10][5],m[5][10]; x[1] = &i; x[3] = j; x[5] = k; x[7] = k[2]; x[9] = k + 5; x[0] x[2] x[4] x[6] x[8] = = = = = l[1]; l + 1; m[1]; &l[3][2]; m[3] + 2;

y = &i; y = k; y[2] = k; y = &k; y y y y = = = = l; m; l[1]; m + 2;

z = k; z = l; z = m;

Exerccios
Seja o seguinte trecho de programa:

73 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

int i=3,j=5; int *p, *q; p = &i; q = &j;


Qual o valor das seguintes expresses ?

p == &i *p - *q **&p 3* - *p/(*q)+7


Qual ser a sada do programa abaixo supondo que i ocupa o endereo 4094 na memria?

main() { int i=5, *p; p = &i; printf( %x %d }


Qual o resultado do seguinte programa?

%d

%d

%d \n , p,*p+2,**&p,3**p,**&p+4);

#include <conio.h> #include <stdio.h> void main(){ float vet[5] = {1.1,2.2,3.3,4.4,5.5}; float *f; int i; f = vet; printf("contador/valor/valor/endereco/endereco"); for(i = 0 ; i <= 4 ; i++){ printf("\ni = %d",i); printf(" vet[%d] = %.1f",i, vet[i]); printf(" *(f + %d) = %.1f",i, *(f+i)); printf(" &vet[%d] = %X",i, &vet[i]); printf(" (f + %d) = %X",i, f+i); } }
Considere os dois programas abaixo. O que fazem quando executados?

74 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <conio.h> #include <stdio.h> void main() { int vet[] = {4,9,12}; int i,*ptr; ptr = vet; for(i = 0 ; i < 3 ; i++) { printf("%d ",*ptr++); } }

#include <conio.h> #include <stdio.h> void main(){ int vet[] = {4,9,12}; int i,*ptr; ptr = vet; for(i = 0 ; i < 3 ; i++) { printf("%d ",(*ptr)++); } }
Seja vet um vetor de 4 elementos: TIPO vet[ 4] . Supor que depois da declarao, vet esteja armazenado no endereo de memria 4092 (ou seja, o endereo de vet[ 0] ). Qual o valor de vet+ 1, vet+ 2 e vet+ 3 se: TIPO = char? TIPO = int? TIPO = float? O que significam as seguintes declaraes:

int int int int int int

* pi; ** ppi; * vpi[5]; (* pvi)[3]; (* pmi)[3][5]; * mpi[5][3];

D exemplo de uma declarao de: vetor para ponteiros para matrizes ponteiro para vetor de matrizes matriz de vetores de ponteiros matriz de ponteiros para vetores Reescreva o programa abaixo, substituindo o comando while pelo comando for.

#include <stdio.h> #define NUMS 5 void main (void) { int nums[NUMS] = {16,54,7,43,-5}; int total = 0, *n_pt; n_pt = nums; /*armazena o endereo de nums[0] em n_pt*/ while (n_pt < nums + NUMS) total+=*n_pt++; printf( O total dos elementos do vetor %d , total); }
Determine a sada do seguinte programa:

75 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> void arr(int (*val)[3]) { printf( \n %d , printf( \n %d , printf( \n %d , printf( \n %d , }

*(*val)); *(*val +1)); *(*(val+1)+2)); *(*val)+1);

void main (void) { int nums[2][3]={{33,16,29},{54,67,99}}; arrs(nums); }


Dada a declarao para val na funo arr, a referncia val[ 1] [ 2] vlida dentro da funo?

Estruturas
lrc , 23 June 2008 (created 23 June 2008)
no tags

Tipos de Dados
Em aulas anteriores dissemos que os TIPOS de DADO podem ser classificados em: bsicos ou primitivos compostos ou construdos

Tipos compostos
Arranjos (matrizes e vetores) Ponteiros Definidos pelo usurio Estruturas Unies Enumeraes Campos de bits typedefs

Estruturas

76 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atividade : asciimap

1. Crie um projeto C chamado asciimap 2. Salve os arquivos abaixo no projeto

/* asciimap.h */ #define LAR_MAX 40 #define ALT_MAX 20

void ler_pontos(char asciimap[ALT_MAX][LAR_MAX]); void imprimir(char asciimap[ALT_MAX][LAR_MAX]);

NOTA : Sobre o uso de ARRANJOS em parametros de funes videL Matrizes e Parmetros de Funes.

77 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* asciimap.c */ #include "asciimap.h"

void ler_pontos(char asciimap[ALT_MAX][LAR_MAX]) { char opc[10] = "sim"; while( strcmp(opc,"nao") != 0 ) { unsigned short x,y; char c; printf("Ponto:\n"); printf(" x = "); scanf("%hu",&x); printf(" y = "); scanf("%hu",&y); if ( x >= LAR_MAX || y >= ALT_MAX ) { printf("erro: Max x = %hu e Max y = %hu\n", LAR_MAX -1, ALT_MAX -1); continue; } printf(" c = "); scanf(" %c" ,&c); asciimap[y][x] = c; printf("Outro? [sim|nao]\n"); scanf("%s",opc); } } void imprimir(char asciimap[ALT_MAX][LAR_MAX]) { int x,y; for( y=0; y < ALT_MAX; y++ ) { for( x=0; x < LAR_MAX; x++ ) printf("%c",asciimap[y][x]); printf("\n"); } }

78 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* asciimap-teste.c */ #include "asciimap.h" main() { char map[ALT_MAX][LAR_MAX]; memset(map,' ',LAR_MAX * ALT_MAX); ler_pontos(map); imprimir(map); }

Atividade 2 : retangulo
1. crie um projeto C e salve com o nome de retangulo 2. crie os arquivos abaixo no projeto retangulo

/* retangulo.h */ #include "asciimap.h" struct ponto { unsigned short x,y; char c; }; struct retangulo { struct ponto ini; unsigned short dx,dy; }; #define min(a,b) ((a) < (b) ? (a) : (b))

void desenhar(char asciimap[ALT_MAX][LAR_MAX], struct retangulo ret);

79 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* retangulo.c */ #include "retangulo.h" void desenhar(char asciimap[ALT_MAX][LAR_MAX], struct retangulo ret) { int x,xf,y,yf; xf = min(ret.ini.x + ret.dx, LAR_MAX); for ( x = ret.ini.x ; x < xf; x++ ) asciimap[ret.ini.y][x] = ret.ini.c; yf = min(ret.ini.y + ret.dy, ALT_MAX); for ( y = ret.ini.y; y < yf; y++ ) asciimap[y][ret.ini.x] = ret.ini.c; if ( ret.ini.y + ret.dy <= ALT_MAX ) for ( x = ret.ini.x ; x < xf; x++ ) asciimap[yf-1][x] = ret.ini.c; if ( ret.ini.x + ret.dx <= LAR_MAX ) for ( y = ret.ini.y ; y < yf; y++ ) asciimap[y][xf-1] = ret.ini.c; }

/* retangulo-teste.c */ #include "retangulo.h"

main() { struct ponto struct retangulo struct retangulo p = {0, 0, '.'}; r = { p, 10, 4 }; r2= { {10,4,'-'}, 10, 10};

char map[ALT_MAX][LAR_MAX]; memset(map,' ', ALT_MAX*LAR_MAX); desenhar(map,r); desenhar(map,r2); imprimir(map); }

Leitura Recomendada
CCT cap 7 http:/ / www.di.ufpe.br/ ~ if097/ lprog1-p10/ sld001.htm

80 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exerccios
1. Estenda o programa da atividade 2 para incluir o desenho de : retas (definida por dois pontos distintos; ) circulos (definido por um ponto central e um raio ); 2. Escreva uma funo que use as mesmas estruturas da atividade 2 para descobrir se um ponto est dentro de um retngulo. 3. Defina uma estrutura que permita representar um tringulo, atravs das coordenadas dos seus vrtices. Em seguida, escreva uma funo que leia as coordenadas dos vrtices de um tringulo e preencha a estrutura definida cujo endereo lhe passado como parmetro. Depois, escreva funes que determinem o permetro e a rea de um tringulo representado pela estrutura definida. Por fim, desenvolva um programa de teste de todas as funes criadas. 4. Considere que uma empresa precisa armazenar os seguintes dados de um cliente: DADOS Nome completo com no mximo 50 caracteres; renda mensado do cliente; ano de nascimento; possui ou no carro. Defina um tipo e uma estrutura para armazenarem estes dados e escreva um programa que leia estes dados armazene-os em uma varivel e em seguida os imprima. 5. Considerando a mesma estrutura do exerccio anterior, escreva um programa que leia os dados de 100 clientes e imprima: quantos clientes tm renda mensal acima da mdia; quantos clientes tm carro; quantos clientes nasceram entre 1960 (inclusive) e 1980 (exclusive). 6. Considere que foi definida a seguinte estrutura:

typedef struct _frac } FRACAO;

{ int numerador, denominador;

Escreva um programa em C que calcule as quatro operaes (+ , -, * e / ) usando fraes definidas com estruturas do tipo FRACAO. O programa deve ler duas fraes e imprimir o resultado de cada uma das quatro operaes.

typedef, ponteiros para funes e union


lrc , 23 June 2008 (created 23 June 2008)
no tags

Exemplo

81 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#ifndef MENU_H #define MENU_H typedef struct char * void(* struct struct struct struct } Item; item { str; fun)(void); item * sub; item * sup; item * nxt; item * prv;

void addMenuItem (const char * str, void(* fun)(void)); void addMenuSubItem (const char * str_i,const char * str_si, void(* fun)(void)); void loopMenu(void); #endif

/** menu.c */ #include #include #include #include #include <stdlib.h> <stdio.h> <conio.h> "buffer.h" "menu.h"

Item * menu; Item * menu_sel; int sub_items_visible; ...

Exemplo

82 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** menu.c */ ... void addMenuItem (const char * str, void(* fun)(void)) { Item * ptr; /** PARAM PONT. FUNCAO */

if ( menu == NULL ) { menu = (Item *) malloc(sizeof (Item)); ptr = menu; ptr->prv = NULL; } else { ptr = menu; while ( ptr->nxt ) { if ( strcmp(ptr->str,str) == 0 ) return; ptr = ptr->nxt; } ptr->nxt = (Item *) malloc(sizeof (Item)); ptr->nxt->prv = ptr; ptr = ptr->nxt; } ptr->str = strdup(str); ptr->fun = fun; /** ATRIBUICAO PONTEIRO FUNCAO **/ ptr->sub = NULL; ptr->sup = NULL; ptr->nxt = NULL; }

... { ... case ENTER: if ( menu_sel->fun ) (*(menu_sel->fun))(); else ... }

/** CHAMADA FUNCAO VIA PONTEIRO **/

83 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#define #define #define #define #define #define union

ENTER ESC RTARR LTARR UPARR DWARR

13 27 77 75 72 80

u_type{ int i; char ch;

} ich;

void loopMenu() { while ( 1 ) { ich.i = getch(); switch ( ich.ch ) { case ENTER: ....

CDIGO COMPLETO
O cdigo abaixo implementa um sistema de menus para um programa de controle acadmico.

84 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** main.c */ #include <stdio.h> #include <stdlib.h> #include "menu.h"

void f() { printf("function activation!"); getch(); } extern Item * menu; extern Item * menu_sel; extern int sub_items_visible; int main(int argc, char *argv[]) { addMenuItem("CADASTRO",NULL); addMenuItem("MATRICULA",NULL); addMenuItem("RELATORIO",NULL); addMenuSubItem("CADASTRO","Alunos",f); addMenuSubItem("CADASTRO","Professores",f); addMenuSubItem("CADASTRO","Disciplinas",f); addMenuSubItem("MATRICULA","Matriculas",f); addMenuSubItem("MATRICULA","Turma",f); loopMenu(); return 0; }

#ifndef MENU_H #define MENU_H typedef struct char * void(* struct struct struct struct } Item; item { str; fun)(void); item * sub; item * sup; item * nxt; item * prv;

void addMenuItem (const char * str, void(* fun)(void)); void addMenuSubItem (const char * str_i,const char * str_si, void(* fun)(void)); void loopMenu(void); #endif

85 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** menu.c */ #include #include #include #include #include <stdlib.h> <stdio.h> <conio.h> "buffer.h" "menu.h"

Item * menu; Item * menu_sel; int sub_items_visible;

void addMenuItem (const char * str, void(* fun)(void)) { Item * ptr; if ( menu == NULL ) { menu = (Item *) malloc(sizeof (Item)); ptr = menu; ptr->prv = NULL; } else { ptr = menu; while ( ptr->nxt ) { if ( strcmp(ptr->str,str) == 0 ) return; ptr = ptr->nxt; } ptr->nxt = (Item *) malloc(sizeof (Item)); ptr->nxt->prv = ptr; ptr = ptr->nxt; } ptr->str = strdup(str); ptr->fun = fun; ptr->sub = NULL; ptr->sup = NULL; ptr->nxt = NULL; } void addMenuSubItem (const char * str_i,const char * str_si, void(* fun)(void)) { Item * ptr; ptr = menu; while ( ptr ) { if ( strcmp(ptr->str,str_i) == 0 ) break; ptr = ptr->nxt; } if ( ptr == NULL ) return; if ( ptr->sub == NULL ) { ptr->sub = (Item *) malloc(sizeof (Item)); ptr->sub->prv = NULL; ptr->sub->sup = ptr; ptr = ptr->sub; } else { ptr = ptr->sub;

86 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** buffer.h */ #ifndef BUFFER_H #define BUFFER_H void clearBuf(void); void xyputs(unsigned short x, unsigned short y, const char * str); void displayBuf(void);

#endif

87 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** buffer.c */ #include <stdlib.h> #include <stdio.h> #include <conio.h> #define BUFW #define BUFH 80 24

char buf[BUFH][BUFW]; void clearBuf(void){ int x,y; for( y = 0; y < BUFH; y++ ) { for( x = 0; x < BUFW; x++ ) buf[y][x] = ' '; } } void xyputs(unsigned short x, unsigned short y, const char * str) { x %= BUFW; y %= BUFH; for ( ; *str ; str++ ) { switch( *str ) { case '\n' : x = 0, y = (y + 1) % BUFH; break; case '\b' : if ( x == 0 ) { x = BUFW - 1; y = y == 0 ? BUFH - 1 : y -1; } else x --; break; default : buf[y][x] = *str; x = (x+1)%BUFW; y = x == 0 ? (y+1)%BUFH : y; } } } void displayBuf(void) { //fseek(stdout,sizeof buf,SEEK_END); system("cls"); fwrite(&buf,sizeof buf ,1,stdout); }

Enumeraes e Campos de Bits


lrc , 23 June 2008 (created 23 June 2008)

88 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

no tags

Enumeraes
Uma enumerao uma extenso da linguagem C acrescentada pelo padro ANSI. Uma enumerao uma declarao de um novo tipo de dados que consiste em um conjunto de constantes inteiras que especficam todos os valores legais que uma varivel desse tipo pode ter. Enumeraes so definidas de forma semelhante a estruturas; no entanto, utiliza-se a palavra-chave enum para assinalar o incio de um tipo de enumerao. FORMA GERAL:

enum identificador { Simbolo_1, Simbolo_2, ... Simbolo_n } var_1, var_2, ..., var_n;

Em uma enumarao cada Simbolo_i representa um valor inteiro. Cada smbolo recebe um valor maior em uma unidade do precedente. Por default, o valor do primeiro smbolo 0. No entanto, voc pode especificar o valor de um ou mais smbolos usando um inicializador. O smbolos que aparecem aps os inicializadores recebem valores maiores que o da inicializao 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

89 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo
struct { unsigned unsigned unsigned unsigned } bitf; mday : 5; month: 4; year :22; isBCE: 1;

Exemplo Completo
O programa abaixo ilustra todos os mecanismos de definio de novos tipos estruturados pelo usurio: estruturas struct definio de novos nomes para tipos typedef enumeraes enum unies union campos de bits struct Alm disso, o exemplo tambm aborda o uso de funes da biblioteca <time.h>. Para o entedimento do exemplo que trata de datas do calendrio gregoriano voc pode consultar: http:/ / en.wikipedia.org/ wiki/ Gregorian_calendar Para implementao do algoritmo DOOMSDAY para o clculo do dia da semana de uma data, consulte: http:/ / en.wikipedia.org/ wiki/ Doomsday_algorithm

90 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** 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 unsigned unsigned unsigned unsigned enum dt_month long unsigned long };

, , , , , ,

, , , , , , , , , , ,

wday; mday; yday; mweek; yweek; month; year; isBCE; serial;

/* /* /* /* /* /* /* /* /*

day of the week : 0 .. day of the month : 1 .. days since Jan. 1 : 1 .. week of the month : 0 .. week of the year : 0 .. month : 1 .. year : -2^22 .. is Before Common Era ? number of days

6 31 366 5 53 12 2^22

*/ */ */ */ */ */ */ */ */

date_t date_t

date(date_t *); mkdate(struct dt *);

/* get current date */ /* code struct dt* in a date_t */

91 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

92 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** date.c Author: Luciano R. Coutinho, 2007. lrc@deinf.ufma.br */ #include #include #include #include <stdio.h> <stdlib.h> <time.h> "date.h"

union date_t { date_t ival; struct { unsigned unsigned unsigned unsigned } bitf; }; /* Global Shared */ static static int 0 , /* 31, /* 28, /* 31, /* 30, 31, 30, 31, 31, 30, 31, 30, 31 /* };

mday : 5; month: 4; year :22; isBCE: 1;

struct dt dt_buf; num_days[13] = { skiped */ January */ February */ Mars */

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 = ud.bitf.month= ud.bitf.year = ud.bitf.isBCE= tm_now->tm_mday; tm_now->tm_mon + 1; tm_now->tm_year + 1900; 0;

if ( d ) *d = ud.ival; return ud.ival; } /* Gregorian Calendar

93 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> #include <stdlib.h> #include "date.h" union date_t { date_t ival; struct { unsigned unsigned unsigned unsigned } bitf; }; char

mday : 5; month: 4; year :22; isBCE: 1;

* 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,sdud.bitf.mday = 7; ud.bitf.month = September; ud.bitf.year = 1822; ud.bitf.isBCE = 0; sd = gcdate(ud.ival); printf("a idependncia ocorreu num(a) %s

\n",wday_name[sd->wday]);

//system("PAUSE"); return 0; }

Exerccios
1. Conclua o exemplo date.h/ date.c; Escreva as funes

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*);
2. Escreva um programa que teste todas as funes criadas acima.

94 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Entrada/ Sada: console


lrc , 23 June 2008 (created 23 June 2008)
no tags

Lendo e Escrevendo Caracteres


#include <stdio.h> int getchar(void); int putchar(int c); #include <conio.h> int getch(void) int getche(void)

Lendo e Escrevendo Strings


#include <stdio.h> char * gets(char *str); int puts(const char *str);

Exemplo 1

#include <stdio.h> #include <ctype.h>

main() { char ch; printf("Digite algum texto (termine com ponto para sair)\n"); do { ch = getchar(); if ( islower(ch) ) ch = toupper(ch); else ch = tolower(ch); putchar(ch); } while ( ch != '.' ); }

95 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Atividade 1
Refaa o programa acima utilizando getch() e getche().

Entrada/Sada Formatada
#include <stdio.h> int printf(const char * string_de_controle, ...); int scanf(const char * string_de_controle, ...);

printf(): Formato Geral

printf(): Formato Detalhado

96 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo 2
printf ("\nResultado :%3.2f",num); printf ("Frase : %s\nContador = %x",string,cont); printf ("a : %-5d b : %-5d c : %-5d",a,b,c);

Atividade 1
Teste o trecho de cdigo acima em um programa.

scanf(): Formato

97 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Leitura Recomendada
CCT Cap 8. http:/ / www.dee.feis.unesp.br/ graduacao/ disciplinas/ langc/ modulo_linguagemc/ modulo4.htm

Entrada/ Sada: arquivos


lrc , 23 June 2008 (created 23 June 2008)
no tags

fopen(), fclose()

98 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include <stdio.h> FILE * fopen(const char * nomearq, const char * modo); int fclose(FILE * fp);

putc(), fputc(), getc(), fgetc()


#include <stdio.h> int putc(int char, FILE * fp); int fputc(int char, FILE * fp); int getc(FILE * fp); int fgetc(FILE * fp);

Exemplo 1

99 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** ktod.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char * argv[]) { FILE * fp; char ch; if ( argc != 2 ) { printf("sintaxe:\n"); printf(" %s NOME_ARQ\n",argv[0]); exit (1); } fp = fopen(argv[1],"w"); if ( fp == NULL ) { printf("O arquivo exit(1); } do { ch = getchar(); putc(ch, fp); } while ( ch != '$' ); fclose(fp); }

%s

no pode ser aberto.\n",argv[1]);

Exemplo 2

100 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/** dtos.c */ #include <stdio.h> #include <stdlib.h> int main(int argc, char * argv[]) { FILE * fp; char ch; if ( argc != 2 ) { printf("sintaxe:\n"); printf(" %s NOME_ARQ\n",argv[0]); exit (1); } fp = fopen(argv[1],"r"); if ( fp == NULL ) { printf("O arquivo exit(1); } ch = getc(fp); while ( ch != EOF ) { putchar(ch); ch = getc(fp); } fclose(fp); }

%s

no pode ser aberto.\n",argv[1]);

fputs() , fgets()
#include <stdio.h> int fputs(const char * str, FILE * fp); char * fgets(char *str, int length, FILE * fp);

fread() , fwrite()
#include <stdio.h> size_t fread(void * buffer, size_t num_bytes, size_t count, FILE * fp); size_t fwrite(const void * buffer, size_t num_bytes, size_t count, FILE * fp);

Leitura Recomendada
CCT Cap 9 http:/ / www.dee.feis.unesp.br/ graduacao/ disciplinas/ langc/ modulo_linguagemc/ modulo8.htm

101 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exerccios
1. Refaa os programas dos exemplos 3 e 4 utilizando fputs() e fgets(). 2. Escreva um programa que abra um arquivo texto e conte o nmero de caracteres presentes nele. Imprima o nmero de caracteres na tela. 3. Considere um arquivo de dados do tipo texto com o seguinte contedo:

3 ZE SA 8.5 10.0 ANTONIO SANTOS 7.5 8.5 SEBASTIAO OLIVEIRA 5.0 6.0
O arquivo acima apenas um exemplo. Nestes arquivos de alunos a primeira linha contm o nmero de alunos no arquivo. As linhas seguintes contm os seguintes dados: nome do aluno com no mximo 50 caracteres; nota da primeira prova; nota da segunda prova. Escreva um programa que imprima os nomes de todos os alunos que tm a mdia das duas notas menor que 7.0

4. Escreva um programa que grave os dados lidos no exerccio anterior em um arquivo do tipo binrio de acesso aleatrio. O nmero que indica quantos alunos devem ser lidos (primeira linha do arquivo) no deve ser gravado no arquivo binrio. Nesta questo os dados devem estar obrigatoriamente armazenados em um vetor de estruturas do seguinte tipo:

typedef struc _aluno { char nome[81]; float n1, n2; } ALUNO;

5. Escreva um programa que leia de um arquivo, cujo nome sera fornecido pelo usuario, um conjunto de numeros reais e armazena em um vetor. O tamanho mximo do vetor e dado pela constante TAM_MAX. A quantidade de numeros no arquivo varia entre 0 e TAM_MAX. O programa ao final calcula a media dos numeros lidos. 6. Faa um programa que leia 10 caracteres e armazene em um arquivo 10 cpias de cada um. Exiba o contedo do arquivo. 7. Crie uma funo que receba duas strings como parmetros, uma com um endereo de arquivo e outra com um texto qualquer, e adicione o texto no fim do arquivo. 8. Utilizando a funo do exerccio anterior faa um programa que gere 10 arquivos com o nome "Teste" e extenses "01", ..., "10". Cada um contendo o texto "Texto do arquivo [ NMERO DO ARQUIVO] ". 9. Escreva um programa para armazenar o telefone de 5 amigos atravez da estrutura

struct pessoa{ char nome[50]; int idade; float altura; char telefone[10]; } amigos[5];
a ser preenchida pelo usurio antes do armazenamento de cada registro. 10. Faa um programa que leia os dados do arquivo gerado no exerccio anterior e salve-os num novo arquivo utilizando uma sada formatada.

102 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

FORMATO: -------[nome] tem [idade] anos e [altura] de altura. Tel.: [telefone]. --------

11. Escreva um programa que leia um arquivo texto contendo linhas de dados. Em cada linha do arquivo h o nome de um aluno e duas notas. Estes dados esto separados por ponto e vrgula. Existe um ponto e vrgula ao final de cada linha. O formato dos dados e o seguinte:

ze sa; 10.0; 9.0; antonio silva: 9.0; 7.0;


O programa deve ler estes dados e imprimir os valores lidos, a mdia das duas notas e se o aluno foi aprovado ou no (media > = 5). O formato de saida e:

ze sa 10.0 8.0 9.0 aprovado antonio silva 9.0 7.0 8.0 aprovado

12. Faa um programa que ao receber o nome de um arquivo, gere uma cpia deste. 13. Escreva um programa que compare dois arquivos especificados pelo usurio e imprima sempre que os caracteres dos dois arquivos coincidirem. Por exemplo:

arquivo1.c Ol, pessoal! arquivo2.c Oi, como vai?


Neste caso, os caracteres na primeira e dcima primeira posio so iguais nos dois arquivos. A sada do seu programa deve ser algo como:

1 - O (79) 11 - a (97)
Os valores entre parenteses so os respectivos cdigos ASCII dos caracteres.

Pr-processador C
lrc , 23 June 2008 (created 23 June 2008)
no tags

Leitura Recomendada
CCT-cap10

Introduo
Um programa em C transformado em cdigo objeto em duas etapas: uma de PRE-PROCESSAMENTO e a outra de COMPILAO propriamente dita. Na primeira etapa, as DIRETIVAS de PRE-PROCESSAMENTO so convertidas em cdigo C; na segunda etapa, o cdigo C resultante compilado. Abaixo iremos estudar o PRE-PROCESSADOR de C e suas DIRETIVAS. Ao longo da explicao utilizaremos como exemplo os arquivos de programa main.c, list.c, list.h, xcpt.c e xcpt.h discutidos ao final da aula Ponteiros.

103 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#include

Exemplo

104 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

/* main.c **/ #include <stdio.h> #include <stdlib.h> #include "list.h" #include "xcpt.h" int main(int argc, char *argv[]) { ... } /* arquivos de cabealho padro */

/* arquivos de cabealho do projeto */

#define

105 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo
/* xcpt.h, Rev. 1.1 (c) 2007, Luciano R. Coutinho <lrc@deinf.ufma.br> Implements an exception handling mechanism inspired in Java. **/ #ifndef XCPT_H #define XCPT_H #define XCPT_NAME_MAX_SIZE #define XCPT_CMSG_MAX_SIZE #define THROW(e,m) #define TRY(f) #define CATCH(e,m) #define #define #define #define #define 32 1024

__throw((e),(m)) __begin_try();f;__end_try(); if(m=__catch(e)) "null pointer" "index out of bounds" "overflow" "underflow" "illegal argument"

NULL_POINTER_XCPT INDEX_OUT_OF_BOUNDS_XCPT OVERFLOW_XCPT UNDERFLOW_XCPT ILLEGAL_ARGUMENT_XCPT

void void const char * void #endif

__begin_try(void); __end_try(void); __catch(const char *name); __throw(const char *name, const char *cmsg);

#if, #else, #elif e #endif

106 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo-1

107 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo-2
/** 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 ...

#ifdef

Exemplo
Vide inicio dos exemplos anteriores. Eles comeam assim:

108 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

#ifndef FILENAME_H #define FILENAME_H ... #endif

#undef

#line

Macros pr-definidas

109 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

Exemplo
Veja um exemplo de uso de __LINE__ e __FILE__ no trecho de programa abaixo que foi apresentado na aula Ponteiros:

/* Add a new element str in the list at a given position pos. From pos to the end of the list, all existing elements are shifted right. Throws: INDEX_OUT_OF_BOUNDS_XCPT LIST_FULL_XCPT LINE_TOO_LONG_XCPT **/ void when pos is invalid ( > size +1 ) when the list size equals LIST_MAX_SIZE when str is greater than LINE_MAX_SIZE

list_add(const char * str, unsigned short pos) { sprintf(xcpt_cmsg,"@%s[%d]\n> list_ins (\"%s\",%d);\n", __FILE__,__LINE__,str,pos); if ( pos > size + 1 ) { THROW(INDEX_OUT_OF_BOUNDS_XCPT,xcpt_cmsg); return ; } ...

#pragma

110 de 111

14/10/2009 11:04

.: CP 5593.6, 2009.2

Linguagem de Programao - Prof. Luciano R....

http://www.deinf.ufma.br/~lrc/2009.2/LP/

TiddlyWiki Osmosoft

111 de 111

14/10/2009 11:04

This document was created with Win2PDF available at http://www.win2pdf.com. The unregistered version of Win2PDF is for evaluation or non-commercial use only. This page will not be added after purchasing Win2PDF.