notas de aula alg

Upload: wander-gaspar

Post on 11-Jul-2015

343 views

Category:

Documents


1 download

TRANSCRIPT

AlgoritmosProf. Wander Antunes Gaspar ValenteVerso 2011f

31 de julho de 2011

SumrioSumrio Prefcio 1 Introduo aos Algoritmos 1.1 Introduo Organizao de Computadores . . . . . . . . . . . . . . 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2 1.3 Modelo de von Neumann . . . . . . . . . . . . . . . . . . . . . Bases de Numerao . . . . . . . . . . . . . . . . . . . . . . . Bit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Codicao ASCII . . . . . . . . . . . . . . . . . . . . . . . . Grandezas Derivadas do Byte . . . . . . . . . . . . . . . . . . Palavra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i 1 3 3 3 4 4 5 6 6 6 6 8

Memria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Programao de Computadores . . . . . . . . . . . . . . . . . . . . . 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5

Linguagem de Mquina . . . . . . . . . . . . . . . . . . . . . 10 Linguagem de Montagem . . . . . . . . . . . . . . . . . . . . 10 Linguagem de Alto Nvel . . . . . . . . . . . . . . . . . . . . . 11 Compilao . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Ligao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Pseudocdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 i

1.4

Algoritmos 1.4.1

ii 1.4.2

SUMRIO Fluxograma . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 19

2 Introduo Programao em C 2.1 2.1.1 2.1.2 2.2 2.3 2.4

Linguagem de Programao C . . . . . . . . . . . . . . . . . . . . . . 19 Ambiente de Desenvolvimento Integrado para C . . . . . . . . 20 Exemplo Preliminar . . . . . . . . . . . . . . . . . . . . . . . 20

Sada de Dados na Sada Padro . . . . . . . . . . . . . . . . . . . . 22 Comentrios em C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Tipos de Dados Primitivos . . . . . . . . . . . . . . . . . . . . . . . . 25 2.4.1 2.4.2 2.4.3 Tipos Inteiros . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Tipos de Ponto Flutuante . . . . . . . . . . . . . . . . . . . . 26 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

2.5 2.6 2.7 2.8

Especicadores de Formato . . . . . . . . . . . . . . . . . . . . . . . 27 Variveis de Memria . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.6.1 Declarao de Variveis na Memria . . . . . . . . . . . . . . 28 Comando de Atribuio . . . . . . . . . . . . . . . . . . . . . . . . . 29 Operadores Aritmticos . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 Operador Menos Unrio . . . . . . . . . . . . . . . . . . . . . 32 Operador Mdulo . . . . . . . . . . . . . . . . . . . . . . . . . 32 Diviso Inteira . . . . . . . . . . . . . . . . . . . . . . . . . . 34 Precedncia de Operadores Aritmticos . . . . . . . . . . . . . 35 Expresses Aritmticas no Corpo da Funo printf() . . . . 36 Controle do Nmero de Dgitos Decimais . . . . . . . . . . . . 37 Controle do Comprimento do Campo de Sada . . . . . . . . . 37 Exibio de Zeros No Signicativos . . . . . . . . . . . . . . 38 Alinhamento Esquerda . . . . . . . . . . . . . . . . . . . . . 39 . . . . . . . . . . . . . . . . . 40

2.9

Controle e Formatao de Sada . . . . . . . . . . . . . . . . . . . . . 37 2.9.1 2.9.2 2.9.3 2.9.4

2.10 Denio de Constantes na Memria . . . . . . . . . . . . . . . . . . 39 2.11 Entrada de Dados na Entrada Padro 2.11.1 Especicadores de Formato para scanf() . . . . . . . . . . . 41

SUMRIO

iii

2.12 Constantes e Funes Matemticas . . . . . . . . . . . . . . . . . . . 43 2.12.1 Constantes Matemticas . . . . . . . . . . . . . . . . . . . . . 45 2.12.2 Funes Matemticas . . . . . . . . . . . . . . . . . . . . . . 45 2.12.3 Valor Absoluto . . . . . . . . . . . . . . . . . . . . . . . . . . 46 3 Estruturas de Seleo 3.1 3.2 3.3 3.1.1 3.2.1 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.4 3.5 3.6 3.7 3.8 49

Operadores Relacionais . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Expresses Envolvendo Operadores Relacionais . . . . . . . . 50 Estrutura de Seleo if-else . . . . . . . . . . . . . . . . . . 50 Operador Lgico && . . . . . . . . . . . . . . . . . . . . . . . 57 Operador Lgico || . . . . . . . . . . . . . . . . . . . . . . . . 57 Operador Lgico ! . . . . . . . . . . . . . . . . . . . . . . . . 58 Expresses Relacionais e Operadores Lgicos . . . . . . . . . 58 Problemas de Mltiplas Opes . . . . . . . . . . . . . . . . . 60 Estruturas de Seleo da Linguagem C . . . . . . . . . . . . . . . . . 50 Operadores Lgicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

Operador Condicional Ternrio . . . . . . . . . . . . . . . . . . . . . 62 Precedncia de Operadores . . . . . . . . . . . . . . . . . . . . . . . . 63 3.5.1 Tabela de Precedncia Entre Operadores . . . . . . . . . . . . 64 Comando de Desvio Condicional switch . . . . . . . . . . . . . . . . 64 Funes para Teste de Caracteres . . . . . . . . . . . . . . . . . . . . 68 Operador Aritmtico de Atribuio . . . . . . . . . . . . . . . . . . . 70 71

4 Estruturas de Repetio 4.1 4.1.1 4.2

Operadores de Incremento e Decremento . . . . . . . . . . . . . . . . 71 Formas Pr-xada e Ps-xada para os Operadores de Incremento e Decremento . . . . . . . . . . . . . . . . . . . . . . . 72 Forma Geral da Estrutura for . . . . . . . . . . . . . . . . . 73 Lao Innito . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Estruturas for Avanadas . . . . . . . . . . . . . . . . . . . . 77

Estrutura de Repetio for . . . . . . . . . . . . . . . . . . . . . . . 73 4.2.1 4.2.2 4.2.3

iv 4.2.4 4.3 4.3.1 4.3.2 4.3.3 4.4 4.5 4.6 4.7 4.4.1

SUMRIO Laos Aninhados . . . . . . . . . . . . . . . . . . . . . . . . . 80 Forma Geral da Estrutura while . . . . . . . . . . . . . . . . 82 Flag ou Sentinela . . . . . . . . . . . . . . . . . . . . . . . . . 83 Estrutura while Sempre Verdadeira . . . . . . . . . . . . . . 84 Forma Geral da Estrutura do-while . . . . . . . . . . . . . . 86

Estrutura de Repetio while . . . . . . . . . . . . . . . . . . . . . . 82

Estrutura de Repetio do-while . . . . . . . . . . . . . . . . . . . . 86 Comando continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Consistncia na Entrada de Dados . . . . . . . . . . . . . . . . . . . 89 Nmeros Pseudoaleatrios . . . . . . . . . . . . . . . . . . . . . . . . 91 4.7.1 4.7.2 Semente de Randomizao . . . . . . . . . . . . . . . . . . . . 92 Escopo dos Nmeros Pseudo-Aleatrios Gerados . . . . . . . . 93 97

5 Estruturas Homogneas 5.1 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.2 5.2.1 5.2.2 5.2.3

Estruturas Homogneas Unidimensionais . . . . . . . . . . . . . . . . 97 Declarao de um Array . . . . . . . . . . . . . . . . . . . . . 98 Arrays e Comandos de Repetio . . . . . . . . . . . . . . . . 99 Diretiva #define . . . . . . . . . . . . . . . . . . . . . . . . . 101 Atribuio de Valor na Declarao do Array . . . . . . . . . . 102 Arrays e Nmeros Pseudoaleatrios . . . . . . . . . . . . . . . 104 Percorrimento de Matriz em C . . . . . . . . . . . . . . . . . 107 Inicializao de Matrizes . . . . . . . . . . . . . . . . . . . . . 108 Atribuio de Valor aos Elementos de uma Matriz . . . . . . . 109 113

Estruturas Homogneas Bidimensionais . . . . . . . . . . . . . . . . . 106

6 Cadeias de Caracteres 6.1 6.2 6.3 6.4

Cadeias de Caracteres em C . . . . . . . . . . . . . . . . . . . . . . . 113 Entrada de cadeias de caracteres . . . . . . . . . . . . . . . . . . . . 116 Converso de Cadeias de Caracteres em Tipos Numricos . . . . . . . 121 Funes de C para Cadeias de Caracteres . . . . . . . . . . . . . . . . 124

SUMRIO 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.5

v Cpia de Cadeias de Caracteres . . . . . . . . . . . . . . . . . 124 Tamanho de Cadeias de Caracteres . . . . . . . . . . . . . . . 126 Concatenao de Cadeias de Caracteres . . . . . . . . . . . . 127 Comparao de Cadeias de Caracteres . . . . . . . . . . . . . 129 Pesquisa em uma Cadeia de Caracteres . . . . . . . . . . . . . 130

Vetor de Cadeias de Caracteres . . . . . . . . . . . . . . . . . . . . . 132 137 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

7 Funes 7.1 7.2 7.3 7.4 7.5 Modularizao

Argumentos de Entrada e Tipos de Retorno . . . . . . . . . . . . . . 140 Funes e Estruturas Homogneas . . . . . . . . . . . . . . . . . . . . 144 Funes e Cadeias de Caracteres . . . . . . . . . . . . . . . . . . . . 147 Tipos Especiais de Variveis . . . . . . . . . . . . . . . . . . . . . . . 148 7.5.1 7.5.2 Variveis Globais . . . . . . . . . . . . . . . . . . . . . . . . . 148 Variveis Estticas . . . . . . . . . . . . . . . . . . . . . . . . 149

7.6 7.7

Recursividade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Bibliotecas de Funes . . . . . . . . . . . . . . . . . . . . . . . . . . 152

vi

SUMRIO

PrefcioNotas de aula da disciplina Algoritmos ministrada aos alunos do curso de Bacharelado em Sistemas de Informao do Centro de Ensino Superior de Juiz de Fora. Horrio das aulas no segundo semestre letivo de 2011: teras e quintas-feiras das 18h50min s 20h30min. de competncia do professor o lanamento quinzenalmente a frequncia no aluno online. A disciplina possui 4 crditos, o que equivale a 72 horas/aula. O limite mximo de faltas, que corresponde a 25%, representa 18 horas/aula.

1

2

SUMRIO

Captulo 1 Introduo aos AlgoritmosNo se pode criar experincia. preciso passar por ela. Albert Einstein

1.1 Introduo Organizao de Computadores1.1.1 Modelo de von NeumannO modelo lgico de computador proposto por von Neumann pode ser descrito pela Figura 1.1.

Figura 1.1: Modelo de Arquitetura de von Neumann

3

4

CAPTULO 1. INTRODUO AOS ALGORITMOS Unidade de controle: a unidade de controle controla o funcionamento da unidade lgica e aritmtica e da memria. Alm disso, ela distribui e organiza tarefas, transfere informaes da entrada para a memria e da memria para a sada. Memria: a memria o dispositivo de armazenamento de informao do computador. Nela so armazenados tanto as instrues de um programa quanto os dados necessrios para a sua execuo. A memria dividida em espaos com endereos. Unidades de entrada e sada: a unidade de entrada traduz informao (por exemplo, letras, nmeros, imagens, marcas magnticas) de uma variedade de dispositivos de entrada em impulsos eltricos que a CPU entenda. A unidade de sada traduz os dados processados, enviados pela CPU em forma de impulsos eltricos, em palavras ou nmeros, que so impressos por impressoras ou mostrados em monitores de vdeo.

1.1.2

Bases de Numerao

Por questes de Engenharia (conabilidade, menor consumo de energia, menor dissipao de calor), os computadores utilizam a base numrica binria (dgitos 0 e 1) em lugar da base numrica decimal (dgitos 0 e 9). Outras bases numricas tambm utilizadas em Cincia da Computao so a octal (dgitos 0 a 7) e hexadecimal (dgitos 0 a 9 e A a F). Isso se deve fcil converso entre a base binria e as bases octal e hexadecimal associado uma representao mais concisa e inteligvel (Figura 1.2). Cada 4 dgitos em um nmero na representao binria corresponde a um nmero na representao hexadecimal. Por exemplo, (101111001101)2 = (BCD)16 e (13A)16 = (000100111010)2 . Analogamente, cada 3 dgitos binrios correspondem a um dgito octal. Por exemplo, (101111001101)2 = (5715)8 . Em decimal, 5 83 + 7 82 + 1 81 + 5 80 = (3021)10 .

1.1.3

Bit

Bit (simplicao para dgito binrio, BInary digiT em ingls) a menor unidade de informao que pode ser codicada e manipulada em um computador digital. Um bit tem um nico valor, 0 ou 1, ou verdadeiro ou falso, ou neste contexto, quaisquer dois valores mutuamente exclusivos.

1.1. INTRODUO ORGANIZAO DE COMPUTADORES

5

Figura 1.2: Bases de Numerao utilizadas em Computao Fisicamente, o valor de um bit armazenado como uma carga eltrica acima ou abaixo de um nvel padro em um nico capacitor dentro de um dispositivo de memria. Mas, bits podem ser representados sicamente por vrios meios: luz (em bras ticas), ondas eletromagnticas (rede wireless), polarizao magntica (discos rgidos).

1.1.4 ByteDenomina-se byte (contrao de BinarY term) unidade bsica de tratamento de informao em computadores digitais. Por padronizao de mercado, 1 byte equivale a 8 bits contguos. A primeira codicao de 1 byte = 8 bits deveu-se empresa IBM em 1960 com a criao da tabela ASCII. Como cada bit pode conter 2 valores binrios diferentes, 1 byte (8 bits) pode representar 256 valores numricos distintos na base 2. A Tabela 1.1 apresenta os valores mnimo e mximo que podem ser armazenados em 1 byte. 1 27 + 1 26 + 1 25 + 1 24 + 1 23 + 1 22 + 1 21 + 1 20 = 255 Cada byte pode armazenar um caractere (letra, nmero ou smbolo), de acordo com alguma tabela de codicao.

6

CAPTULO 1. INTRODUO AOS ALGORITMOS Tabela 1.1: Valores mnimo e mximo em 1 byte 0 0 0 1 1 1 0 0 0 1 1 1 0 0 1 1

1.1.5

Codicao ASCII

ASCII (acrnimo para American Standard Code for Information Interchange, que em portugus signica Cdigo Padro Americano para o Intercmbio de Informao) uma codicao de caracteres de oito bits criado pela IBM. Originalmente ASCII usava apenas 7 bits (capaz de representar 128 caracteres) mas posteriormente estendeu-se para 8 bits para suportar os caracteres acentuados usados em diversos idiomas como o portugus. A Figura 1.3 apresenta a codicao ASCII para os principais caracteres imprimveis dos idiomas ocidentais.

1.1.6

Grandezas Derivadas do Byte

Uma vez que os computadores utilizam aritmtica binria (base 2), os valores numricos so expressos em potncias de dois e no em potncias de dez, embora sejam usados os mesmos nomes para os mltiplos. Assim, 1 quilobyte (KB) equivale a 210 bytes = 1.024 bytes, 1 megabyte (MB) equivale a 220 bytes = 1.048.576 bytes e 1 gigabyte (GB) equivale a 230 bytes = 1.073.741.824 bytes.

1.1.7

Palavra

Uma palavra (word) um valor xo para um determinado processador. Assim, um Pentium possui uma palavra de 32 bits. Isso signica que 1 palavra de 32 bits so processados por vez nesse processador e indica a sua capacidade de processamento.

1.2

Memria

Memria o componente de um computador cuja funo armazenar informaes a serem manipuladas pelo sistema. A Figura 1.4 apresenta uma analogia entre uma memria de computador e um arquivo de chas em uma empresa.

1.2. MEMRIA

7

Figura 1.3: Caracteres imprimveis da tabela ASCII

8

CAPTULO 1. INTRODUO AOS ALGORITMOS

Figura 1.4: Analogia entre memria de computador e chrio manual Na realidade, existem diversos tipos de memria em um computador: Memria principal: (memria RAM Random Access Memory Memria de Aceso Randmico). Memria cache: construda com tecnologia RAM, inserida entre a UCP e a memria principal. Registradores: dispositivos de armazenamento existentes no interior dos processadores, com o objetivo de conter os dados, instrues e endereos de memria RAM a serem processados pela UCP. Memria secundria: discos rgidos, mdias ticas, pen drives. A A Figura 1.5 apresenta a relao entre o custo e o desempenho dos tipos de memria existentes. A memria principal endereada por bytes (clulas), comeando pelo endereo 0 (byte 0) at o ltimo byte disponvel. A A Figura 1.6 apresenta um exemplo de alocao de bytes na memria principal de um computador.

1.3

Programao de Computadores

Uma linguagem de programao uma codicao criada para instruir um computador a realizar uma determinada tarefa. Para que um computador execute qualquer tarefa necessrio fornecer um cdigo, escrito em uma linguagem de programao.

1.3. PROGRAMAO DE COMPUTADORES

9

Figura 1.5: Relao custo versus desempenho dos tipos de memria

Figura 1.6: Alocao de bytes na memria do computador

10

CAPTULO 1. INTRODUO AOS ALGORITMOS

1.3.1

Linguagem de Mquina

O tipo mais primitivo de linguagem de programao chamado de linguagem de mquina, assim chamado porque a nica codicao que o computador entende diretamente. Os primeiros computadores baseados no modelo de Von Neumann utilizavam unicamente a programao em linguagem de mquina. A Figura 1.7 apresenta um trecho de um programa codicado em linguagem de mquina.

Figura 1.7: Trecho de programa em linguagem de mquina

1.3.2

Linguagem de Montagem

Uma linguagem de montagem ou assembly uma notao legvel por humanos para o cdigo de mquina de um computador. A linguagem de montagem foi a primeira evoluo no sentido de tornar a programao de computadores mais fcil e menos tediosa. A Figura 1.8 apresenta um trecho de um programa codicado em linguagem assembly.

Figura 1.8: Trecho de programa em linguagem de montagem

1.3. PROGRAMAO DE COMPUTADORES

11

Por exemplo, enquanto um computador sabe o que a instruo 10110000 01100001 faz, para os programadores mais fcil recordar a representao equivalente em uma instruo mnemnica da linguagem de montagem MOV AL 61. Tal instruo ordena que o valor hexadecimal 61 (97, em decimal) seja movido para o registrador AL do processador.

1.3.3 Linguagem de Alto NvelUma linguagem de alto nvel, ou orientada ao problema, permite que o programador especique a realizao de uma tarefa pelo computador de uma forma muito mais prxima da linguagem humana do que da linguagem de mquina ou de montagem. Uma das principais metas das linguagens de programao de alto nvel permitir que programadores tenham uma maior produtividade, permitindo expressar suas intenes mais fcil e rapidamente. Linguagens de programao de alto nvel tambm tornam os programas menos dependentes de computadores ou ambientes computacionais especcos (propriedade chamada de portabilidade). Isto acontece porque programas escritos em linguagens de programao de alto nvel so traduzidos para o cdigo de mquina especco do computador em que ser executado. Desde o surgimento do Fortran, centenas de linguagens de programao j foram desenvolvidas. A Figura 1.9 apresenta algumas das linguagens mais bem sucedidas ao longo dos ltimos 50 anos.

1.3.4 CompilaoCompilao o processo de anlise de um programa escrito em uma linguagem de alto nvel, chamado programa fonte (ou cdigo fonte) e sua converso (ou traduo) em um programa equivalente em linguagem binria de mquina (programa objeto ou cdigo objeto). O processo de compilao de um programa fonte em programa objeto feito pelo compilador da linguagem. Assim, um compilador C converte um cdigo fonte escrito em linguagem C para a linguagem de mquina do computador subjacente. A Figura 1.10 apresenta o processo de compilao.

1.3.5 LigaoExiste uma srie de tarefas que o programador no precisa incluir no cdigo fonte. Exemplos dessas tarefas so como apresentar informao na tela, como obter dados do teclado, como ler ou gravar em um disco rgido. O cdigo para essas tarefas em

12

CAPTULO 1. INTRODUO AOS ALGORITMOS

Figura 1.9: Linguagens de alto nvel bem sucedidas no ltimos 50 anos

1.3. PROGRAMAO DE COMPUTADORES

13

Figura 1.10: Processo de compilao

14

CAPTULO 1. INTRODUO AOS ALGORITMOS

geral organizado em arquivos formando uma biblioteca (library) de rotinas fornecida em conjunto com o compilador da linguagem. O que importa ao programador ligar (linkeditar) o cdigo objeto gerado pelo processo de compilao com as rotinas da biblioteca necessrias para a execuo do programa. A Figura 1.11 apresenta o processo de linkedio.

Figura 1.11: Processo de linkedio Todo esse processo seria muito simples se no ocorressem erros. Na prtica, o programador deve lidar com a possibilidade de acontecerem erros ao programar. Por exemplo, o compilador no ir gerar o cdigo objeto se houver algum erro no cdigo fonte (erro de compilao). Outro exemplo, um programa executvel no ser gerado a partir de um cdigo objeto se uma ou mais rotinas disponveis nas bibliotecas da linguagem no forem encontradas (erro de linkedio). Mesmo que todo o processo de compilao e ligao funcione corretamente, gerando um programa executvel, isso no garante que o programador no tenha cometido erros. necessrio vericar se a ao do programa corresponde de fato ao que foi projetado (erro de lgica).

1.4. ALGORITMOS

15

Portanto, o diagrama apresentado na Figura 1.12 ilustra de forma mais realstica a realidade do trabalho do programador.

1.4 AlgoritmosUm algoritmo consiste em uma sequncia de instrues sem ambiguidade que executada at que determinada condio se verique. O conceito de algoritmo frequentemente ilustrado pelo exemplo de uma receita, embora muitos algoritmos sejam mais complexos. Eles podem repetir passos (fazer iteraes) ou necessitar de decises (tais como comparaes ou lgica) at que a tarefa seja completada. Um algoritmo corretamente executado no ir resolver um problema se estiver implementado incorretamente ou se no for apropriado ao problema. Um algoritmo no representa, necessariamente, um programa de computador, e sim os passos necessrios para realizar uma tarefa. Sua implementao pode ser feita por um computador, por outro tipo de mquina ou mesmo por um ser humano. Diferentes algoritmos podem realizar a mesma tarefa usando um conjunto diferenciado de instrues em mais ou menos tempo, espao ou esforo do que outros. Tal diferena pode ser reexo da complexidade computacional aplicada. Por exemplo, um algoritmo para se vestir pode especicar que voc vista primeiro as meias e os sapatos antes de vestir a cala enquanto outro algoritmo especica que voc deve primeiro vestir a cala e depois as meias e os sapatos. Fica claro que o primeiro algoritmo mais difcil de executar que o segundo apesar de ambos levarem ao mesmo resultado. Etimologia: a palavra algoritmo tem origem no sobrenome, Al-Khwarizmi, do matemtico persa do sculo IX, Mohamed ben Musa, cujas obras foram traduzidas no ocidente cristo no sculo XII, tendo uma delas recebido o nome Algorithmi de numero indorum, sobre os algoritmos usando o sistema de numerao decimal.

1.4.1 PseudocdigoPseudocdigo uma forma genrica de escrever um algoritmo, utilizando uma linguagem simples (nativa a quem o escreve, de forma a ser entendida por qualquer pessoa) sem necessidade de conhecer a sintaxe de nenhuma linguagem de programao. Alguns livros introdutrios de programao utilizam algum tipo de pseudocdigo para ilustrar os seus exemplos, de forma que todos os estudantes possam

16

CAPTULO 1. INTRODUO AOS ALGORITMOS

Figura 1.12: Processo de linkedio

1.4. ALGORITMOS

17

entend-los independentemente da linguagem que vierem a utilizem. O Exemplo 1.1 apresenta um pseudocdigo em lngua portuguesa. Exemplo 1.1 Exemplo de pseudocdigo. escreva: Qual a nota do aluno? leia nota se nota maior ou igual a sete ento: escreva Ele passou seno: escreva: Ele foi reprovado fim do se fim do programa Embora no caso da lngua portuguesa existam alguns interpretadores de pseudocdigo, nenhum tem a projeo das linguagens Pascal ou C, que no caso da lngua inglesa se assemelham bastante a um pseudocdigo.

1.4.2 FluxogramaFluxograma um tipo de diagrama, e pode ser entendido como uma representao esquemtica de um processo. Em programao, trata-se de uma ferramenta para a elaborao de algoritmos que, em uma etapa posterior, podem usados como base para que o programador escreva um programa fonte. No existe uma padronizao para os smbolos utilizados em uxogramas. A Figura 1.13 apresenta alguns smbolos comumente empregados em uxogramas para representar algoritmos.

18

CAPTULO 1. INTRODUO AOS ALGORITMOS

Figura 1.13: Smbolos usados em uxogramas.

Captulo 2 Introduo Programao em CNada complicado se nos prepararmos previamente Confcio

2.1 Linguagem de Programao CC uma linguagem de programao criada em 1972, por Dennis Ritchie, no AT&T Bell Labs, para desenvolver o sistema operacional UNIX (que foi originalmente escrito em Assembly). Desde ento, tornou-se uma das linguagens de programao mais usadas, e inuenciou muitas outras, especialmente C++, que foi desenvolvida como uma extenso de C. Em 1978, Brian Kernighan e Dennis Ritchie publicaram a primeira edio do livro The C Programming Language. Esse livro, conhecido pelos programadores de C, como K&R, serviu durante muitos anos como uma especicao informal da linguagem. No m da dcada de 1970, C comeou a substituir BASIC como a linguagem de programao de microcomputadores mais usada. Durante a dcada de 1980, foi adaptada para uso no PC IBM, e a sua popularidade comeou a aumentar signicativamente. Ao mesmo tempo, Bjarne Stroustrup e sua equipe nos laboratrios Bell, comeou a trabalhar num projeto onde se adicionavam construes de orientao objetos linguagem C. O produto desse trabalho, chamado C++, nos dias de hoje a linguagem de programao mais usada no desenvolvimento do sistema operacional Windows e da maioria das aplicaes de grande porte; C permanece mais popular no mundo UNIX. Em 1983, o instituto norte-americano de padres (ANSI) formou um comit para estabelecer uma especicao do padro da linguagem C. Aps um processo longo e rduo, o padro foi completo em 1989 e raticado como ANSI X3.159-1989 19

20

CAPTULO 2. INTRODUO PROGRAMAO EM C

Programming Language C. Esta verso da linguagem frequentemente referida como ANSI C. Em 1990, o padro ANSI C, aps sofrer umas modicaes menores, foi adotado pela Organizao Internacional de Padres (ISO) como ISO/IEC 9899:1990.

2.1.1

Ambiente de Desenvolvimento Integrado para C

IDE, do ingls Integrated Development Environment ou Ambiente Integrado de Desenvolvimento, um programa de computador que rene caractersticas e ferramentas de apoio ao desenvolvimento de software com o objetivo de agilizar este processo. As caractersticas e ferramentas mais comuns encontradas nos IDEs so: Editor: edita o cdigo fonte do programa escrito nas linguagens suportadas pelo IDE; Compilador: compila o cdigo fonte do programa em cdigo objeto; Linkeditor: liga o cdigo objeto s bibliotecas necessrias e gera um cdigo executvel; Depurador: (debugger) auxilia no processo de encontrar e corrigir erros (bugs) no cdigo fonte do programa, na tentativa de aprimorar a qualidade de software; Os principais IDES disponveis atualmente como software livre e compatveis com o desenvolvimento em linguagem C na plataforma Windows so: Netbeans, Eclipse, Dev-C++ e Code::Block. Na disciplina Algoritmos do Bacharelado em Sistemas de Informao do CES/JF ser utilizado o IDE Dev-C++ disponvel em http://www.bloodshed.net/devcpp.html.

2.1.2

Exemplo Preliminar

Escreva seu primeiro programa fonte em linguagem C. Depois salve-o com o nome Exemplo1.c, compile e execute-o no IDE Dev-C. Para escrever um novo cdigo fonte, a partir do menu principal, selecione Arquivo Novo Arquivo Fonte. Digite as linhas de cdigo a seguir. #include int main(void) { printf("Alo, mundo!"); system("pause"); return 0; }

2.1. LINGUAGEM DE PROGRAMAO C

21

Para compilar, linkeditar e executar o programa, selecione Executar Compilar & Executar no menu principal do DEV-C ou utilize a hot-key F9. Se no houver erros de compilao ou ligao, a execuo dever apresentar em uma janela do DOS a mensagem: Alo, mundo! seguido de Pressione qualquer tecla para continuar... Entendendo o Exemplo Preliminar preciso entender todos os componentes desse programa fonte C. O termo #include trata-se de uma diretiva ao pr-processador. O arquivo de cabealho necessrio sempre que o programa C utilizar a instruo printf(). O programa C composto de uma ou mais funes. Uma funo um bloco de cdigo fonte que possui um nome e delimitado por chaves de abertura e fechamento. main() a funo mais importante em C porque a partir dela que tem incio a execuo do programa. No exemplo preliminar, a funo main() possui 3 linhas de cdigo. A linha de cdigo printf("Alo, mundo!"); uma instruo para exibir alguma informao na sada padro do computador (vdeo). Nesse exemplo, a informao a ser apresentada a cadeia de caracteres "Alo, mundo!". Observe que uma cadeia de caracteres deve ser delimitada por aspas duplas. A instruo printf() tambm uma funo, assim como main(), porm, no precisa ser codicada pelo programador. Ela faz parte da biblioteca de recursos da linguagem C. Uma funo pode receber argumentos para serem manipulados em seu cdigo. Os argumentos devem ser inseridos entre parnteses, logo aps o nome da funo. Assim, "Alo, mundo!" fornecido como argumento para a funo printf(). Observe que main seguido por (void) que signica, nesse contexto, sem argumentos, ou seja, nesse exemplo, nenhum argumento deve ser passado funo main(). Todas as trs linhas de cdigo no interior de main() terminam em ponto-evrgula. Isso uma exigncia do compilador C: toda instruo tem que terminar com esse caractere delimitador. A funo system("pause"); usada para fazer uma pausa na execuo do programa. Sem essa linha, o usurio no teria tempo de ver a sada do cdigo na tela. Ateno: voc deve salvar o seu cdigo fonte com o suxo .c do contrrio o Dev-C acusar erro de compilao na funo system(). Finalmente, a instruo return 0; especica que, ao terminar a execuo de main(), retornado um valor inteiro 0 (zero) para o Sistema Operacional subjacente. Esse cdigo representa que o programa terminou a execuo sem erros. Valores

22

CAPTULO 2. INTRODUO PROGRAMAO EM C

diferentes de zero podem ser usados para representar execues terminadas com algum tipo de erro. Os termos return, int e void so exemplos de palavras reservadas da linguagem C. Isso implica que possuem um signicado nico e denido para o compilador. Se voc digitar erradamente alguma delas o compilador acusar erro. No Dev-C observe que tais palavras so apresentadas sempre em negrito.

2.2

Sada de Dados na Sada Padro

A funo printf() a forma mais usual de se exibir informao na sada padro, ou seja, no monitor de vdeo. A funo printf() requer a biblioteca stdio.h que deve ser informada em uma diretiva ao pr-processador #include. Uma cadeia de caracteres permite a incluso de caracteres de controle, identicados pelo delimitador barra invertida (\). O caractere de controle \n signica avanar o cursor para o incio da prxima linha. O Exemplo 2.1 ilustra o emprego do caractere de controle \n para o avano do cursor. Exemplo 2.1 Emprego de funo printf() com caractere de controle para avano do cursor. #include int main(void) { printf("Alo, mundo!\n"); system("pause"); return 0; } Alo, mundo! Pressione qualquer tecla para continuar... A simples incluso de uma nova chamada funo printf() no implica no avano do cursor para o incio da prxima linha. Essa ao deve ser explicitamente representada pelo uso do caractere de controle \n. O Exemplo 2.2 gera a mesma sada do Exemplo 2.1 porm utilizando duas chamadas funo printf(). Exemplo 2.2 Funo printf() e uso do caractere de controle para avano do cursor.

2.2. SADA DE DADOS NA SADA PADRO #include int main(void) { printf("Alo, "); printf("mundo!\n"); system("pause"); return 0; } Alo, mundo! Pressione qualquer tecla para continuar...

23

Observe que programas fonte apresentados at o momento utilizam um recurso visual denominado indentao, onde os comandos presentes na funo main() entre as chaves de abertura e fechamento possuem um recuo na linha. O uso correto e consistente da indentao do cdigo fonte consiste em uma boa prtica de programao pois muito importante para facilitar a leitura e o entendimento do algoritmo e deve ser utilizado em todos os programas desenvolvidos. A Tabela 2.1 apresenta os principais caracteres de controle que podem ser utilizados para a formatao de sada com a funo printf(). Tabela 2.1: Caracteres de controle para uso na funo printf() Caractere \n \t \r \b \'' \' \\ Formatao Avano para o incio da prxima linha Avano para a prxima tabulao Retorno para o incio da linha atual Retrocesso Insero de uma aspas duplas Insero de um apstrofo Insero de uma barra invertida

Exerccio 2.1 Escreva um programa C para exibir na tela a sada: CES/JF SISTEMAS DE INFORMACAO DISCIPLINA: ALGORITMOS

24

CAPTULO 2. INTRODUO PROGRAMAO EM C

Exerccio 2.2 Escreva um programa C para exibir na tela a sada: 65 "A" 66 "B" 67 "C" 68 "D"

2.3

Comentrios em C

Uma boa prtica de programao consiste em documentar o cdigo fonte, com o objetivo de facilitar o seu entendimento e posterior manuteno. A documentao pode ser realizada atravs de comentrios, conforme apresentado no Exemplo 2.3. Exemplo 2.3 Comentrios em cdigo fonte C. /* Programa para exibir uma mensagem na tela */ #include int main(void) { printf("Alo, mundo!\n"); /* sada na tela */ system("pause"); return 0; } Qualquer trecho de cdigo fonte delimitado por /* e */ no considerado pelo compilador. Voc pode inserir comentrios em qualquer parte de um programa C. Comentrios de Linha Como alternativa, C oferece comentrios de linha, delimitados por //. Comentrios de linha podem ser inseridos em qualquer posio de uma linha no cdigo fonte e, nesse caso, o restante da linha ser desconsiderado durante o processo de compilao (Exemplo 2.4). Exemplo 2.4 Comentrios de linha em C. // Programa para exibir uma mensagem na tela #include int main(void) { printf("Alo, mundo!\n"); // sada na tela system("pause"); return 0; }

2.4. TIPOS DE DADOS PRIMITIVOS

25

2.4 Tipos de Dados PrimitivosOs tipos de dados primitivos com os quais C trabalha so os nmeros inteiros e os nmeros reais (tambm chamados nmeros de ponto utuante no contexto da linguagem). A insero do ponto decimal dene para o compilador C um valor numrico como sendo de ponto utuante e a delimitao por apstrofos dene um valor inteiro como sendo um caractere da tabela ASCII. Caracteres ASCII podem ser armazenados em qualquer tipo de dado inteiro, embora usualmente se usa o tipo char.

2.4.1 Tipos InteirosA linguagem C oferece mais de um tipo de dado inteiro conforme apresentado na Tabela 2.2, que inclui a faixa de valores vlida para o compilador do IDE DevC++. Observe que a faixa de valores pode variar entre os diversos compiladores C existentes. Tabela 2.2: Tipos de dados inteiros Tipo char short int int long int Bytes 1 2 4 4 Faixa de Valores -128 a +127 -32.768 a +32.767 -2.147.438.648 a +2.147.438.647 -2.147.438.648 a +2.147.438.647

Observe que caracteres da tabela ASCII so normalmente referenciados atravs do tipo inteiro char. Isso est correto. Lembre-se que cada cdigo ASCII corresponde a um nmero inteiro na tabela. Os tipos short int e long int podem ser abreviados por short e long respectivamente. Modicador unsigned O modicador unsigned altera a faixa de valores de cada um dos tipos primitivos apresentados ao descartar valores negativos. A Tabela 2.3 apresenta os valores mximos e mnimos para os tipos inteiros com o modicador unsigned.

26

CAPTULO 2. INTRODUO PROGRAMAO EM C Tabela 2.3: Tipos de dados inteiros com o modicador unsigned Tipo unsigned unsigned unsigned unsigned Bytes 1 2 4 4 Faixa de Valores 0 a +255 0 a +65.535 0 a +4.294.967.295 0 a +4.294.967.295

char short int int long int

2.4.2

Tipos de Ponto Flutuante

A linguagem C tambm oferece mais de um tipo de dado de ponto utuante para armazenamento de valores numricos reais, conforme apresentado na Tabela 2.4. Observe que a faixa de valores pode variar entre os diversos compiladores C existentes. Tabela 2.4: Tipos de dados de ponto utuante Tipo float double Bytes Faixa de Valores Preciso 38 4 3.4 10 6 dgitos decimais 308 8 1.7 10 15 dgitos decimais

2.4.3

Constantes

Uma constante representa um valor xo, que pode ser de qualquer um dos tipos primitivos apresentados. Observe que uma constante do tipo ponto utuante se diferencia de uma constante do tipo inteiro pela insero do ponto decimal. Constantes do tipo caractere devem ser delimitadas por apstrofos. O Exemplo 2.5 ilustra a aplicao dos tipos primitivos e de constantes em C. Exemplo 2.5 Tipos primitivos e constantes em C. #include int main(void) { printf("Inteiro..: %d\n",10); printf("Real.....: %f\n",10.);

2.5. ESPECIFICADORES DE FORMATO printf("Caractere: %c\n",'A'); system("pause"); return 0; } Inteiro..: 10 Real.....: 10.000000 Caractere: A

27

2.5 Especicadores de FormatoA funo printf() exige um especicador de formato para tipos primitivo includo como parte do argumento. Os principais especicadores de formato so %d para int, %f para float e %c para char. A constante cadeia de caracteres includa na funo printf(), delimitada por apstrofos, deve conter um especicador de formato para cada constante de um tipo primitivo a ser exibida. Aps a vrgula, informado o valor propriamente dito, compatvel com o especicador de formato denido. Por padro, valores do tipo ponto utuante float e double so apresentados com 6 dgitos decimais. Exerccio 2.3 Escreva um programa C para exibir na tela a sada a seguir usando tipos primitivos: 10 10.000000 A

2.6 Variveis de MemriaUma varivel consiste em um segmento de memria compreendendo um ou mais bytes contguos. Cada varivel deve possuir um nome, que usado para referenciar o local na memria onde encontram-se armazenadas as informaes guardadas na varivel. No possvel nomear duas variveis distintas com o mesmo nome. Recomendase empregar nomes mneumnicos ao se declarar variveis de memria. Entretanto, a denio de variveis em C deve seguir um conjunto de regras para nomeao. Pode conter letras maisculas e minsculas, dgitos numricos e o caractere de sublinhar.

28

CAPTULO 2. INTRODUO PROGRAMAO EM C Deve comear por letra ou caractere de sublinhar. Pode conter at 31 caracteres. Palavras reservadas da linguagem no podem ser usadas como nomes de variveis.

Alm disso, importante observar que C diferencia caracteres alfabticos maisculos e minsculos. Portanto, possvel, embora no seja recomendvel, denir variveis de memria distintas com nomes var1, VAR1 e Var1.

2.6.1

Declarao de Variveis na Memria

Para que uma varivel de memria possa ser utilizada em um programa C deve inicialmente ser declarada. A declarao requer, nessa ordem, a especicao do tipo de dado e do nome da varivel, conforme as regras para nomeao de variveis. uma boa prtica de programao declarar todas as variveis a serem usadas logo no incio do programa, antes de quaisquer outros comandos. Essa prtica facilita o entendimento do algoritmo e evita erros. A inicializao de uma varivel de memria feita a partir do operador de atribuio representado pelo smbolo de igualdade (=). O Exemplo 2.6 apresenta um programa fonte onde declarada e inicializada uma varivel de memria do tipo inteiro. Exemplo 2.6 Declarao e inicializao de uma varivel de memria do tipo inteiro. #include int main(void) { int num; num = 10; printf("Conteudo da variavel num: %d\n", num); system("pause"); return 0; } Conteudo da variavel num: 10 A especicao de formato deve ser compatvel com o tipo de dado. Caso ocorra inconsistncia entre o formato e o tipo de dado, o compilador no apresentar erro mas o valor ser exibido na sada padro de forma incorreta, conforme ilustrado no Exemplo 2.7.

2.7. COMANDO DE ATRIBUIO

29

Exemplo 2.7 Compatibilidade entre o tipo de dado e o especicador de formato. #include int main(void) { int num1 = 10; float num2 = 10; printf("%f %d\n",num1,num2); system("pause"); return 0; } 0.000000 1076101120

2.7 Comando de AtribuioComo possvel observar a partir dos Exemplos 2.6 e 2.7, o comando de atribuio (=) pode ser usado para alocar um determinado valor a uma varivel de memria, desde que compatvel com o tipo primitivo denido. A varivel que recebe o valor do comando de atribuio deve corresponder ao lado esquerdo do sinal de igualdade e o lado direito pode ser uma varivel, uma constante ou uma expresso aritmtica que contenha variveis, constantes e operadores aritmticos. Ateno: o comando de atribuio no pode ser entendido como igualdade aritmtica. A varivel de memria que recebe a atribuio deve obrigatoriamente estar do lado esquerdo da expresso. O Exemplo 2.8 apresenta um programa C com uso incorreto do comando de atribuio. Nesse caso, o compilador acusar erro de compilao. Exemplo 2.8 Uso incorreto do comando de atribuio em C. #include int main(void) { int num; 10 = num; // Uso incorreto do comando de atribuio. printf("Conteudo da variavel num: %d\n", num); system("pause"); return 0; }

30

CAPTULO 2. INTRODUO PROGRAMAO EM C

A expresso no lado direito de um comando de atribuio pode conter constantes e variveis, conforme apresentado no Exemplo 2.9 Exemplo 2.9 Exemplos de comandos de atribuio com constantes e variveis. #include int main(void) { int num1; num1 = 10; int num2; num2 = num1; printf("num1: %d\n", num1); printf("num2: %d\n", num2); system("pause"); return 0; } num1: 10 num2: 10 Exerccio 2.4 Escreva um programa C para denir 3 variveis, uma de cada um dos tipos primitivos apresentados (int, float e char), atribuir valores e exibir os valores atribudos na tela. Exerccio 2.5 Ainda no programa do Exerccio 2.4, inclua linhas de instruo para alterar os valores das variveis denidas e reapresente os valores na tela. Observe que a declarao e a inicializao de uma varivel de memria podem ser denidos em uma nica linha de cdigo, conforme apresentado no Exemplo 2.10. Exemplo 2.10 Declarao e atribuio de valor a varivel em uma nica instruo. #include int main(void) { int num = 10; printf("Conteudo da variavel num: %d\n", num); system("pause"); return 0; } Conteudo da variavel num: 10

2.8. OPERADORES ARITMTICOS

31

2.8 Operadores AritmticosAs operaes aritmticas fundamentais empregam os seguintes smbolos em C: + para a adio, - para a subtrao, * para a multiplicao e / para a diviso. Na linguagem C, um operador aritmtico deve ser utilizado em conjunto com dois operandos, que podem ser constantes ou variveis numricas. Por padro, uma operao aritmtica na qual os dois operandos forem do tipo inteiro processada como uma operao inteira e o resultado tambm um valor do tipo inteiro (Exemplo 2.11). Se pelo menos um dos operandos for do tipo ponto utuante, a operao ser processada em ponto utuante e o resultado ser um valor em ponto utuante (Exemplo 2.12). Exemplo 2.11 Operadores aritmticos onde os operandos so valores numricos do tipo inteiro. #include int main(void) { int num1 = 10; int num2 = 5; printf("Adicao.......: printf("Subtracao....: printf("Multiplicacao: printf("Divisao......: system("pause"); return 0; } Adicao.......: Subtracao....: Multiplicacao: Divisao......: 15 5 25 2

%d\n", %d\n", %d\n", %d\n",

10 + 5); num1 - 5); 5 * num2); num1 / num2);

Exemplo 2.12 Operadores aritmticos onde os operandos so valores numricos de ponto utuante. #include int main(void) { float num1 = 10; float num2 = 5; printf("Adicao.......: %f\n", 10.0 + 5.);

32

CAPTULO 2. INTRODUO PROGRAMAO EM C printf("Subtracao....: %f\n", num1 - 5.); printf("Multiplicacao: %f\n", 5.0 * num2); printf("Divisao......: %f\n", num1 / num2); system("pause"); return 0;

} Adicao.......: Subtracao....: Multiplicacao: Divisao......: 15.000000 5.000000 25.000000 2.000000

Observe que uma constante numrica com ponto decimal interpretada pelo compilador C como sendo de ponto utuante.

2.8.1

Operador Menos Unrio

Como exceo, o operador para a subtrao pode ser empregado com um nico operando, conforme apresentado no Exemplo 2.13. Exemplo 2.13 Operador Menos Unrio. #include int main(void) { int num = 10; num = -num; printf("%d\n", num); system("pause"); return 0; } -10

2.8.2

Operador Mdulo

Alm das quatro operaes aritmticas bsicas, C oferece o operador mdulo ou resto da diviso inteira, cujo smbolo %. Observe que a operao de resto da diviso inteira vlida apenas quando usada com variveis ou constantes do tipo primitivo inteiro. Os Exemplos 2.14 e 2.15 ilustram a aplicao do operador mdulo.

2.8. OPERADORES ARITMTICOS Exemplo 2.14 Resto da diviso inteira com constantes do tipo inteiro. #include int main(void) { printf("Modulo %d\n", 10 % 3); system("pause"); return 0; } Modulo 1

33

Exemplo 2.15 Resto da diviso inteira com varivel e constante do tipo inteiro. #include int main(void) { int n = 10; printf("Modulo %d\n", n % 3); system("pause"); return 0; } Modulo 1 Observe a partir do Exemplo 2.16 que no h limite para o nmero de constantes ou variveis em um nico printf(). Exemplo 2.16 Funo printf() com mais de um caractere de controle. #include int main(void) { int num1 = 10; int num2 = 3; int num3 = num1 + num2; printf("%d + %d = %d\n", num1, num2, num3); system("pause"); return 0; } 10 + 3 = 13

34

CAPTULO 2. INTRODUO PROGRAMAO EM C

2.8.3

Diviso Inteira

A operao de diviso processada de acordo com o tipo dos operandos associados. Caso os dois operadores sejam do tipo inteiro, a diviso tambm ser inteira e o resultado, consequentemente ser inteiro (Exemplo 2.17). Exemplo 2.17 Diviso com operandos inteiros. #include int main(void) { int num1 = 10; int num2 = 3; int num3 = num1 / num2; printf("%d / %d = %d\n", num1, num2, num3); system("pause"); return 0; } 10 / 3 = 3 Em uma operao de diviso com operandos do tipo inteiro, mesmo que o valor calculado seja atribudo a uma varivel de ponto utuante, a operao de diviso permanece inteira (Exemplo 2.18). Exemplo 2.18 Diviso com operandos inteiros e atribuio a varivel de ponto utuante. #include int main(void) { int num1 = 10; int num2 = 3; float num3 = num1 / num2; printf("%d / %d = %f\n", num1, num2, num3); system("pause"); return 0; } 10 / 3 = 3.000000 Se pelo menos um dos operandos envolvidos em uma operao de diviso for do tipo ponto utuante ento a operao ser real e o resultado ser um nmero de ponto utuante (Exemplo 2.19).

2.8. OPERADORES ARITMTICOS Exemplo 2.19 Diviso com operandos de tipos distintos. #include int main(void) { int num1 = 10; float num2 = 3; float num3 = num1 / num2; printf("%d / %f = %f\n", num1, num2, num3); system("pause"); return 0; } 10 / 3.000000 = 3.333333

35

2.8.4 Precedncia de Operadores AritmticosA precedncia dos operadores aritmticos apresentada na Tabela 2.5. Tabela 2.5: Precedncia de operadores aritmticos Operador ( ) * / % + Descrio Parnteses Menos unrio Multiplicao, diviso e mdulo Adio e subtrao

Como pode ser observado, o uso de parnteses permite a mudana na ordem de precedncia dos operadores. O Exemplo 2.20 ilustra alguns casos de precedncia entre operadores. Exemplo 2.20 Precedncia em operadores. #include int main(void) { int num; num = 2 + 3 * 5; printf("%d \n", num); num = (2 + 3) * 5;

36

CAPTULO 2. INTRODUO PROGRAMAO EM C printf("%d \n", num); num = -num * 2 + 50; printf("%d \n", num); system("pause"); return 0;

} 17 25 0

2.8.5

Expresses Aritmticas no Corpo da Funo printf()

Embora no seja uma boa prtica de programao, possvel inserir expresses aritmticas no corpo da funo printf(), conforme apresentado no Exemplo 2.21. Exemplo 2.21 Expresso matemtica no corpo da funo printf(). #include int main(void) { int num1 = 10; int num2 = 3; printf("%d + %d = %d\n", num1, num2, num1 + num2); system("pause"); return 0; } 10 + 3 = 13 Exerccio 2.6 Escreva um programa C para denir e atribuir valor a 2 variveis de memria do tipo int. Exibir na tela o resultado das cinco operaes aritmticas com as variveis denidas. Exerccio 2.7 Escreva um programa C para denir e atribuir valor a 2 variveis de memria do tipo float. Exibir na tela o resultado das quatro operaes aritmticas bsicas com as variveis denidas. Exerccio 2.8 Escreva um programa C para denir e atribuir valor a 2 variveis de memria, uma do tipo int e uma do float. Exibir na tela o resultado das quatro operaes aritmticas bsicas com as variveis denidas.

2.9. CONTROLE E FORMATAO DE SADA

37

2.9 Controle e Formatao de Sada2.9.1 Controle do Nmero de Dgitos DecimaisPor padro, a sada de valores de ponto utuante na sada padro (vdeo) a partir da funo printf() exibida com 6 dgitos decimais. O modicador de preciso permite controlar o nmero de dgitos decimais, conforme apresentado no Exemplo 2.22. Exemplo 2.22 Controle do nmero de dgitos decimais com o modicador de preciso. #include int main(void) { float num1 = 10; float num2 = 3; float num3 = num1 / num2; printf("%.1f / %.1f = %.1f\n", num1, num2, num3); system("pause"); return 0; } 10.0 / 3.0 = 3.3

2.9.2 Controle do Comprimento do Campo de SadaAlm do nmero de dgitos decimais, o especicador de formato usado na funo printf() permite controlar o comprimento total do campo de sada para todos os tipos de dados numricos, conforme apresentado no Exemplo 2.23. Exemplo 2.23 Controle do comprimento do campo de sada na funo printf(). #include int main(void) { float num1 = 10; int num2 = 3; float num3 = num1 / num2; printf("%5.1f / %4d = %5.1f\n", num1, num2, num3); system("pause");

38 return 0; } 10.0 / 3 =

CAPTULO 2. INTRODUO PROGRAMAO EM C

3.3

Observe que se o especicador de formato denir um comprimento de campo menor que o mnimo necessrio para a correta exibio do valor numrico a ser exibido, o compilador C ir desconsiderar o tamanho do campo especicado (Exemplo 2.24). Exemplo 2.24 Controle de comprimento do campo menor que o necessrio para exibio do valor numrico. #include int main(void) { float num1 = 100; int num2 = 3; float num3 = num1 / num2; printf("%3.1f / %1d = %2.1f\n", num1, num2, num3); system("pause"); return 0; } 10.0 / 3 = 33.3

2.9.3

Exibio de Zeros No Signicativos

O controle do comprimento de campo permite tambm a exibio dos zeros no signicativos na sada de valores numricos a partir da funo printf(). Esse recurso obtido ao antepor-se um dgito 0 entre o especicador de formato % e o controle do comprimento de campo, conforme apresentado no Exemplo 2.25. Exemplo 2.25 Exibio de zeros no signicativos a partir do controle do comprimento do campo. #include int main(void) { float num1 = 3.1416; int num2 = 323;

2.10. DEFINIO DE CONSTANTES NA MEMRIA printf("%08.4f\n", num1); printf("%06d\n",num2); system("pause"); return 0; } 003.1416 000323

39

2.9.4 Alinhamento EsquerdaPor padro, valores numricos so alinhados direita. possvel, entretanto, modicar a exibio dos valores numricos alterando-se o alinhamento para a esquerda, conforme apresentado no Exemplo 2.26. Exemplo 2.26 Alinhamento de valores numricos esquerda. #include int main(void) { float num1 = 100.0; int num2 = 15; printf("%7.1f\n",num1); printf("%-7.1f\n",num1); printf("%5d\n",num2); printf("%-5d\n",num2); system("pause"); return 0; } 100.0 100.0 15 15

2.10 Denio de Constantes na MemriaPara se denir uma constante na memria e alocar um valor que no pode ser alterado posteriormente durante a execuo do programa, utiliza-se a palavra reservada

40

CAPTULO 2. INTRODUO PROGRAMAO EM C

const (Exemplo 2.27). Observe que se o programador tentar alterar o valor de uma constante previamente denida, o compilador acusar um erro. Exemplo 2.27 Declarao de constantes na memria. #include int main(void) { int raio = 2; const float pi = 3.1415926; float area; area = pi * raio * raio; printf("Area do circulo de raio %d: %.2f\n",raio, area); system("pause"); return 0; } Area do circulo de raio 2: 12.57

2.11 Entrada de Dados na Entrada PadroA funo scanf() a forma mais usual de fazer a entrada de dados a partir da entrada padro (teclado). Para seu correto funcionamento necessrio especicar a biblioteca . A funo scanf() recebe como argumento uma constante cadeia de caracteres com um ou mais especicadores de formato seguido por um ou mais endereos de memria de variveis previamente denidas no cdigo fonte do programa C. O Exemplo 2.28 apresenta um caso de uso simples da funo scanf(). Exemplo 2.28 Funo para entrada de dados scanf(). #include int main(void) { int num; printf("Digite um numero inteiro: "); scanf("%d", &num); printf("Voce digitou o numero %d.\n", num); system("pause"); return 0; }

2.11. ENTRADA DE DADOS NA ENTRADA PADRO

41

Digite um numero inteiro: 6 Voce digitou o numero 6. A varivel de memria que recebe o valor digitado pelo usurio deve ser precedida pelo operador endereo de memria, representado pelo smbolo &. A omisso do operador & no causa erro de compilao mas pode determinar a abortagem da execuo do programa.

2.11.1 Especicadores de Formato para scanf()A funo scanf() exige a especicao do tipo de dado, com os mesmos especicadores de formato usados na funo printf(): %d para tipos inteiros, %f para tipos de ponto utuante e %c para caracteres da tabela ASCII. A funo scanf() permite a entrada de dados para mais de uma varivel de memria. Nesse caso, para cada entrada de dados, deve corresponder um especicador de formato e uma varivel de memria precedida pelo operador de endereo (Exemplo 2.29). Exemplo 2.29 Entrada de mltiplos valores com scanf(). #include int main(void) { int num1; int num2; printf("Digite dois numeros inteiros: "); scanf("%d%d", &num1, &num2); printf("Voce digitou os numeros %d e %d.\n", num1, num2); system("pause"); return 0; } Digite dois numeros inteiros: 4 7 Voce digitou os numeros 4 e 7. A funo scanf() tambm permite o uso do especicador de tamanho para delimitar o nmero de caracteres a serem alocados para uma varivel. O Exemplo 2.30 apresenta um caso de uso desse recurso.

42

CAPTULO 2. INTRODUO PROGRAMAO EM C

Exemplo 2.30 Controle do nmero de caracteres aceitos para uma varivel a partir do especicador de tamanho na funo scanf(). #include int main(void) { int dia; int mes; int ano; printf("Digite a data atual no formato DDMMAAAA: "); scanf("%2d%2d%4d", &dia, &mes, &ano); printf("Data: %02d/%02d/%d\n", dia, mes, ano); system("pause"); return 0; } Digite a data atual no formato DDMMAAAA: 09082010 Data: 09/08/2010 Tambm possvel inserir outros caracteres no especicador de formato de uma chamada funo scanf(). Nesse caso, o respectivo caractere deve ser informado na entrada de dados do usurio na posio solicitada. O Exemplo 2.31 ilustra o recurso. Exemplo 2.31 Outros caracteres na entrada de dados atravs da funo scanf(). #include int main(void) { int hora; int min; printf("Digite a hora atual no formato HH:MM "); scanf("%2d:%2d", &hora, &min); printf("%2d horas e %2d minutos.\n", hora, min); system("pause"); return 0; } Digite a hora atual no formato HH:MM 14:47 14 horas e 47 minutos. Exerccio 2.9 Escreva um programa C que solicite ao usurio a entrada de 3 nmeros inteiros quaisquer. O programa deve calcular e apresentar na tela a soma dos nmeros informados pelo usurio.

2.12. CONSTANTES E FUNES MATEMTICAS

43

Exerccio 2.10 Escreva um programa C que solicite ao usurio a entrada de 3 nmeros reais quaisquer. O programa deve calcular e apresentar na tela a mdia aritmtica dos nmeros. Exerccio 2.11 Escreva um programa C que solicite ao usurio o salrio de um funcionrio e que calcule e mostre na tela o novo salrio, sabendo-se que houve um reajuste de 12.5%. Exerccio 2.12 Escreva um programa C que calcule e apresente na tela a rea de um tringulo retngulo. Os valores da base e altura devem ser fornecidos pelo usurio em tempo de execuo. Exerccio 2.13 Escreva um programa C que solicite ao usurio a digitao do seu ano de nascimento. O programa deve calcular e apresentar na tela: (a) a idade do usurio e (b) em qual ano ter 65 anos. Exerccio 2.14 Escreva um programa C que calcule e apresente na tela a mdia ponderada de duas notas fornecidas pelo usurio em tempo de execuo. Considere peso 2 para a primeira prova e 3 para a segunda prova. Exerccio 2.15 Escreva um programa C que solicite ao usurio o valor da hora atual no formato HHMMSS. O programa deve calcular e mostrar na tela o total de segundos transcorridos desde o incio do dia. Exerccio 2.16 Escreva um programa C que solicite ao usurio a digitao de um nmero real. O programa deve exibir na tela o valor inteiro mais prximo do nmero real informado. Por exemplo, se o nmero digitado for 3.8, o valor inteiro mais prximo 4. Exerccio 2.17 Escrever um programa C que solicite ao usurio a digitao de um nmero inteiro no intervalo [100, 999]. Calcular a soma dos algarismos do nmero digitado. Por exemplo, se o nmero for 234, a soma deve ser 9.

2.12 Constantes e Funes MatemticasO arquivo de cabealho math.h inclui as declaraes necessrias para diversas funes matemticas disponveis nos compiladores C, incluindo-se funes para calcular potncia e raiz quadrada, funes trigonomtricas para clculos que envolvem seno,

44

CAPTULO 2. INTRODUO PROGRAMAO EM C

cosseno e tangente, alm de constantes para nmeros irracionais como, por exemplo, e 2. Uma chamada a uma funo matemtica pode ser ser associada a um comando de atribuio ou utilizada diretamente em um printf() para exibio na sada padro do sistema. O Exemplo 2.32 apresenta a chamada a uma funo matemtica em um comando de atribuio. Exemplo 2.32 Clculo do valor absoluto de um nmero inteiro fornecido pelo usurio. #include #include int main(void) { int num; int valorabs; printf("Digite um numero inteiro qualquer: "); scanf("%d", &num); valorabs = abs(num); printf("Valor absoluto de %d: %d.\n", num, valorabs); system("pause"); return 0; } Digite um numero inteiro qualquer: -5 Valor absoluto de -5: 5. O Exemplo 2.33 apresenta a chamada a uma funo matemtica em um printf(). Exemplo 2.33 Clculo do valor absoluto de um nmero inteiro fornecido pelo usurio. #include #include int main(void) { int num; printf("Digite um numero inteiro qualquer: "); scanf("%d", &num); printf("Valor absoluto de %d: %d.\n", num, abs(num)); system("pause"); return 0;

2.12. CONSTANTES E FUNES MATEMTICAS } Digite um numero inteiro qualquer: -8 Valor absoluto de -8: 8.

45

2.12.1 Constantes MatemticasA Tabela 2.6 apresenta diversas constantes matemticas denidas na biblioteca math.h. Todas as constantes so denidas como nmeros de ponto utuante do tipo double. Tabela 2.6: Constantes matemticas denidas em math.h Smbolo e log2 e log10 e /2 /4 2 Descrio Nmero de Euler Logaritmo de e na base 2 Logaritmo de e na base 10 Pi Meio Pi Quarto de Pi Raiz quadrada de 2 Constante M_E M_LOG2E M_LOG10E M_PI M_PI_2 M_PI_4 M_SQRT2 Valor 2.7182818284590452354 1.4426950408889634074 0.43429448190325182765 3.14159265358979323846 1.57079632679489661923 0.78539816339744830962 1.41421356237309504880

2.12.2 Funes MatemticasAs funes matemticas da biblioteca math.h retornam valores numricos do tipo double.

Funes Trigonomtricas As funes trigonomtricas recebem como argumento o ngulo em radiano. sin(double) retorna o valor do seno. cos(double) retorna o valor do cosseno. tan(double) retorna o valor da tangente.

46

CAPTULO 2. INTRODUO PROGRAMAO EM C

Funes Logaritmicas log2(double) retorna o valor do logaritmo na base 2. log10(double) retorna o valor do logaritmo na base 10. log(double) retorna o valor do logaritmo neperiano (ou natural), na base e. Potncias pow(double, double) retorna o valor da base elevada ao expoente. Recebe dois argumentos do tipo double, o primeiro a base e o segundo o expoente. sqrt(double) retorna o valor da raiz quadrada. Arredondamento ceil(double) retorna o primeiro double sem casas decimais acima do valor fornecido como argumento. Exemplo: ceil(45.98561) retorna 46. floor(double) retorna o primeiro double sem casas decimais abaixo do valor fornecido como argumento. Exemplo: floor(45.98561) retorna 45.

2.12.3

Valor Absoluto

abs(int) retorna o valor absoluto de um nmero inteiro fornecido como argumento. O retorno um nmero inteiro. fabs(double) retorna o valor absoluto de um double fornecido como argumento. O retorno um double. Exemplo 2.34 Emprego de constante e de funo matemtica da biblioteca math.h para o clculo do seno de um ngulo cujo ngulo fornecido pelo usurio em graus. #include #include int main(void) { int angulo; float radiano; printf("Digite o angulo em graus: "); scanf("%d", &angulo); radiano = angulo * M_PI / 180; printf("Seno de %d graus: %f\n", angulo,sin(radiano)); system("pause");

2.12. CONSTANTES E FUNES MATEMTICAS return 0; } Digite o angulo em graus: 30 Seno de 30 graus: 0.50000

47

Exerccio 2.18 Escreva o programa C para o calculo da area de um circulo utilizando a funao matemtica pow(). Exerccio 2.19 Escreva um programa C que solicite ao usuario em tempo de execuo o raio R e que calcule e mostre na tela a rea A e o volume V de uma esfera dados por 4R3 A = 4R2 e V = 3 Exerccio 2.20 Escreva um programa C que que solicite ao usuario em tempo de execuao as coordenadas x e y de dois pontos quaisquer do plano cartesiano e que calcule e mostre na tela a distancia entre os pontos. Exerccio 2.21 Escreva um programa C que que solicite ao usuario em tempo de execuao o valor de um angulo em graus e que calcule e mostre na tela os valores da cosecante e da cotangente. Lembre-se que 180 equivale a radianos. Exerccio 2.22 A funo exponencial usada para calcular a desintegrao do carbono 14 atravs da equao y(t) = y0 e0.00012t , onde y0 a massa inicial da substncia medida em gramas e t o tempo transcorrido, medido em anos. Escreva um programa C que solicite ao usurio a massa inicial de uma amostra de carbono 14 e que apresente na sada padro a massa aps 10, 100 e 1000 anos.

48

CAPTULO 2. INTRODUO PROGRAMAO EM C

Captulo 3 Estruturas de SeleoQuem pouco pensa, muito erra. Leonardo da Vinci

Todos os programas apresentados ate o momento sao executados exatamente na ordem em que as instruoes sao escritas, do incio ate o m. A maioria dos algoritmos a serem implementados em uma linguagem de programaao nao seguem essa sequencia. A razao para isso e que muitas vezes e necessario tomar uma decisao e, a partir da, continuar a execuao de uma maneira ou de outra.

3.1 Operadores RelacionaisPara tomar uma deciso necessrio um mecanismo para se comparar valores. A linguagem C oferece um conjunto de operadores relacionais com esse objetivo, conforme apresentado na Tabela 3.1. Tabela 3.1: Operadores Relacionais Smbolo < >= == != Descrio Menor que Menor ou igual a Maior que Maior ou igual a Igual a Diferente de

49

50

CAPTULO 3. ESTRUTURAS DE SELEO

3.1.1

Expresses Envolvendo Operadores Relacionais

A partir dos operadores relacionais apresentados na Tabela 3.1 possvel elaborar expresses lgicas ou booleanas. Tais expresses podem resultar em apenas um de dois valores possveis: verdadeiro ou falso. Na linguagem C, um valor logicamente verdadeiro representado pelo nmero 1 e um valor logicamente falso representado pelo nmero 0. O Exemplo 3.1 ilustra a aplicao dos operadores relacionais em expresses lgicas. Exemplo 3.1 Operadores relacionais em expresses lgicas. #include int main(void) { printf("%d\n",5>4); printf("%d\n",1==2); printf("%d\n",'A'!='a'); system("pause"); return 0; } 1 0 1

3.2

Estruturas de Seleo da Linguagem C

As estruturas de seleo permitem que o programa possa decidir o caminho a seguir durante a execuo. Por exemplo, dependendo do valor de uma varivel, uma estrutura de deciso pode executar um conjunto de comandos ou no. As estruturas de seleo utilizam os operadores relacionais para compor expresses lgicas e decidir qual o caminho que a execuo de um programa deve seguir dependendo do resultado da expresso, ou seja, verdadeiro ou falso.

3.2.1

Estrutura de Seleo if-else

O comando if-else a estrutura de seleo mais utilizada na maioria das linguagens de programao. Basicamente, utilizada quando torna-se necessrio escolher

3.2. ESTRUTURAS DE SELEO DA LINGUAGEM C entre dois caminhos possveis para a execuo do programa. A forma geral do comando if-else dada por if (expresso lgica) bloco de comandos 1; else bloco de comandos 2;

51

Atente para o uso de parnteses para delimitar a expresso lgica a ser avaliada na estrutura de seleo if-else. O comando if-else avalia o valor da expresso lgica e, caso o resultado seja verdadeiro, o bloco de comandos 1 executado. Caso o resultado seja falso, o bloco de comandos 2, associado clusula else, executado. Entende-se por bloco de comandos um conjunto formado por um ou mais comandos da linguagem C. Observe que em uma dada execuo do programa executado apenas o bloco de comandos 1, associado ao resultado verdadeiro para a expresso lgica avaliada, ou o bloco de comandos 2, associado ao resultado falso para a expresso lgica avaliada. O Exemplo3.2 ilustra o emprego da estrutura de seleo if-else usando expresses lgicas para denir o caminho a ser seguido pela execuo do programa. Exemplo 3.2 Programa C que solicita ao usurio a digitao de um nmero inteiro qualquer e verica se igual ou diferente de 10. #include int main(void) { int num; printf("Digite um numero inteiro: "); scanf("%d",&num); if(num == 10) printf("O numero %d eh igual a 10.\n",num); else printf("O numero %d eh diferente de 10.\n",num); system("pause"); return 0; } Digite um numero inteiro: 11 O numero 11 eh diferente de 10.

52

CAPTULO 3. ESTRUTURAS DE SELEO

Exerccio 3.1 Escreva um programa C que solicite ao usuario a digitaao de um nmero inteiro N em tempo de execuao. O programa deve calcular e apresentar na tela N caso N 0 ou N 2 caso N < 0. Exerccio 3.2 Escreva um programa C que solicite ao usuario a digitaao de dois nmeros inteiros em tempo de execuao. O programa deve vericar se os nmeros digitados so iguais ou diferentes. Exerccio 3.3 Escreva um programa C que solicite ao usuario a digitaao de dois nmeros quaisquer em tempo de execuao. O programa deve apresentar na tela o maior dos dois nmeros informados. Exerccio 3.4 Escreva um programa C que solicite ao usuario a digitaao das quatro notas de um aluno e que calcule e apresente na tela a media aritmetica das notas e uma mensagem de aprovado ou reprovado, considerando para aprovaao a media maior ou igual a 70. Considere as notas como sendo nmeros inteiros no intervalo [0, 100]. Uma vez que para a linguagem C todo nmero diferente de 0 considerado logicamente verdadeiro e o 0 considerado logicamente falso, o Exemplo 3.3 apresenta um comando de seleo if-else que baseia-se nessa caracterstica para denir se um nmero informado pelo usurio nulo ou no. Exemplo 3.3 Programa C que solicita ao usurio a digitao de um nmero inteiro qualquer e verica se igual ou diferente de 0. #include int main(void) { int num; printf("Digite um numero inteiro: "); scanf("%d",&num); if(num) // num verdadeiro, isto , num diferente de 0? printf("Numero %d -> diferente de 0\n",num); else printf("Numero %d -> igual a 0\n",num); system("pause"); return 0; } Digite um numero inteiro: 3 Numero 3 -> diferente de 0.

3.2. ESTRUTURAS DE SELEO DA LINGUAGEM C

53

Exerccio 3.5 Escreva um programa C que solicite ao usuario a digitaao de um nmero inteiro e positivo qualquer e que verique se o nmero digitado par ou mpar. Exerccio 3.6 Escreva um programa C que solicite ao usuario a digitaao de um numerico inteiro e positivo em tempo de execuao. O programa deve informar na tela se o numero e ou no divisivel por 5. Estrutura de Seleo if Sem Clusula else A clusula else no obrigatria. O Exemplo 3.4 apresenta um programa C que emprega a estrutura de seleo if sem a clusula else. Exemplo 3.4 Programa C que solicita ao usurio a digitao de um nmero inteiro qualquer e que calcula o valor absoluto. #include int main(void) { int num; printf("Digite um numero inteiro qualquer: "); scanf("%d", &num); if(num < 0) num = -num; printf("Valor absoluto: %d\n",num); system("pause"); return 0; } Digite um numero inteiro: -1 Valor absoluto: 1 Exerccio 3.7 Escreva um programa C que solicite ao usuario a digitaao de um nmero inteiro N em tempo de execuao. O programa deve calcular e exibir o logaritmo neperiano (log N ) caso N 0 ou o prprio nmero N, caso N < 0. Uso de Blocos de Cdigo em Estruturas if-else Retornando forma geral do comando if-else, dada por

54 if (expresso lgica) bloco de comandos 1; else bloco de comandos 2;

CAPTULO 3. ESTRUTURAS DE SELEO

importante observar que quando houver mais de um comando associado ao bloco de comandos 1 ou ao bloco de comandos 2, ento torna-se necessrio delimitar por chaves de abertura e de fechamento o conjunto de comandos. A esse conjunto de instrues C delimitadas por chaves de abertura e fechamento d-se o nome de bloco de cdigo. Como poder ser visto ao longo do curso, em muitas situaes um bloco de cdigo exigido por diversos comandos da linguagem C quando h mais de uma instruo a ser executada. Embora no seja necessrio, permitido delimitar-se por chaves de abertura de fechamento um bloco de cdigo que contenha apenas um nico comando. O Exemplo 3.5 ilustra a aplicao de blocos de cdigo em um comando if-else. Observe que o bloco de cdigo associado clusula else possui apenas um nico comando. Nesse caso, a delimitao do bloco por chaves opcional. Ateno: o uso incorreto de chaves de abertura e de fechamento fonte de erros ao compilar um programa C. Procure sempre vericar se para cada chave de abertura corresponde uma chave de fechamento. Exemplo 3.5 Programa C que solicita ao usurio a digitao de um nmero inteiro e positivo e que calcula e exibe a raiz quadrada e a raiz cbica. Uma mensagem de erro apresentada caso o nmero digitado no seja positivo. #include #include int main(void) { int num; printf("Digite um numero inteiro e positivo: "); scanf("%d", &num); if(num > 0) { printf("Raiz quadrada: %f\n",sqrt(num)); printf("Raiz cubica..: %f\n",pow(num,0.333)); } else { printf("Erro. Numero nao positivo.\n"); } system("pause"); return 0;

3.2. ESTRUTURAS DE SELEO DA LINGUAGEM C } Digite um numero inteiro e positivo: 9 Raiz quadrada: 3 Raiz cubica..: 2.078561

55

Exerccio 3.8 Segundo uma tabela medica, o peso ideal esta relacionado com a altura e o sexo. Fazer um programa C que receba, em tempo de execuao, a altura H e o sexo de uma pessoa e que calcule e imprima o seu peso ideal, utilizando as seguintes formulas: (a) para homens: 72.7 H58 e (b) para mulheres 62.1 H44.7. Estruturas if-else Aninhadas Para escrever muitos algoritmos torna-se necessrio empregar estruturas de seleo aninhadas, ou seja, uma dentro da outra. Uma vez que cada estrutura if-else permite apenas selecionar entre dois valores lgicos (verdadeiro ou falso), a soluo para algoritmos que envolvam mais de duas condies possveis recai no emprego de estruturas aninhadas conforme mostrado no Exemplo 3.6. Exemplo 3.6 Programa C que solicita ao usurio a digitao da idade I de uma pessoa e que verica se menor de idade (I < 18), maior de idade ou idoso (I 65). #include #include int main(void) { int idade; printf("Digite a idade: "); scanf("%d", &idade); if(idade < 18) printf("Menor de idade.\n"); else if(idade < 65) printf("Maior de idade.\n"); else printf("Idoso.\n"); system("pause"); return 0; } Digite a idade: 30 Maior de Idade.

56

CAPTULO 3. ESTRUTURAS DE SELEO

Exerccio 3.9 Escreva um programa C que receba dois numeros e execute as operaoes listadas a seguir, de acordo com a escolha do usuario. Se a opao digitada for invalida, mostrar uma mensagem de erro. Observe que no possvel calcular a diviso quando o divisor for nulo. 1. 2. 3. 4. media entre os numeros digitados; diferena do maior pelo menor; produto dos numeros digitados; divisao do maior pelo menor.

Exerccio 3.10 Escreva um programa C que solicite ao usuario a digitao de duas notas de um aluno (no intervalo [0, 100]) e que calcule e apresente na tela a media aritmetica das notas e a mensagem segundo a regra: media menor que 40 Reprovado media entre 40 e 70 Exame nal media maior que 70 Aprovado

3.3

Operadores Lgicos

Muitas vezes as expresses relacionais a serem avaliadas necessitam combinar mais de uma condio utilizando-se os operadores relacionais apresentados anteriormente na Tabela 3.1. Por exemplo, pode ser necessrio executar uma ao se um determinado nmero est um intervalo especco [a, b], ou seja, deve ser no menor que a e no maior que b. Em outra situao, uma ao deve ser executada somente se um caractere igual a 'A' ou igual a 'a'. Para compor expresses relacionais que sejam capazes de lidar adequadamente com essas situaes podem ser utilizados os operadores lgicos, apresentados na Tabela 3.2. Tabela 3.2: Operadores Lgicos Smbolo && || ! Descrio E lgico OU lgico NO lgico

3.3. OPERADORES LGICOS

57

3.3.1 Operador Lgico &&Uma expresso relacional composta que empregue um operador E lgico (&&) ser considerada verdadeira se, e somente se, todos os componentes forem logicamente verdadeiros. Se apenas um dos componentes for logicamente falsa ento a expresso relacional ser avaliada como falsa. O Exemplo 3.7 ilustra a aplicao do operador lgico &&. Exemplo 3.7 Programa C para exemplicar o emprego do operador lgico E. #include int main(void) { int num1 = 2; float num2 = 3.5; char ch = 'R'; if(num1 3.4 && ch == 'T') printf("Dados validos.\n"); else printf("Dados invalidos.\n"); system("pause"); return 0; } Dados invalidos.

3.3.2 Operador Lgico ||Uma expresso relacional composta que empregue um operador OU lgico (||) ser considerada verdadeira se, e somente se, pelo menos um dos componentes for logicamente verdadeiro. Somente se todos os componentes forem logicamente falsos que a expresso relacional ser avaliada como falsa. O Exemplo 3.8 ilustra a aplicao do operador lgico ||. Exemplo 3.8 Programa C para exemplicar o emprego do operador lgico OU. #include int main(void) { int num1 = 2; float num2 = 3.5; char ch = 'R';

58

CAPTULO 3. ESTRUTURAS DE SELEO if(num1 3.4 || ch == 'T') printf("Dados validos.\n"); else printf("Dados invalidos.\n"); system("pause"); return 0;

} Dados validos.

3.3.3

Operador Lgico !

O operador lgico NO, representado pelo smbolo !, um operador unrio. Se objetivo reverter o valor lgico de uma expresso relacional. Assim, se uma dada expresso for logicamente verdadeira, o operador ! torna a expresso logicamente falsa e vice-versa. O Exemplo 3.9 ilustra o uso do operador lgico !. Exemplo 3.9 Programa C para exemplicar o emprego do operador lgico NO. #include int main(void) { int num; printf("Digite um numero inteiro: "); scanf("%d", &num); if(!num) printf("Nulo.\n"); else printf("Nao nulo.\n"); system("pause"); return 0; } Digite um numero inteiro: 3 O numero 3 eh diferente de 0.

3.3.4

Expresses Relacionais e Operadores Lgicos

O emprego de operadores lgicos permite a composio de expresses relacionais complexos, que podem empregar diversos operadores relacionais, conforme ilustrado no Exemplo 3.10.

3.3. OPERADORES LGICOS

59

Exemplo 3.10 Escrever um programa C que solicite ao usurio a digitao dos lados de um tringulo e que exiba na tela a classicao do tringulo quanto ao tamanho dos lados (equiltero, issceles ou escaleno). Um tringulo equiltero se possui os trs lados iguais, issceles se possui 2 lados iguais e escaleno se possui os 3 lados de tamanhos diferentes.

#include int main(void) { int a; int b; int c; printf("Digite os lados de um triangulo: "); scanf("%d%d%d", &a, &b, &c); if(a == b && a == c) printf("Triangulo equilatero.\n"); else if(a == b || a == c || b == c) printf("Triangulo isosceles.\n"); else printf("Triangulo escaleno.\n"); system("pause"); return 0; } Digite os lados de um triangulo: 2 5 3 Triangulo escaleno.

Ateno: Considerando-se o Exemplo 3.10 importante observar que a linguagem C no permite a composio de expresses relacionais do tipo: if(a == b && c) ou if(a == b || == c || b == c). Em outros termos, uma expresso relacional deve ser formada por dois operandos e um operador relacional e a composio de duas ou mais expresses relacionais deve ser formada com operadores lgicos.

Exerccio 3.11 Escreva um programa C que solicite ao usuario o codigo de origem de um produto e que mostre o a procedencia, de acordo com a Tabela 3.3.

60

CAPTULO 3. ESTRUTURAS DE SELEO Cod. Origem 1 2 3 4 5 ou 6 7 ou 8 ou 9 10 a 20 21 a 30 Procedencia Sul Norte Leste Oeste Nordeste Sudeste Centro-Oeste Noroeste

Tabela 3.3: Procedncia de Produtos Categoria Infantil Juvenil Adolescente Adulto Senior Idade 5a7 8 a 10 11 a 15 16 a 30 Acima de 30

Tabela 3.4: Categorias de Nadadores

3.3.5

Problemas de Mltiplas Opes

Nos casos de problemas de mltipla opes, onde necessrio o emprego de duas ou mais estruturas if else, a sintaxe pode ser ligeiramente alterada conforme apresentado no Exemplo 3.11. Este estilo de codicao else if mais recomendado nessas situaes porque facilita a legibilidade. Exemplo 3.11 Escrever um programa C que solicite ao usurio a digitao dos lados de um tringulo e que exiba na tela a classicao do tringulo quanto ao tamanho dos lados (equiltero, issceles ou escaleno). Um tringulo equiltero se possui os trs lados iguais, issceles se possui 2 lados iguais e escaleno se possui os 3 lados de tamanhos diferentes. #include int main(void) { int a; int b; int c; printf("Digite os lados de um triangulo: "); scanf("%d%d%d", &a, &b, &c);

3.3. OPERADORES LGICOS if(a == b && a == c) printf("Triangulo equilatero.\n"); else if(a == b || a == c || b == c) printf("Triangulo isosceles.\n"); else printf("Triangulo escaleno.\n"); system("pause"); return 0; } Digite os lados de um triangulo: 2 5 3 Triangulo escaleno.

61

Exerccio 3.12 Escreva um programa C que solicite ao usuario a idade de um nadador e mostre na tela a sua categoria, usando as regras apresentadas na Tabela 3.4. Exerccio 3.13 Trs valores numricos podem ser os lados de um tringulo se cada valor for menor que a soma dos outros valores. Escreva um programa C que solicite ao usurio a digitao de trs valores inteiros e verique se podem formar um tringulo. Exerccio 3.14 Escrever um programa C que solicite ao usurio a digitao dos coecientes de uma equao do segundo grau (ax2 + bx + c = 0) e que calcule e retorne as razes reais da equao. Observe que uma equao do 2o grau pode ter duas, uma ou nenhuma raiz real, dependendo do valor de , onde = b2 4ac. Exerccio 3.15 Capicua ou palndromo denido como um nmero que lido da direita para a esquerda ou da esquerda para a direita idntico. Escreva um programa C que solicite ao usuario a digitaao de um nmero inteiro e positivo no intervalo [1000, 9999] e que verique se o nmero palndromo. Exerccio 3.16 O Teorema de Pitgoras provavelmente o mais clebre dos teoremas da Matemtica. Enunciado pela primeira vez por lsofos gregos chamados de pitagricos, estabelece uma relao simples entre o comprimento dos lados de um tringulo retngulo: o quadrado da hipotenusa igual soma dos quadrados dos catetos. Escreva um programa C para vericar se os valores fornecidos pelo usurio em tempo de execuo para as medidas dos lados formam ou no um tringulo retngulo.

62

CAPTULO 3. ESTRUTURAS DE SELEO

3.4

Operador Condicional Ternrio

A linguagem C fornece um operador condicional ternrio, muito semelhante a um bloco if-else. A sintaxe do comando condio ? expresso1 : expresso2. O primeiro operando uma condio a ser logicamente avaliada, o segundo operando a expresso a ser executada caso a condio avaliada seja logicamente verdadeira. O terceiro operando a expresso a ser executada caso a condio avaliada seja logicamente falsa. Os Exemplos 3.12 e 3.13 apresentam alguns casos de uso do operador condicional ternrio. Exemplo 3.12 Operador condicional ternrio associado a um comando de atribuio. #include int main(void) { int num; int res; printf("Digite um numero inteiro: "); scanf("%d", &num); res = (num >= 0) ? 1 : 0; printf("%d\n", res); system("pause"); return 0; } Digite um numero inteiro: 3 1 Exemplo 3.13 Operador condicional ternrio associado sada padro. #include int main(void) { int num; printf("Quantos animais de estimacao voce possui? "); scanf("%d", &num); printf("Voce possui %d anima%s de estimacao.\n", num, (num == 1) ? "l" : "is"); system("pause");

3.5. PRECEDNCIA DE OPERADORES return 0; } Quantos animais de estimacao voce possui? 1 Voce possui 1 animal de estimacao.

63

3.5 Precedncia de OperadoresAgora que j foram apresentados diversos operadores aritmticos, relacionais e lgicos, torna-se importante observar a ordem de precedncia de execuo entre eles. Suponha que seja necessrio escrever um programa para selecionar candidatos a uma vaga de emprego com os seguintes requisitos: idade acima de 25 anos e formao em Engenharia ou Informtica. O Exemplo 3.14 tenta resolver o problema. Exemplo 3.14 Precedncia entre operadores da linguagem C. #include int main(void) { int idade; int graduacao; printf("Idade: "); scanf("%d", &idade); printf("Graduacao: (1) Engenharia (2) Informatica scanf("%d", &graduacao); if(idade > 25 && graduacao == 1 || graduacao == 2) printf("Candidato aprovado.\n"); else printf("Candidato reprovado.\n"); system("pause"); return 0; } Idade: 20 Graduacao: (1) Engenharia Candidato aprovado.

(3) Outro ");

(2) Informatica

(3) Outro 2

A resposta est incorreta porque a precedncia do operador relacional && maior que do operador ||. A expresso relacional que consta do Exemplo 3.14 avaliada da seguinte forma: (idade > 25 && graduacao == 1) || graduacao == 2

64

CAPTULO 3. ESTRUTURAS DE SELEO

Para corrigir a precedncia dos operadores relacionais necessrio usar parnteses (Exemplo 3.15). Exemplo 3.15 Alterao de precedncia entre operadores com o uso de parnteses. #include int main(void) { int idade; int graduacao; printf("Idade: "); scanf("%d", &idade); printf("Graduacao - (1) Engenharia (2) Informatica (3) Outro: "); scanf("%d", &graduacao); if(idade > 25 && (graduacao == 1 || graduacao == 2)) printf("Candidato aprovado.\n"); else printf("Candidato reprovado.\n"); system("pause"); return 0; } Idade: 20 Graduacao - (1) Engenharia Candidato reprovado.

(2) Informatica

(3) Outro: 2

3.5.1

Tabela de Precedncia Entre Operadores

A Tabela 3.5 apresenta a precedncia entre os operadores aritmticos, relacionais e lgicos utilizados at esse ponto do curso. Exerccio 3.17 Escrever um programa C que solicite ao usuario a digitaao do dia e do mes corrente no formato DD/MM e que verique se e uma data valida ou invlida. Por exemplo, 30/02 e 31/04 sao datas invalidas.

3.6

Comando de Desvio Condicional switch

O comando de desvio condicional switch uma alternativa ao uso de diversas estruturas if-else em problemas de mltiplas opes. A forma geral do comando switch apresentada a seguir:

3.6. COMANDO DE DESVIO CONDICIONAL SWITCH Tabela 3.5: Precedncia entre Operadores Smbolo ( ) ! * / % + < >= == != && || ?: Descrio Parnteses Menos unrio No lgico Mutiplicao, diviso e mdulo Adio e subtrao Menor que, menor ou igual a, maior que, maior ou igual a Igual, diferente E lgico OU lgico Operador condicional ternrio

65

switch(expresso) { case constante1: sequncia_de_comandos; break; case constante2: sequncia_de_comandos; break; case constante3: sequncia_de_comandos; break; case ... default: sequncia_de_comandos; } Uma sequncia de comandos diferencia-se de um bloco de comandos por no ser delimitado por chaves de abertura e de fechamento. A execuo do comando switch segue os seguintes passos: A expresso avaliada. O resultado da expresso comparado com as constantes associadas s clusulas case. Quando o resultado da expresso for igual a uma das constantes, a execuo transferida para o incio da sequncia de comandos associada a esta constante.

66

CAPTULO 3. ESTRUTURAS DE SELEO A execuo continua sequencialmente at o m do comando switch a menos que um comando break seja encontrado. Nesse caso, a execuo do comando switch terminada. Caso o valor da expresso no corresponda a nenhuma das constantes associadas s clusulas case, a sequncia de comandos associada clusula default executada. A clusula default opcional. Nenhuma sequncia de comandos ser executada caso o valor da expresso no corresponda a nenhuma clusula case e no houver uma clusula default denida.

O comando break um dos comandos de desvio incondicional da linguagem C. O comando break usado no corpo do comando switch para interromper a execuo de uma sequncia de comandos e pular para a instruo seguinte ao comando switch. H ainda alguns pontos importantes que devem ser mencionados sobre o comando switch: O resultado da expresso avaliada deve ser um valor inteiro. Caso no exista um comando de desvio incondicional break, todas as instrues seguintes clusula case selecionada sero executadas, mesmo que pertenam as sequncias de comandos seguintes. O comando switch s pode testar a igualdade. Cada constante associada a uma clusula case deve possuir um valor diferente. No h uma ordem estabelecida para as diversas clusulas case de um comando switch. O Exemplo 3.16 ilustra a aplicao do comando de desvio condicional switch. Exemplo 3.16 Escrever um programa C para solicitar ao usuario a digitao de um numero inteiro correspondente a classicao em uma competio esportiva e que apresente na tela a medalha conquistada. #include int main(void) { int classificacao; printf("Digite a classificacao: "); scanf("%d",&clas); switch(clas) { case 1: printf("Medalha de ouro.\n"); break;

3.6. COMANDO DE DESVIO CONDICIONAL SWITCH case 2: printf("Medalha de prata.\n"); break; case 3: printf("Medalha de bronze.\n"); break; default: printf("Nao ha medalha para essa classificacao.\n"); } system("pause"); return 0; } Digite a classificacao: 2 Medalha de prata.

67

Observe que as clusulas case de um comando switch no podem ser associadas a expresses relacionais. O Exemplo 3.17 ilustra essa restrio da estrutura. Exemplo 3.17 Escrever um programa C para solicitar ao usuario a digitao de uma resposta do tipo sim ou no a uma pergunta. O usurio pode usar letras maisculas ou minsculas ao responder. #include int main(void) { char resp; printf("Digite (S)im ou (N)ao: "); scanf("%c", &resp); switch(resp) { case 'S': case 's': printf("Voce respondeu SIM.\n"); break; case 'N': case 'n': printf("Voce respondeu NAO.\n"); break; default: printf("Voce respondeu incorretamente.\n"); } system("pause");

68 return 0; }

CAPTULO 3. ESTRUTURAS DE SELEO

Exerccio 3.18 Escrever um programa C que solicite ao usuario o peso de uma pessoa na Terra e o numero correspondente a um dos demais planetas do sistema solar e que apresente na tela o peso no planeta especicado. Considere a Tabela 3.6 para os valores da gravidade relativa dos planetas tomando como base 1 o valor na Terra. Tabela 3.6: Gravidade relativa nos planetas do Sistema Solar Nmero Gravidade Planeta 1 0,37 Mercrio 2 0,88 Vnus 3 0,38 Marte 4 2,64 Jpiter 5 1,15 Saturno 6 1,17 Urano

Exerccio 3.19 Escrever um programa C que solicite ao usuario qual o prato principal, a sobremesa e a bebida escolhidos a partir do cardapio de um restaurante e que informe o total de calorias que sera consumido pelo cliente. Considere a Tabela 3.7 de calorias.

3.7

Funes para Teste de Caracteres

A biblioteca padro disponibiliza diversas funes para teste de caracteres, conforme apresentado na Tabela 3.8. Em todos os casos a funo retorna verdadeiro ou falso. Alm das funes para teste de caracteres, a biblioteca padro oferece as funes tolower() e toupper() que permitem a converso de uma letra maiscula para minscula e vice-versa. Exemplo 3.18 Escrever um programa C para solicitar ao usuario a digitao de um caractere em tempo de execuo. O programa deve vericar se o usurio digitou uma vogal ou uma consoante.

3.7. FUNES PARA TESTE DE CARACTERES Tabela 3.7: Calorias por item do cardpio de um restaurante Prato Vegetariano (180 cal) Peixe (230 cal) Frango (250 cal) Carne de Porco (350 cal) Sobremesa Abacaxi (75 cal) Sorvete diet (110 cal) Mousse diet (170 cal) Mousse chocolate (200 cal)

69

Bebida Cha (20 cal) Suco de Laranja (70 cal) Suco de Melao (100 cal) Refrigerante (120 cal)

Tabela 3.8: Funes para teste de caracteres Funo islower isupper isalpha isalnum isdigit isblank Teste Letra minscula Letra maiscula Letra maiscula ou minscula Letra ou dgito numrico Dgito numrico Espao em branco ou marca de tabulao

#include #include int main(void) { char ch; printf("Digite um caractere: "); scanf("%c",&ch); if(isalpha(ch)) { if(islower(ch)) ch = toupper(ch); if(ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') printf("Voce digitou uma vogal.\n"); else printf("Voce digitou uma consoante.\n"); } system("pause"); return 0; } Digite um caractere: a

70 Voce digitou uma vogal.

CAPTULO 3. ESTRUTURAS DE SELEO

Exerccio 3.20 Escrever um programa C para solicitar ao usuario a digitao de um caractere em tempo de execuo. O programa deve vericar se o usurio digitou letra, nmero, espao ou nenhum desses. Exerccio 3.21 Escrever um programa C para solicitar ao usuario a digitao de um caractere em tempo de execuo. O programa deve vericar se o usurio digitou letra ou nmero. Se digitou letra, informar se a letra digitada maiscula ou minscula. Exerccio 3.22 Escrever um programa C que solicite ao usurio a digitao da sigla da unidade da federao (UF) e que exiba o nome do Estado correspondente. Para simplicar o exerccio, considere apenas os Estados da regio Sudeste. Exerccio 3.23 Um nmero hexadecimal pode conter dgitos numricos (0 a 9) e letras (A a E). Escreva um programa C que solicite ao usurio a digitao de um nmero hexadecimal composto por um nic