Apostila - SENAI - Mecatrônica - Fundamentos de Linguagem C

  • Upload
    renato

  • View
    30

  • Download
    5

Embed Size (px)

Citation preview

Centro Tecnolgico de Mecatrnica

11

Centro Tecnolgico de Mecatrnica

Fundamentos de Linguagem C

ou

Tudo que voce precisa saber sobre C para no passar vergonha!

Caxias do Sul, novembro de 1997

Conselho Regional do SENAI - RS

Presidente

Dagoberto Lima Godoy

Conselheiros

Titulares Suplentes

Deomedes Roque Talini Valayr Hlio Wosiack

Enio Lcio SchelnValdomiro Bochese da Cunha

Astor Milton Schmitt Jos Carlos Cerveri

Diretoria SENAI - SR

Diretor Regional

Jos Zorta

Diretor Tcnico

Paulo Fernando Presser

Diretor Administrativo e Financeiro

Adalberto Luiz Lenhard

Apresentao

O texto que segue um resumo dos topicos fundamentais sobre a linguagem C.

C uma linguagem poderosa, robusta, flexivel e madura. Conhecer todos os seus detalhes, truques e armadilhas requer um estudo criterioso e profundo. Mas o C uma linguagem de sintaxe simples e elegante que permite rapido entendimento pelo programador iniciante. Desde sua criacao, o C tornou-se uma linguagem popular tanto entre programadoere profissionais quanto iniciantes.

Neste contexto, procuramos abordar os topicos essenciais da linguagem que nos permite escrever um programa completo e util.

Esperamos ter alcanados os objetivos propostos, e em prximas edies, aprimora-las.

Adalberto A. Dornelles F.

1. Fundamentos da Linguagem C

Neste capitulo sero vistos os fundamentos da linguagem C. O conceito de linguagem de programao, linguagens de alto e baixo nvel, linguagens genricas e especificas. Ser visto um pouco do histrico da criao da linguagem e a descrio das caractersticas mais importantes da linguagem C. Finalmente, ser visto o aspecto geral de um cdigo fonte escrito em C.

1.1Linguagens de Programao

Um programa de computador um conjunto instrues que representam um algoritmo para a resoluo de algum problema. Estas instrues so escritas atravs de um conjunto de cdigos (smbolos e palavras). Este conjunto de cdigos possui regras de estruturao lgica e sinttica prpria. Dizemos que este conjunto de smbolos e regras formam uma linguagem de programao.

1.1.1Exemplos de cdigos.

Existem muitas linguagens de programao. Podemos escrever um algoritmo para resoluo de um problema por intermdio de qualquer linguagem. A seguir mostramos alguns exemplos de trechos de cdigos escritos em algumas linguagens de programao.

Exemplo: trecho de um algoritmo escrito em Pseudo-linguagem que recebe um nmero num e escreve a tabuada de 1 a 10 para este valor:

leia num

para n de 1 at 10 passo 1 faa

tab num * n

imprime tab

fim faa

Exemplo: trecho do mesmo programa escrito em linguagem C:

scanf(&num);

for(n = 1; n

Caracteres no vlidos:

@ $

Os caracteres acima so vlidos apenas em strings. Veja seo 2.1.4.

1.3.2Comentrios

Em C, comentrios podem ser escritos em qualquer lugar do texto para facilitar a interpretao do algoritmo. Para que o comentrio seja identificado como tal, ele deve ter um /* antes e um */ depois. Observe que no exemplo e0101.cpp todo o cabealho esta dentro de um comentrio.

Exemplo:

/* esta e uma linha de comentrio em C */

Observao: O C++ permite que comentrios sejam escritos de outra forma: colocando um // em uma linha, o compilador entender que tudo que estiver a direita do smbolo um comentrio. Observe no programa exemplo e0101.cpp as linhas de comentrios colocadas a direita dos comandos.

Exemplo:

// este e um comentrio valido apenas em C++

1.3.3 Diretivas de Compilao

Em C, existem comandos que so processados durante a compilao do programa. Estes comandos so genericamente chamados de diretivas de compilao. Estes comandos informam ao compilador do C basicamente quais so as constantes simblicas usadas no programa e quais bibliotecas devem ser anexadas ao programa executvel. A diretiva #include diz ao compilador para incluir na compilao do programa outros arquivos. Geralmente estes arquivos contem bibliotecas de funes ou rotinas do usurio. Voltaremos a trabalhas esta diretiva com mais detalhe no captulo 5. A diretiva #define diz ao compilador quais so as constantes simblicas usadas no programa. Veremos sobre esta diretiva no capitulo 2.

1.3.4 Declarao de variveis

Em C, como na maioria das linguagens, as variveis devem ser declaradas no inicio do programa. Estas variveis podem ser de vrios tipos: int (inteiro), float (real de simples preciso) e outras que sero vistas no capitulo 2. No exemplo acima num, raiz, inf e sup so declaradas como variveis reais, enquanto i declarada como uma varivel inteira.

1.3.5 Entrada e sada de dados

Em C existem varias maneiras de fazer a leitura e escrita de informaes. Estas operaes so chamadas de operaes de entrada e sadia. Veremos no capitulo 3 algumas funes de entrada e sadia de informaes via teclado e tela. Outras funes de leitura e escrita em arquivos, sadia grfica, funes de manipulao de mouse, entrada e sadia de informaes via portas serial e paralela sero vistas em captulos posteriores. No exemplo acima printf uma funo de escrita na tela, scanf uma funo de leitura de teclado.

1.3.6 Estruturas de controle

A linguagem C permite uma ampla variedade de estruturas de controle de fluxo de processamento. Estas estruturas sero vistas em detalhes nos captulos 4 e 5. Duas estruturas das estruturas bsicas (deciso e repetio) so muito semelhantes as estruturas usadas nas Pseudo-linguagem algortmicas:

Estrutura de Deciso: Permite direcionar o fluxo lgico para dois blocos distintos de instrues conforme uma condio de controle.

Pseudo-linguagem Linguagem C

se condio if(condio){

ento bloco 1 bloco 1;

seno bloco 2 }else{

fim se bloco 2;

};

Estrutura de Repetio: Permite executar repetidamente um bloco de instrues ate que uma condio de controle seja satisfeita.

Pseudo-linguagem Linguagem C

faa do{

bloco bloco;

at condio }while(condio);

2. Constantes e Variveis

Neste capitulo veremos como os dados constantes e variveis so manipulados pela linguagem C. O que so constantes inteiras, reais, caracteres e strings. Quais so as regras de atribuio de nomes a variveis e quais so os tipos de dados que O C pode manipular. Veremos tambm como so declaradas as variveis e as constantes simblicas usadas em um programa.

2.1Constantes

O C possui quatro tipos bsicos de constantes: inteiras, de ponto flutuante, caracteres e strings. Constantes inteiras e de ponto flutuante representam nmeros de um modo geral. Caracteres e strings representam letras e agrupamentos de letras (palavras).

2.1.1Constantes inteiras

Uma constante inteira um nmero de valor inteiro. De uma forma geral, constantes inteiras so seqncias de dgitos que representam nmeros inteiros. Nmeros inteiros podem ser escritos no formato decimal (base 10), hexadecimal (base 16) ou octal (base 8).

Uma constante inteira decimal formada por uma seqncia de dgitos decimais: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Se a constante tiver dois ou mais dgitos, o primeiro no pode ser 0. Na verdade, pode ser 0 mas o compilador considerar esta constante como octal e no decimal.

Exemplo: A seguir so mostradas algumas constantes inteiras decimais vlidas.

0 3 -45 26338 -7575 1010

Exemplo: Algumas constantes inteiras decimais invlidas.

1.(ponto)

1,2(vrgula)

045(primeiro dgito 0: no constante decimal)

212-22-33 (caracter ilegal: -)

Uma constante inteira hexadecimal formada por uma seqncia de dgitos decimais: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F (ou a, b, c, d, e). Uma constante hexadecimal deve comear por 0x. Neste caso, os dgitos hexadecimais podem ser minsculos ou maisculos.

Exemplo: A seguir so mostrados algumas constantes inteiras hexadecimais vlidas.

0x0 0x3 0x4f5a 0x2FFE OxABCD 0xAaFf

Exemplo: Algumas constantes inteiras hexadecimais invlidas.

0x3.(ponto)

0x1,e(vrgula)

0x ff(espao)

FFEE(no comea com 0x: no constante hexadecimal)

0Xfg34 (caracter ilegal: g)

Uma constante inteira octal formada por uma seqncia de dgitos octais: 0, 1, 2, 3, 4, 5, 6, 7. A constante octal deve ter o primeiro digito 0 para que o compilador a identifique como tal

Exemplo: A seguir so mostrados algumas constantes octais vlidas.

00 -03 045 02633 07575 -0101

Exemplo: Algumas constantes inteiras octais invlidas.

010.(ponto)

01,2(vrgula)

0 4(espao)

45(primeiro digito no 0: no constante octal)

01784(caracter ilegal: 8)

2.1.2Constantes de ponto flutuante

Nmeros reais (no inteiros) so representados em base 10, por nmeros com um ponto decimal e (opcionalmente) um expoente. Um nmero ponto flutuante deve ter um ponto decimal que no pode ser substitudo por uma vrgula. Um nmero de ponto flutuante pode ser escrito em notao cientfica. Neste caso o x10 substitudo por e ou E. O nmero 1.23e4 representa 1.23 x 104 ou 12300.

Exemplo: Nmeros de ponto flutuante vlidos.

0.234 125.65 .93 1.23e-9 -1.e2 10.6e18 -.853E+67

A forma de representao de um nmero real em C bastante flexvel.

Exemplo: O nmero 314 pode ser representado por qualquer uma das seguintes formas:

314.3.14e2+3.14e+231.4e1.314E+3314e0

2.1.3Constantes caracteres

Uma constante caracter uma letra ou smbolo colocado entre aspas simples.

Exemplo: Abaixo esto representados algumas constantes caracteres.

abX&{

Embora sejam visualizados como letras e smbolos as constantes caracteres so armazenadas internamente pelo computador como um nmero inteiro entre 0 e 255. O caracter A por exemplo, tem valor 65. Os valores numricos dos caracteres esto padronizados em uma tabela chamada de American Standard Code for Information Interchange Table ou simplesmente tabela ASCII. Veja apndice B.

Certos codigos de controle da tabela ASCII (como o line feed) ou caracteres especiaiss (como ') possuem representao especial no C. Esta representacao chama-se seqncia de escape representada por uma barra invertida (\) e um caracter. Sequencias de escape so interpretadas como caracteres simples. Abaixo segue uma lista das principais sequencias de escape usadas no C.

Controle/Caracter Sequencia de escape Valor ASCII

nulo (null) \0 00

campainha (bell) \a 07

retrocesso (backspace) \b 08

tabulacao horizontal \t 09

nova linha (new line) \n 10

tabulacao vertical \v 11

alimentacao de folha (form feed) \f 12

retorno de carro (carriage return) \r 13

aspas (") \" 34

apostrofo (') \' 39

interrogacao (?) \? 63

barra invertida (\) \\ 92

2.1.4Constantes strings

Uma constante string consiste de um conjunto de caracteres colocados entre aspas duplas. Embora as instrues do C usem apenas os caracteres do conjunto padro ASCII, as constantes caracter e string podem conter caracteres do conjunto estendido ASCII: , , , , ...

Exemplo: Abaixo seguem algumas constantes strings vlidas.

Oba!

Caxias do Sul

A resposta :

Joo Carlos da Silveira

a

isto uma string

2.2Identificadores

Identificadores so os nomes das variveis e funes usadas no programa. Por exemplo raiz e MAX so nomes de variveis utilizadas no programa e0101.cpp.

2.2.1Regras de sintaxe

Os identificadores devem seguir as seguintes regras de construo:

Os identificadores devem comear por uma letra (a - z , A - Z) ou um underscore ( _ ).

O resto do identificador deve conter apenas letras, underscores ou dgitos (0 - 9). No pode conter outros caracteres. Em C, os identificadores podem ter at 32 caracteres.

Em C, letras maisculas so diferentes de letras minsculas: Por exemplo: MAX, max, Max so nomes diferentes para o compilador. Esta propriedade chamada de case sensibility.

Exemplo: os nomes abaixo so vlidos:

abc, y24, VetorPontosMovimentoRobo, nota_1, TAM_MAX.

Exemplo: os nomes abaixo no so vlidos:

3dia, vetor-1, pao&leite, iterao.

2.2.2Palavras reservadas

Existem certos nomes que no podem ser usados como identificadores. So chamadas as palavras reservadas e so de uso restrito da linguagem C (comandos, estruturas, declaraes, etc.). O conjunto de palavras reservadas usadas em C o seguinte:

asm auto break case cdecl char

class const continue _cs default delete

do double _ds else enum _es

extern _export far _fastcall float for

friend goto huge if inline int

interrupt _loadds long near new operator

pascal private protected public register return

_saveregs _seg short signed sizeof _ss

static struct switch template this typedef

union unsigned virtual void volatile while

Exemplo: No possvel declarar estes conjunto de variveis:

do, re, mi, fa, sol, la, si

old, new

Dos conjuntos acima, do e new so palavras reservadas.

2.3Tipos de dados

Em C, como na maioria das linguagens, os dados so divididos tipos: inteiro, real, caracter, etc. Esta diviso se deve basicamente ao nmero de bytes reservados para cada dado. Cada tipo de dado possui um intervalo de valores permitidos.

2.3.1Tipos bsicos

Abaixo segue uma lista dos tipos bsicos de dados permitidos em C. Os tipos char e int so inteiros e os tipos float e double so de ponto flutuante.

Tipo Tamanho Intervalo Uso

char 1 byte -128 a 127 nmero muito pequeno e caracter ASCII

int 2 bytes -32768 a 32767 contador, controle de lao

float 4 bytes 3.4e-38 a 3.4e38 real (preciso de 7 dgitos)

double 8 bytes 1.7e-308 a 1.7e308 cientfico (preciso de 15 dgitos)

2.3.2Declarao de variveis

Para que se possa usar uma varivel em um programa, necessrio fazer uma declarao de varivel antes. A declarao de variveis simplesmente informa ao processador quais so os nomes utilizados para armazenar dados variveis e quais so os tipos usados. Deste modo o processador pode alocar (reservar) o espao necessrio na memria para a manipulao destas variveis. possvel declarar mais de uma varivel ao mesmo tempo, basta separ-las por vrgulas (,).

Sintaxe: A sintaxe para declarao de variveis a seguinte:

tipo variavel_1 [, variavel_2, ...] ;

Onde tipo o tipo de dado e variavel_1 o nome da varivel a ser declarada. Se houver mais de uma varivel, seus nomes so separados por vrgulas.

Exemplo: Declarao das variveis:

int i;

int x,y,z;

char letra;

float nota_1,nota_2,media;

double num;

No exemplo acima, i, x, y e z foram declaradas variveis inteiras. Assim elas podem armazenar valores inteiros de -32768 at 32767. Do mesmo modo letra foi declarada como varivel caracter podendo receber valores de -128 at 127 ou caracteres do conjunto padro ASCII. As variveis nota_1, nota_2 e media foram declaradas como ponto flutuante tipo float e num como ponto flutuante tipo double.

A declarao de variveis feita, em geral, dentro de uma rotina. Por exemplo, a rotina principal main(). Deste modo se diz que est se fazendo uma declarao de variveis locais. Variveis locais podem ser referenciadas apenas dentro da rotina dentro da qual foi declarada, neste caso a rotina main().

Exemplo: Observe o uso da declarao de variveis no trecho de programa abaixo:

void main(){

float raio, area; // declaracao de variaveis

raio = 2.5;

rea = 3.14 * raio * raio;

}

No exemplo acima, as variveis area e raio foram declaradas como variveis locais tipo float. Assim o processador faz a alocao de dois espaos (endereos) de 4 bytes cada para armazenar as informaes, um para cada varivel. Na terceira linha, o processador coloca no endereo alocado para raio o valor 2.5. Depois, na quarta linha, o processador coloca o resultado da conta (19.625) no endereo de rea.

possvel fazer a declarao de variveis fora de uma rotina. Neste caso diz-se que se fez a declarao de variveis globais. O uso de variveis globais explicado na sesso ?.?.

2.3.3Tipos modificados

Alm dos tipos de dados citados acima existem outros tipos de dados ditos modificados. Em C existem dois modificadores: o modificador long e o modificador unsigned. Tipicamente o modificador long aumenta o nmero de bytes usados para o registro do nmero. Por conseqncia o intervalo de validade do nmero fica aumentado significativamente. O modificador unsigned, usado somente em inteiros, permite que um bit usado para guardar o sinal do nmero seja usado para guardar o valor do nmero. Em conseqncia disto o intervalo do nmero fica dobrado, porm somente permite o uso de nmeros positivos.

Tipo Tamanho (bytes) Intervalo

unsigned char 1 0 a 255

unsigned int 2 0 a 65 535

long int 4 -2 147 483 648 a 2 147 483 647

unsigned long int 4 0 a 4 294 967 295

long double 10 3.4e-4932 a 1.1e4932

2.3.4Strings.

Uma string um conjunto ordenado de caracteres que pode ser armazenado sob forma de um vetor um ponteiro. Estas estruturas de dados sero vistas em detalhe nos capitulo ? e ?. Por enquanto, nos basta saber como declarar e armazenar um conjunto caracter em uma varivel.

Sintaxe: Para declararmos uma varivel para receber um conjunto caracter devemos escrever:

char* var;

Exemplo: No exemplo seguinte a varivel nome foi declarada como conjunto caracter e em seguida recebe uma constante string.

char* nome;

nome = "Joo Carlos de Oliveira Andrade";

2.3.5Inicializao de variveis.

Quando se faz a declarao de uma varivel est se determinando que tipo de dado ela vai receber. possvel, em C, declarar uma varivel e j armazenar nela um valor inicial. Chamamos este procedimento de inicializao de uma varivel.

Sintaxe: A sintaxe para a inicializao de variveis :

tipo var_1 = valor_1 [, var_2 = valor_2, ...] ;

Onde tipo o tipo de dado, var_1 o nome da varivel a ser inicializada e valor_1 o valor inicial da varivel.

Exemplo: Inicializao de variveis:

int i = 0, j = 100;

float num = 13.5;

char* titulo = " Programa Teste ";

No exemplo acima, i e j foram declaradas variveis tipo int. O valor inicial de i 0 e o de j 100. Do mesmo modo num foi declarada como varivel float com valor inicial de 13.5. Tambem a variavel titulo foi declarada como um conjunto caracter e recebeu como conteudo inicial a string " Programa Teste ".

2.3.6Converso de tipo (Casting)

Algumas vezes queremos, momentaneamente, modificar o tipo de dado representado por uma varivel, isto , queremos que o dado seja apresentado em um tipo diferente do qual a varivel foi inicialmente declarada. Por exemplo: declaramos uma varivel como int e queremos, momentaneamente, que seu contedo seja apresentado como float. Este procedimento chamado de converso de tipo ou casting (moldagem, em ingls).

Sintaxe: A sintaxe da instruo de converso de tipo :

(tipo) varivel

onde tipo o nome do tipo ao qual queremos converter o dado armazenado em varivel.

Exemplo: observe a converso de tipo feita no exemplo abaixo:

int num;

float valor = 13.0;

num = (int)valor % 2;

No exemplo acima a varivel valor foi declarada inicialmente como sendo do tipo float recebendo o valor inicial 13.0. Logo em seguida o contedo de valor convertido para o tipo int para realizar a operao mdulo (%) com o inteiro 2. Aqui a converso necessria pois a operao mdulo somente pode ser feita com inteiros. importante salientar que a converso de tipo feita com o dado armazenado em uma varivel mas a varivel continua tendo o seu tipo original. No exemplo acima a varivel valor e os dados nela armazenados continuam sendo do tipo float aps a converso.

Veremos na seo 3.1 uma explicao mais detalhada do uso da converso de tipos.

2.4 Constantes Simblicas

Muitas vezes identificamos uma constante numrica por um smbolo: Pi = 3,14159 por exemplo. Podemos definir um nome simblico para esta constante, isto , podemos definir uma constante simblica que represente valor.

2.4.1Constantes definidas pelo programador

O programador pode definir constantes simblicas em qualquer programa.

Sintaxe: A sintaxe da instruo de definio de uma constante simblica :

#define nome valor

Onde #define uma diretiva de compilao que diz ao compilador para trocar as ocorrncias do texto nome por valor. Observe que no h ; no final da instruo pois trata-se de um comando para o compilador e no para o processador. A instruo #define deve ser escrita antes da instruo de declarao da rotina principal.

Exemplo: a seguir definimos algumas constantes simblicas.

#define PI 3.14159

#define ON 1

#define OFF 0

#define ENDERECO 0x378

void main(){

...

No exemplo acima, definimos PI como 3.14159. Isto significa que todas as ocorrncias do texto PI ser trocado por 3.14159. Assim se escrevemos uma instruo:

rea = PI * raio * raio;

o compilador vai interpretar esta instruo como se fosse escrita assim:

rea = 3.14159 * raio * raio;

Poderamos escrever estas instrues assim:

float pi = 3.14159;

rea = pi * rea * rea;

porm este tipo de instruo tem duas desvantagens: Primeiro, reserva 4 bytes de memria desnecessariamente. Segundo, esta instruo executada mais lentamente pois o processador precisa acessar a memria para verificar qual o valor de pi.

Observe tambm que no exemplo definimos os nomes simblicos com letras maisculas. Isto no necessrio, podemos perfeitamente definir nomes simblicos usando letras minsculas, porm faz parte do jargo dos programadores C usar letras maisculas para definir constantes simblicas.

O uso da diretiva #define no se restringe apenas ao apresentado acima, podemos us-la para definir macro instrues. No veremos o uso de macros neste texto, procure mais detalhes na bibliografia recomendada.

2.4.2Constantes pr-definidas

Em alguns compiladores C, algumas constantes simblicas j esto pr-definidas. Estas constantes em geral definam alguns valores matemticos (, /2, e, etc.), limites de tipos etc. A seguir segue uma tabela contendo algumas (existem muitas outras) constantes simblicas pr-definidas no compilador Turbo C++ da Borland.

Biblioteca Constante Valor Significado

math.h M_PI 3.14159...

math.h M_PI_2 1.57079... /2

math.h M_PI_4 0,78539... /4

math.h M_1_PI 0,31830... 1/

math.h M_SQRT2 1,41421... 2

conio.h BLACK 0 valor da cor (preto)

conio.h BLUE 1 valor da cor (azul)

conio.h GREEN 2 valor da cor (verde)

conio.h CYAN 3 valor da cor (cyan)

conio.h RED 4 valor da cor (vermelho)

conio.h MAGENTA 5 valor da cor (magenta)

limits.h INT_MAX 32767 limite superior do tipo int

limits.h INT_MIN -32768 limite inferior do tipo int

Cada uma das constantes acima esta definida em uma biblioteca. Uma biblioteca, em C, um arquivo pr-compilado chamado arquivo header (cabealho, em ingls). Em cada biblioteca esto agrupadas constantes e funes semelhantes (veja seo 3.7.2). Por exemplo, constantes e funes matemticas esto guardadas na biblioteca math.h (mathematical functions), constantes e funes de manipulao teclado e monitor esto guardadas na biblioteca conio.h (console input and output). Para que se possa usar a constante simblica em um programa preciso incluir a biblioteca na compilao do programa.

Sintaxe: A sintaxe de incluso de bibliotecas a seguinte:

#include

onde nome_bib o nome da biblioteca que se deseja incluir. Esta instruo deve ser escrita antes do programa principal.

Exemplo: O programa abaixo usa a constante predefinida M_PI para calcular a rea de um disco circular.

#include

void main(){

float area, raio = 5.0;

rea = M_PI * raio * raio;

}

3. Operadores, Expresses e Funes

Um programa tem como caracterstica fundamental a capacidade de processar dados. Processar dados significa realizar operaes com estes dados. As operaes a serem realizadas com os dados podem ser determinadas por operadores ou funes. Os operadores podem ser de atribuio, aritmticos, de atribuio aritmtica, incrementais, relacionais, lgicos e condicionais.

Exemplo: o smbolo + um operador que representa a operao aritmtica de adio. O identificador sqrt() uma funo que representa a operao de extrair a raiz quadrada de um nmero.

Uma expresso um arranjo de operadores e operandos. A cada expresso vlida atribudo um valor numrico.

Exemplo: 4 + 6 uma expresso cujo valor 10. A expresso sqrt(9.0) tem valor 3.0.

3.1 Operador de Atribuio

A operao de atribuio a operao mais simples do C. Consiste de atribuir valor de uma expresso a uma varivel.

Sintaxe: A sintaxe da operao de atribuio a seguinte:

identificador = expresso;

onde identificador o nome de uma varivel e expresso uma expresso vlida (ou outro identificador).

Exemplo: A seguir so mostradas algumas atribuies vlidas:

a = 1;

delta = b * b - 4. * a * c;

i = j;

Observe que o smbolo de atribuio ( = ) no tem o mesmo significado que o usual da matemtica que representa a igualdade de valores. Este smbolo, em C, representa a atribuio do valor calculado em expresso a varivel identificador. Em pseudo-linguagem o operador de atribuio representado como . Tambm no se pode confundir o operador de atribuio ( = ) com o operador relacional de igualdade ( == ) que ser visto na seo 3.5.1.

Observe-se tambm que o operando esquerdo deve ser um identificador de varivel, isto , no pode ser uma constante ou expresso.

Exemplo: A seguir so mostradas algumas atribuies invlidas:

1 = a; // constante!

b + 1 = a; // expresso!

3.1.1Converso de tipo.

Se os dois operandos de uma atribuio no so do mesmo tipo, o valor da expresso ou operador da direita ser convertido para o tipo do identificador da esquerda.

Exemplo: Algumas atribuies com converso de tipo:

int i;

float r;

i = 5; // valor de i: 5

r = i ; // valor de r: 5.0

A varivel i foi inicializada com o valor 5. Ao final da terceira instruo, r recebe o valor 5.0.

Nestas converses podem ocorrer alteraes dos valores convertidos se o operando da esquerda for de um tipo que utilize menor numero de bytes que o operando da direita.

Exemplo: Algumas atribuies com converso de tipo e perda de informao:

int i;

float r = 654.321;

i = r; // truncamento!

Aps a execuo deste trecho de programa o valor da varivel i ser 654 pois seu valor foi truncado durante a converso.

Pode-se dizer que as converses potencialmente perigosas (onde h possibilidade de perda de informao) so:

char int float double

Observe que o compilador C ao encontrar esta operao no gera nenhum aviso de ateno para o programador. Assim este detalhe pode gerar um erro de programao (bug) que passe desapercebido ao programador inexperiente. possvel dizer que a linguagem C possui tipos macios (soft types) pois a operao com variveis de tipos diferentes perfeitamente possvel. Esta caracterstica do C se contrape a algumas linguagens em que isto no possvel (Fortran, por exemplo). Estas linguagens possuem tipos duros (hard types).

3.1.2Limites do intervalo do tipo de dado.

Tambm importante observar que os tipos em C tem intervalos bem definidos e os resultados das operaes devem respeitar estes intervalos. Se a uma varivel for atribudo um valor que esteja fora dos seus limites ento este valor ser alterado.

Exemplo: Observe as expresses abaixo, assuma que i seja uma varivel do tipo int.

i = 4999; // o valor de i e 4999

i = 4999 + 1; // o valor de i e 5000

i = 5000 + 30000; // o valor de i e -30536

O valor de 35000 ultrapassou o limite superior do tipo int (32767).

importante observar que em C, ao contrrio de outras linguagens, a ultrapassagem do limite de um tipo no interpretado como erro. Isto pode acarretar resultados inesperados para o programador desatento.

3.1.3Atribuio mltipla.

E possvel atribuir um valor a muitas variveis em uma nica instruo. A esta operao d-se o nome de atribuio mltipla.

Sintaxe: A sintaxe da atribuio mltipla seguinte:

var_1 = [var_2 = ... ] expresso;

onde var_1, var_2, ... so os identificadores de variveis e expresso uma expresso vlida.

Observe que na atribuio mltipla as operaes ocorrem da direita para a esquerda, isto , inicialmente o valor de expresso atribudo a var_2 e depois o valor de var_2 atribudo a var_1. Deve-se tomar cuidado com as converses de tipo e limites de intervalo para atribuies de tipos diferentes.

Exemplo: Observe a instruo de atribuio mltipla abaixo: as variveis inteiras i, j e k so todas inicializadas com o valor 1. E as variveis de dupla preciso max e min so inicializadas com o valor 0.0:

int i, j, k;

double max, min;

i = j = k = 1;

max = min = 0.0;

Programa Exemplo: O arquivo e0301.cpp traz um programa para visualizar alguns aspectos relacionados com o operador de atribuio. Execute o programa passo-a-passo e observe o valor das variveis.

3.2 Operadores Aritmticos

Existem cinco operadores aritmticos em C. Cada operador aritmticos est relacionado ao uma operao aritmtica elementar: adio, subtrao, multiplicao e diviso. Existe ainda um operador (%) chamado operador de mdulo cujo significado o resto da diviso inteira. Os smbolos dos operadores aritmticos so:

Operador Operao

+ adio.

- subtrao.

* multiplicao

/ diviso

% mdulo (resto da diviso inteira)

Sintaxe: A sintaxe de uma expresso aritmtica :

operando operador operando

onde operador um dos caracteres mostrados acima e operando uma constante ou um identificador de varivel.

Exemplo: Algumas expresses aritmticas:

1+2 a-4.0 b*c valor_1/taxa num%2

No existe em C, como existe em outras linguagens, um operador especfico para a operao de potenciao (ab). Existe, porm, uma funo de biblioteca (pow()) que realiza esta operao. Veja a seo 3.7 adiante. Embora as operaes do C sejam semelhantes as operaes aritmticas usuais da matemtica, alguns detalhes so especficos da linguagem, e devem ser observados.

3.2.1Restries de operandos.

Os operandos dos operadores aritmticos devem ser constantes numricas ou identificadores de variveis numricas. Os operadores +, -, *, / podem operar nmeros de todos os tipos (inteiros ou reais) porm o operador % somente aceita operandos inteiros.

Exemplo: Expresses vlidas

Expresso Valor

6.4 + 2.1 8.5

7 - 2 5

2.0 * 2.0 4.0

6 / 3 2

47 % 2 1

Uma restrio ao operador de diviso (/) que o denominador deve ser diferente de zero. Se alguma operao de diviso por zero for realizada o correra um erro de execuo do programa (run-time error), o programa ser abortado e a mensagem divide error ser exibida.

Exemplo: A expresso abaixo invlida pois o primeiro operando no um numero inteiro.

Expresso Valor

6.4 % 3 invalido!

Podemos contornar o problema do operador inteiro da operao modulo usando o artifcio da converso de tipo (casting) mostrada na seo 2.3.4:

Exemplo: Observe o trecho de programa abaixo:

int num;

float valor = 13.0;

num = valor % 2; // invlido!

num = (int)valor % 2; // vlido!

Observe que usamos a converso de tipo para que o dado armazenado em valor fosse transformado no tipo int assim a operao mdulo pode ser efetuada.

3.2.2Converso de tipo.

O resultado de uma operao aritmtica depende dos tipos dos operandos. Se os operandos so do mesmo tipo o resultado ser do mesmo tipo. Se os operando forem de tipos diferentes ento haver uma converso de tipo tal que o tipo que ocupa menos espao de memria ser convertido para o tipo que ocupa mais espao de memria e o resultado ser deste tipo. Em geral:

char int float double

Esta uma regra geral, alguns compiladores podem ter outras regras de converso.

Exemplo: Observe as converses de tipo abaixo:

Expresso Valor Converso

6 + 2.0 8.0 int float

7.000000 - 2.0000000000000 5.000000000000000 float double

2 * 3.000000000000000 6.000000000000000 int double

Observe que estas converses podem gerar resultados surpreendentes para o programador desatento.

Exemplo: Observe as expresses abaixo. Assuma que as variveis num_i, num_f, den_i e den_f so inicializadas como:

int num_i = 7 , den_i = 2 ;

float num_f = 7.0, den_f = 2.0;

Expresso Valor Operandos Resultado

num_f / den_f 3.5 float / float float

num_f / den_i 3.5 float / int float

num_i / den_f 3.5 int / float float

num_i / den_i 3 int / int int

Observe que no exemplo acima o valor da ltima expresso 3 e no 3.5. Isto ocorre porque como os dois operandos so tipo int o resultado e convertido para o tipo int e ocorre o truncamento. O truncamento da diviso inteira feito de modo a obter o menor valor absoluto.

Em C caracteres so armazenados na memria como nmeros inteiros e por isso operaes aritmticas so permitidas com tipos char. Os valores usados so os correspondentes da tabela ASCII.

Exemplo: Observe as expresses abaixo:

Expresso Valor Converso

A + 1 B 65 + 1 66

A + B 65 + 66 131

A + 32 a 65 + 32 97

3.2.4Precedncia de operadores.

Quando mais de um operador se encontram em uma expresso aritmtica as operaes so efetuadas uma de cada vez respeitando algumas regras de precedncia: Estas regras de precedncia so as mesmas da matemtica elementar.

Os operadores de multiplicao (*), diviso (/) e mdulo (%) tem precedncia sobre os operadores de adio (+) e subtrao (-). Entre operadores de mesma precedncia as operaes so efetuadas da esquerda para a direita. Veja a tabela 3.1.

Exemplo: Observe, nas expresses abaixo, o seu valor e a ordem das operaes efetuadas:

Expresso Valor Ordem

1 + 2 - 3 0 + -

24 - 3 * 5 9 * -

4 - 2 * 6 / 4 + 1 2 * / - +

6 / 2 + 11 % 3 * 4 11 / % * +

A ordem de precedncia dos operadores pode ser quebrada usando-se parnteses: ( ). Os parnteses so, na verdade, operadores de mais alta precedncia e so executados primeiro. Parnteses internos so executados primeiro que parnteses externos.

Exemplo: Observe, nas expresses abaixo, o seu valor e a ordem das operaes efetuadas:

Expresso Valor Ordem

1 + (2 - 3) 0 - +

(24 - 3) * 5 105 - *

(4 - 2 * 6) / 4 + 1 -1 * - / +

6 / ((2 + 11) % 3) * 4 24 + % / *

Observe que os operadores e os operandos deste exemplo so os mesmos do exemplo anterior. Os valores, porm, so diferentes pois a ordem de execuo das operaes foi modificada pelo uso dos parnteses.

Programa Exemplo: O arquivo e0302.cpp traz um programa para visualizar alguns aspectos relacionados com os operadores aritmticos. Execute o programa passo-a-passo e observe o valor das variveis.

3.3 Operadores de Atribuio Aritmtica

Muitas vezes queremos alterar o valor de uma varivel realizando alguma operao aritmtica com ela. Como por exemplo: i = i + 1 ou val = val * 2. Embora seja perfeitamente possvel escrever estas instrues, foi desenvolvido na linguagem C uma instrues otimizadas com o uso de operadores ditos operadores de atribuio aritmtica. Os smbolos usado so (+=, -=, *=, /= , %=). Deste modo as instrues acima podem ser rescritas como: i += 1 e val *= 2, respectivamente.

Sintaxe: A sintaxe da atribuio aritmtica a seguinte:

var += exp;

var -= exp;

var *= exp;

var /= exp;

var %= exp;

onde var o identificador da varivel e exp uma expresso vlida. Estas instrues so equivalentes as seguintes:

var = var + exp;

var = var - exp;

var = var * exp;

var = var / exp;

var = var % exp;

Exemplo: Observe as atribuies aritmticas abaixo e suas instrues equivalentes:

Atribuio aritmtica Instruo equivalente

i += 1; i = i + 1;

j -= val; j = j - val;

num *= 1 + k; num = num * (1 + k);

troco /= 10; troco = troco / 10;

resto %= 2; resto = resto % 2;

O operador de atribuio aritmtica tem precedncia menor que os outros operadores at aqui discutidos. Veja a tabela 3.1.

Programa Exemplo: O arquivo e0303.cpp traz um programa para visualizar alguns aspectos relacionados com os operadores de atribuio aritmtica. Execute o programa passo-a-passo e observe o valor das variveis.

3.4 Operadores Incrementais

Em programao existem instrues muito comuns chamadas de incremento e decremento. Uma instruo de incremento adiciona uma unidade ao contedo de uma varivel. Uma instruo de decremento subtrai uma unidade do contedo de uma varivel.

Existem, em C, operadores especficos para realizar as operaes de incremento (++) e decremento (--). Eles so genericamente chamados de operadores incrementais.

Sintaxe: A sintaxe dos operadores incrementais a seguinte:

instruo equivalente

++ var var = var + 1

var ++ var = var + 1

-- var var = var - 1

var -- var = var - 1

onde var o nome da varivel da qual se quer incrementar ou decrementar um unidade.

Observe que existe duas sintaxes possveis para os operadores: pode-se colocar o operador esquerda ou direita da varivel. Nos dois casos o valor da varivel ser incrementado (ou decrementado) de uma unidade. Porm se o operador for colocado esquerda da varivel, o valor da varivel ser incrementado (ou decrementado) antes que a varivel seja usada em alguma outra operao. Caso o operador seja colocado direita da varivel, o valor da varivel ser incrementado (ou decrementado) depois que a varivel for usada em alguma outra operao.

Exemplo: Observe o fragmento de cdigo abaixo e note o valor que as variveis recebem aps a execuo da instruo:

valor das variveis

int a, b, c, i = 3; // a: ? b: ? c: ? i: 3

a = i++; // a: 3 b: ? c: ? i: 4

b = ++i; // a: 3 b: 5 c: ? i: 5

c = --i; // a: 3 b: 5 c: 4 i: 4

Os operadores incrementais so bastante usados para o controle de laos de repetio, que sero vistos na seo ??. importante que se conhea exatamente o efeito sutil da colocao do operador, pois isto pode enganar o programador inexperiente.

Os operadores incrementais tem a mais alta precedncia entre todos, sendo superados apenas pelos parnteses que tem precedncia ainda maior. Veja a tabela 3.1.

Programa Exemplo: O arquivo e0304.cpp traz um programa para visualizar alguns aspectos relacionados com os operadores incrementais. Execute o programa passo-a-passo e observe o valor das variveis.

3.5 Operadores Relacionais e Lgicos

A chave para a flexibilidade de um algoritmo a tomada de decises atravs da avaliao de condies de controle. Uma condies de controle uma expresso lgica que avaliadas como verdadeira ou falsa. Uma expresso lgica construda com operadores relacionais e lgicos.

3.5.1Operadores relacionais

Operadores relacionais verificam a relao de magnitude e igualdade entre dois valores. So seis os operadores relacionais em C:

Operador Significado

> maior que

< menor que

>= maior ou igual a (no menor que)

r 0

6 >= i 1

i < j 0

s , = e m 1 * > !=

6 >= n < 3 - m 0 - >= <

m == n m 0 !=

3.5.2Operadores lgicos

So trs os operadores lgicos de C: &&, || e !. Estes operadores tem a mesma significao dos operadores lgicos Booleanos AND, OR e NOT.

Sintaxe: A sintaxe de uso dos operadores lgicos:

expr_1 && expr_2

expr_1 || expr_2

!expr

onde expr_1 , expr_2 e expr so expresses quaisquer.

Observe que os operadores lgicos atuam sobre expresses de quaisquer valores. Para estes operadores todo valor numrico diferente de 0 considerado 1.

Exemplo: A seguir mostrado o valor lgico de uma expresso qualquer:

Expresso Valor lgico

0 0

1 1

1.0 1

0.4 1

-5.2 1

onde expr_1 , expr_2 e expr so expresses quaisquer.

O resultado da operao lgica && ser 1 somente se os dois operandos forem 1, caso contrrio o resultado 0. O resultado da operao lgica || ser 0 somente se os dois operandos forem 0, caso contrrio o resultado 1. O resultado da operao lgica ! ser 0 se o operandos for 1, e 1 se o operando for 0. Abaixo mostra-se o resultado das possveis combinaes entre os operandos para cada operador lgico:

Operador &&: op_1 op_2 Res

op_1 && op_2 1 1 1

1 0 0

0 1 0

0 0 0

Operador ||: op_1 op_2 Res

op_1 || op_2 1 1 1

1 0 1

0 1 1

0 0 0

Operador !: op Res

!op 1 0

0 1

O Operador && tem precedncia sobre o operador ||. Estes dois tm precedncia menor que os operadores relacionais. O operador ! tem a mesma precedncia que os operadores incrementais. Veja a tabela 3.1.

Exemplo: Observe as expresses lgicas abaixo e verifique o resultado de sua avaliao. Admita que a, b e c so variveis tipo int com valores 0, 1 e 2, respectivamente.

Expresso Valor Ordem de Operao

a && b 0

c > b || a < c 1 > < ||

a + b && !c - b 1 ! + - &&

!b && c || a 0 ! && ||

Programa Exemplo: O arquivo e0305.cpp traz um programa para visualizar alguns aspectos relacionados com os operadores lgicos e relacionais. Execute o programa passo-a-passo e observe o valor das variveis.

3.6 Operador Condicional

O operador condicional (?:) usado em expresses condicionais. Uma expresso condicional pode ter dois valores diferentes dependendo de uma condio de controle.

Sintaxe: A sintaxe de uma expresso condicional :

condio ? expresso_1 : expresso_2

onde expresso_1 e expresso_2 so duas expresses quaisquer, e condio uma expresso lgica que ser avaliada primeiro. Se o valor de condio for 1, isto , verdadeiro, ento a expresso condicional assumir o valor de expresso_1. Caso contrario assumir o valor de expresso_2. Uma expresso condicional equivalente a uma estrutura de deciso simples:

se condio

ento expressao_1

seno expressao_2

fim se

Exemplo: Observe as expresses condicionais abaixo e verifique o resultado de sua avaliao. Admita que i, j e k so variveis tipo int com valores 1, 2 e 3, respectivamente.

Expresso Valor

i ? j : k 2

j > i ? ++k : --k 4

k == i && k != j ? i + j : i - j -1

i > k ? i : k 3

O operador condicional tem baixa precedncia, precedendo, apenas, aos operadores de atribuio. Veja a tabela 3.1.

Programa Exemplo: O arquivo e0306.cpp traz um programa para visualizar alguns aspectos relacionados com o operador condicional. Execute o programa passo-a-passo e observe o valor das variveis.

3.7 Funes de biblioteca

Uma funo um sub-programa (tambm chamado de rotina). Esta funo recebe informaes, as processa e retorna outra informao. Por exemplo, podemos ter uma funo que receba um valor numrico, calcule seu logaritmo decimal e retorne o valor obtido. Existem dois tipos de funes: funes de biblioteca e funes de usurio. Funes de biblioteca so funes escritas pelos fabricantes do compilador e j esto pr-compiladas, isto , j esto escritas em cdigo de mquina. Funes de usurio so funes escritas pelo programador. Nesta seo trataremos somente das funes de biblioteca, funes de usurio sero vistas no captulo ?.

3.7.1O uso de funes

Antes de usar uma funo preciso saber como a funo esta declarada, isto , quais so os parmetros que a funo recebe e quais so os para metros que a funo retorna. Estas informaes esto contidas no manual do usurio do compilador ou em sua documentao on-line.

Sintaxe: A sintaxe de declarao de uma funo :

tipo_ret nome(tipo_1, tipo_2, ...)

onde nome o nome da funo, tipo_1, tipo_2, ... so os tipos (e quantidade) de parmetros de entrada da funo e tipo_ret o tipo de dado de retorno da funo. Alm dos tipos usuais vistos na seo 2.3, existe ainda o tipo void (vazio, em ingls) que significa que aquele parmetro inexistente.

Exemplo: A funo cos() da biblioteca math.h declarada como:

double cos(double);

Isto significa que a funo tem um parmetro de entrada e um parmetro de sada, ambos so do tipo double.

Exemplo: A funo getch() da biblioteca conio.h declarada como:

int getch(void);

Isto significa que a funo no tem parmetros de entrada e tem um parmetro int de sada.

Para podermos usar um funo de biblioteca devemos incluir a biblioteca na compilao do programa. Esta incluso feita com o uso da diretiva #include colocada antes do programa principal, como visto na secao 2.4.2.

Exemplo: Assim podemos usar a funo no seguinte trecho de programa:

#include // incluso de biblioteca

void main(){ // inicio do programa principal

double h = 5.0; // hipotenusa

double co; // cateto oposto

double alfa = M_PI_4; // angulo: /4

co = h * cos(alfa); // calculo: uso da funcao cos()

} // fim do programa

As funes tem alta precedncia, sendo mais baixa apenas que os parnteses. A tabela 3.1 mostra as precedncias de todos os operadores estudados neste captulo.

3.7.2 As bibliotecas disponveis e algumas funes interessantes

A seguir segue uma lista de todas as bibliotecas disponveis no compilador Turbo C++ 3.0 Borland: Ao longo do texto veremos o uso de muitas funes cobrindo uma boa parte destas bibliotecas, porm o leitor que desejar tornar-se "fluente" na linguagem C pode (e deve) estud-las com profundidade.

alloc.h assert.h bcd.h bios.h complex.h

conio.h ctype.h dir.h dirent.h dos.h

errno.h fcntl.h float.h fstream.h generic.h

graphics.h io.h iomanip.h iostream.h limits.h

locale.h malloc.h math.h mem.h process.h

setjmp.h share.h signal.h stdarg.h stddef.h

stdio.h stdiostr.h stdlib.h stream.h string.h

strstrea.h sys\stat.h sys\timeb.h sys\types.h time.h

values.h

Vejamos algumas funcoes disponiveis nas bibliotecas C.

Biblioteca math.h

int abs(int i);

double fabs(double d);

Calcula o valor absoluto do inteiro i e do real d, respectivamente.

double sin(double arco);

double cos(double arco);

double tan(double arco);

double asin(double arco);

double acos(double arco);

double atan(double arco);

Funes trigonometricas do ngulo arco, em radianos.

double ceil(double num);

double floor(double num);

Funcoes de arredondamento para inteiro.

ceil() arredonda para cima. Ex. ceil(3.2) == 3.0;

floor() arredonda para baixo. Ex. floor(3.2) == 4.0;

double log(double num);

double log10(double num);

Funcoes logaritmicas: log() logaritmo natural (base e), log10() logaritmo decimal (base 10).

double pow(double base, double exp);

Potenciacao: pow(3.2,5.6) = 3.25.6.

double sqrt(double num);

Raiz quadrada: sqrt(9.0) = 3.0.

Biblioteca stdlib.h

int random(int num);

Gera um nmero inteiro aleatrio entre 0 e num - 1.

Programa Exemplo: O arquivo e0307.cpp traz um programa para visualizar alguns aspectos relacionados com funes de biblioteca. Execute o programa passo-a-passo e observe o valor das variveis.

3.8Precedncia entre os operadores do C

A tabela 3.1 mostra a ordem de precedncia de todos os operadores estudados neste captulo. Os operadores de maior precedncia so os parnteses e as chamadas de funes. Os operadores de menor precedncia so os o operadores de atribuio.

Categoria

Operadores

Prioridade

parnteses

( )

interno externo

funo

nome()

E D

incremental, lgico

++ -- !

E D

aritmtico

* / %

E D

aritmtico

+ -

E D

relacional

< > =

E D

relacional

== !=

E D

lgico

&&

E D

lgico

||

E D

condicional

?:

E D

atribuio

= += -= *= /= %=

E D

Tabela 3.1: Precedncia dos operadores. Maior precedncia no topo, menor precedncia na base.

4. Entrada e Sada

Para que um programa torne-se minimamente funcional preciso que ele receba dados do meio externo (teclado, mouse, portas de comunicao, drives de disco, etc.) e emita o resultado de seu processamento de volta para o meio externo (monitor, impressora, alto-falante, portas de comunicao, drives de disco, etc.). De outro modo: um programa deve trocar informaes com o meio externo. Em C, existem muitas funes pr-definidas que tratam desta troca de informaes. So as funes de entrada e sada do C. Nos exemplos mostrados nos captulos anteriores foram vistas algumas funes de entrada (scanf(), getch()) e algumas funes de sada (printf()). Neste captulo veremos, em detalhe, estas e outras funes de modo a permitir escrever um programa completo em C.

Mostraremos, nas duas sees iniciais as mais importantes funes de entrada e sada de dados em C: as funes printf() e scanf(). A partir do estudo destas funes possvel escrever um programa propriamente dito com entrada, processamento e sada de dados.

4.1Sada formatada: printf()

Biblioteca: stdio.h

Declarao: int printf (const char* st_contr [, lista_arg]);

Propsito: A funo printf() (print formated) imprime dados da lista de argumentos lista_arg formatados de acordo com a string de controle st_contr. Esta funo retorna um valor inteiro representando o nmero de caracteres impressos.

Esta funo imprime dados numricos, caracteres e strings. Estafuno dita de sada formatada

pois os dados de sada podem ser formatados (alinhados, com nmero de dgitos variveis, etc.).

Sintaxe: A string de controle uma mscara que especifica (formata) o que ser impresso e de que maneira ser impresso.

Exemplo: Observe no exemplo abaixo as instrues de sada formatada e os respectivos resultados.

Instruo Sada

printf(Ola, Mundo!); Ola, Mundo!

printf(linha 1 \nlinha 2 ); linha 1

linha 2

Observe que na primeira instruo, a sada exatamente igual a string de controle. J na segunda instruo a impresso se deu em duas linhas. Isto se deve ao \n que representa o cdigo ASCII para quebra de linha (veja seo 2.1.3).

Nesta mascara possvel reservar espao para o valor de alguma varivel usando especificadores de formato. Um especificador de formato marca o lugar e o formato de impresso das variveis contidas na lista variveis. Deve haver um especificador de formato para cada varivel a ser impressa. Todos os especificadores de formato comeam com um %.

Exemplo: Observe no exemplo abaixo as instrues de sada formatada e os respectivos resultados. Admita que idade seja uma varivel int contendo o valor 29 e que tot e din sejam variveis float cujo valores so, respectivamente, 12.3 e 15.0.

Instruo:

printf(Tenho %d anos de vida,idade);

Sada:

Tenho 29 anos de vida

Instruo:

printf(Total: %f.2 \nDinheiro: %f.2 \nTroco: %f.2,tot,din,din-tot);

Sada:

Total: 12.30

Dinheiro: 15.00

Troco: 2.70

Depois do sinal %, seguem-se alguns modificadores, cuja sintaxe a seguinte:

% [flag] [tamanho] [.preciso] tipo

[flag]

justificao de sada: (Opcional)

-

justificao esquerda.

+

converso de sinal (sada sempre com sinal: + ou -)

converso de sinal (sadas negativas com sinal, positivas sem sinal)

[tamanho]

especificao de tamanho (Opcional)

n

pelo menos n dgitos sero impressos (dgitos faltantes sero completados por brancos).

0n

pelo menos n dgitos sero impressos (dgitos faltantes sero completados por zeros).

[.preciso]

especificador de preciso, dgitos a direita do ponto decimal. (Opcional)

(nada)

padro: 6 dgitos para reais.

.0

nenhum digito decimal.

.n

so impressos n dgitos decimais.

Tipo

caracter de converso de tipo (Requerido)

d

inteiro decimal

o

inteiro octal

x

inteiro hexadecimal

f

ponto flutuante: [-]dddd.dddd.

e

ponto flutuante com expoente: [-]d.dddde[+/-]ddd

c

caracter simples

s

string

Programa Exemplo: O arquivo e0401.cpp contm um programa que ilustra o uso da funo printf() usando vrias combinaes de strings de controle e especificadores de formato. Execute o programa passo-a-passo e verifique a sada dos dados.

4.2Leitura formatada: scanf()

Biblioteca: stdio.h

Declarao: int scanf(const char* st_contr [, end_var, ...]);

Propsito: A funo scanf() (scan formated) permite a entrada de dados numricos, caracteres e 'strings' e sua respectiva atribuio a variveis cujos endereos so end_var. Esta funo dita de entrada formatada pois os dados de entrada so formatados pela string de controle st_contr. a um determinado tipo de varivel (int, float, char, ...).

Sintaxe: O uso da funo scanf() semelhante ao da funo printf(). A funo l da entrada padro (em geral, teclado) uma lista de valores que sero formatados pela string de controle e armazenados nos endereos das variveis da lista. A string de controle formada por um conjunto de especificadores de formato, cuja sintaxe a seguinte:

% [*] [tamanho] tipo

*

indicador de supresso (Opcional)

Se o indicador de supresso estiver presente o campo no lido. Este supressor til quando no queremos ler um campo de dado armazenado em arquivo.

O campo lido normalmente.

Tamanho

especificador de tamanho(Opcional)

n

Especifica n como o numero mximo de caracteres para leitura do campo.

Campo de qualquer tamanho.

Tipo

define o tipo de dado a ser lido (Requerido)

d

inteiro decimal (int)

f

ponto flutuante (float)

o

inteiro octal (int)

x

inteiro hexadecimal (int)

i

inteiro decimal de qualquer formato(int)

u

inteiro decimal sem sinal (unsigned int)

s

string (char*)

c

caracter (char)

A lista de variveis o conjunto de (endereos) de variveis para os quais sero passados os dados lidos. Variveis simples devem ser precedidos pelo caracter &. Veja mais sobre endereos na seo ?.? Variveis string e vetores no so precedidos pelo caracter &. Veja mais sobre strings e vetores na seo ?.?

Programa exemplo: O arquivo e0402.cpp contm um programa que ilustra o uso da funo scanf() na leitura de dados. Execute o programa passo-a-passo e verifique como os especificadores de formato agem sobre os dados digitados.

4.3Entrada de caracter individual: getchar()

Biblioteca: stdio.h

Declarao: int getchar(void);

Propsito: A funo getchar() (get character) l um caracter individual da entrada padro (em geral, o teclado). Se ocorrer um erro ou uma condio de 'fim-de-arquivo' durante a leitura, a funo retorna o valor da constante simblica EOF (end of file)definida na biblioteca stdio.h. Esta funo permite uma forma eficiente de deteco de finais de arquivos.

Esta funo dita line buffered, isto , no retorna valores at que o caracter de controle line feed (\n) seja lido. Este caracter, normalmente, enviado pelo teclado quando a tecla [enter] pressionada. Se forem digitados vrios caracteres, estes ficaro armazenados no buffer de entrada at que a tecla [enter] seja pressionada. Ento, cada chamada da funo getchar() ler um caracter armazenado no buffer.

4.4Sada de caracter individual: putchar()

Biblioteca: stdio.h

Declarao: int putchar(int c);

Propsito: Esta funo putchar() (put character) imprime um caracter individual c na sada padro (em geral o monitor de vdeo).

Programa Exemplo: O programa e0403.cpp mostra o uso das funes getchar() e putchar() em um programa que l caracteres do teclado e os reimprime convertidos para maisculos.

4.5Leitura de teclado: getch(), getche()

Biblioteca: conio.h

Declarao:int getch(void);

int getche(void);

Propsito: Estas funes fazem a leitura dos cdigos de teclado. Estes cdigos podem representar tecla s de caracteres (A, y, *, 8, etc.), teclas de comandos ( [enter], [delete], [Page Up], [F1], etc.) ou combinao de teclas ([Alt] + [A], [Shift] + [F1], [Ctrl] + [Page Down], etc.).

Ao ser executada, a funo getch() (get character) aguarda que uma tecla (ou combinao de teclas) seja pressionada, recebe do teclado o cdigo correspondente e retorna este valor. A funo getche()(get character and echoe) tambm escreve na tela, quando possvel, o caracter correspondente.

Cdigo ASCII: ao ser pressionada uma tecla correspondente a um caracter ASCII, o teclado envia um cdigo ao 'buffer' de entrada do computador e este cdigo lido. Por exemplo, se a tecla A for pressionada o cdigo 65 ser armazenado no buffer e lido pela funo.

Cdigo Especial: ao serem pressionadas certas teclas (ou combinao de teclas) que no correspondem a um caracter ASCII, o teclado envia ao 'buffer' do computador dois cdigos, sendo o primeiro sempre 0. Por exemplo, se a tecla [F1] for pressionada os valores 0 e 59 sero armazenados e a funo deve ser chamada duas vezes para ler os dois cdigos.

Programa exemplo: O arquivo e0404.cpp mostra um programa para a leitura de teclado. Este programa usa a funo getch() para reconhecer teclas e combinao de teclas.

Programa exemplo: O arquivo e0405.cpp mostra um programa para a leitura de teclado usando a funo getche().

4.6Escrita formatada em cores: cprintf()

Biblioteca: conio.h

Declarao: int cprintf (const char* st_contr [, lista_arg]);

Propsito: Esta funo cprintf() (color print formated) permite a sada de dados numricos, caracteres e strings usando cores. O uso da funo cprintf() semelhante a printf()porm permite que a sada seja a cores. Para que a sada seja colorida necessrio definir as cores de fundo e de letra para a impresso antes do uso da funo.

Cores (Modo Texto)

Cor Constante Valor Fundo Letra

Preto BLACK 0 ok ok

Azul BLUE 1 ok ok

Verde GREEN 2 ok ok

Cian CYAN 3 ok ok

Vermelho RED 4 ok ok

Magenta MAGENTA 5 ok ok

Marrom BROWN 6 ok ok

Cinza Claro LIGHTGRAY 7 ok ok

Cinza Escuro DARKGRAY 8 -- ok

Azul Claro LIGHTBLUE 9 -- ok

Verde Claro LIGHTGREEN 10 -- ok

Cian Claro LIGHTCYAN 11 -- ok

Vermelho Claro LIGHTRED 12 -- ok

Magenta Claro LIGHTMAGENTA 13 -- ok

Amarelo YELLOW 14 -- ok

Branco WHITE 15 -- ok

Piscante BLINK 128 -- ok

Estas definies so feitas pelas funes texcolor() e textbackground() cuja sintaxe :

textcolor(cor_de_letra);

textbackground(cor_de_fundo);

onde cor_de_letra e cor_de_fundo so nmeros inteiros referentes as cores da palheta padro (16 cores, modo texto). Estes valores de cor so representadas por constantes simblicas definidas na biblioteca conio.h. Para se usar uma letra piscante deve-se adicionar o valor 128 ao valor da cor de letra. Alguns valores de cor no podem ser usados como cor de fundo. A relao acima mostra as cores, suas constantes simblicas e onde podem ser usadas:

Exemplo: O trecho de programa abaixo imprime uma mensagem de alerta em amarelo piscante sobre fundo vermelho.

#include

...

textbackground(RED);

textcolor(YELLOW + BLINK);

cprintif( Alerta: Vrus Detectado! );

...

Programa Exemplo: O programa do arquivo e0406.cpp mostra todas as combinaes possveis de impresso colorida em modo texto.

4.7Sada sonora: sound(), delay(), nosound()

Biblioteca: dos.h

Declaraes: void sound(unsigned freq);

void delay(unsigned tempo);

void nosound(void);

Propsito: A funo sound() ativa o alto-falante do PC com uma freqncia freq (Hz). A funo delay() realiza uma pausa (aguarda intervalo de tempo) de durao tempo (milisegundos). A funo nosound() desativa o alto-falante.

Programa Exemplo: O uso destas funes muito simples mas produz resultados interessantes. No arquivo e0407.cpp temos um exemplo do uso de sons em programas.

4.8Limpeza de tela: clrscr(), clreol()

Biblioteca: conio.h

Declaraes: void clrscr(void);

void clreol(void);

Propsito: A funo clrscr() (clear screen) limpa a janela de tela e posiciona o cursor na primeira linha e primeira coluna da janela (canto superior esquerdo da janela). A funo clreol() (clear to end of line) limpa uma linha desde a posio do cursor at o final da linha mas no modifica a posio do cursor. Ambas funes preenchem a tela com a cor de fundo definida pela funo textbacground().

4.9Posicionamento do cursor: gotoxy()

Biblioteca: conio.h

Declaraes: void gotoxy(int pos_x, int pos_y);

Propsito: Em modo texto padro, a tela dividida em uma janela de 25 linhas e 80 colunas. A funo gotoxy() permite posicionarmos o cursor em qualquer posio (pos_x,pos_y) da tela. Sendo que a posio (1,1) corresponde ao canto superior esquerdo da tela e a posio (80,25) corresponde ao canto inferior direito. Como as funes printf() e cprintf() escrevem a partir da posio do cursor, podemos escrever em qualquer posio da tela.

4.10Redimencionamento de janela: window()

Biblioteca: conio.h

Declaraes: void window(int esq, int sup, int dir, int inf);

Propsito: Esta funo permite redefinir a janela de texto. As coordenadas esq e sup definem o canto superior esquerdo da nova janela, enquanto as coordenadas inf e dir definem o canto inferior direito da nova janela. Para reativar a janela padro escreve-se a instruo window(1,1,80,25). Quando uma janela definida, o texto que ficar fora da janela fica congelado at que se redefina a janela original.

4.11Monitorao de teclado: kbhit()

Biblioteca: conio.h

Declaraes: int kbhit(void);

Propsito: Esta funo (keyboard hitting) permite verificar se uma tecla foi pressionada ou no. Esta funo verifica se existe algum cdigo no buffer de teclado. Se houver algum valor, ela retorna um nmero no nulo e o valor armazenado no buffer pode ser lido com as funes getch() ou getche(). Caso nenhuma tecla seja pressionada a funo retorna 0. Observe que, ao contrrio de getch(), esta funo no aguarda que uma tecla seja pressionada.

Programa Exemplo: O arquivo e0408.cpp contm um programa para exemplificar o uso das funes clrscr(), clreol(), gotoxy(), window(), kbhit().

5. Estruturas de Controle

Estruturas de controle permitem controlar a seqncia das aes lgicas de um programa. Basicamente, existem dois tipos de estruturas de controle: estruturas de repetio e estruturas de deciso. A estrutura de repetio permite que um bloco de instrues seja executado repetidamente uma quantidade controlada de vezes. A estrutura de deciso permite executar um entre dois ou mais blocos de instrues. Neste captulo estudaremos em detalhe as instrues do C que permitem implementar estas estruturas.

5.1Condio de controle

Em todas as estruturas, existe pelo menos uma expresso que faz o controle de qual bloco de instrues ser executado ou quantas vezes ele ser executado: o que chamamos de condio de controle. Uma condio de controle uma expresso lgica ou aritmtica cujo resultado pode ser considerado verdadeiro ou falso. Conforme vimos na seo 3.5, a linguagem C no possui, entretanto, variveis ou constantes lgicas, possui somente expresses numricas, assim quando uma expresso numrica se encontra em uma condio de controle, ela ser considerada falsa se seu valor for igual a zero, e verdadeira se seu valor for diferente de zero.

Exemplo: Observe nas condies abaixo, seu valor numrico e seu significado lgico. Considere as variveis int i = 0, j = 3;

condio valor numrico significado lgico

(i == 0) 1 verdadeiro

(i > j) 0 falso

(i) 0 falso

(j) 3 verdadeiro

Este fato deve ficar claro pois, nas estruturas que estudaremos neste captulo, quando for dito que uma condio falsa ou verdadeira quer se dizer que seu valor e igual a zero ou diferente de zero.

5.2Estrutura do...while

Esta uma estrutura bsica de repetio condicional. Permite a execuo de um bloco de instrues repetidamente. Sua sintaxe a seguinte:

Sintaxe:

do{

bloco

}while(condio);

onde:condio uma expresso lgica ou numrica.

bloco um conjunto de instrues.

Esta estrutura faz com que o bloco de instrues seja executado pelo menos uma vez. Aps a execuo do bloco, a condio avaliada. Se a condio verdadeira o bloco executado outra vez, caso contrrio a repetio terminada. Ofluxograma desta estrutura mostrada na figura 5.1:

bloco

condio?

V

F

Figura 5.1: Fluxograma da estrutura do...while.

Exemplo: No trecho abaixo, a leitura de um nmero feita dentro de um lao de repetio condicional. A leitura repetida caso o nmero lido seja negativo.

do{

puts("Digite um nmero positivo:");

scanf("%f",&num);

}while(num 1.0){

eps /= 2.0;

}

Programa exemplo: No arquivo e0502.cpp existe um programa que calcula a raiz quadrada de um nmero real positivo usando o mtodo de Newton. Este programa ilustra o uso da estrutura while.

5.4 Estrutura for

A estrutura for muito semelhante as estruturas de repetio vistas anteriormente, entretanto costuma ser utilizada quando se quer um nmero determinado de ciclos. A contagem dos ciclos feita por uma varivel chamada de contador. A estrutura for , as vezes, chamada de estrutura de repetio com contador. Sua sintaxe a seguinte:

Sintaxe:

for(inicializao; condio; incremento){

bloco

}

onde:inicializao uma expresso de inicializao do contador.

condio uma expresso lgica de controle de repetio.

incremento uma expresso de incremento do contador.

bloco um conjunto de instrues a ser executado.

Esta estrutura executa um nmero determinado de repeties usando um contador de iteraes. O contador inicializado na expresso de inicializao antes da primeira iterao. Por exemplo: i = 0; ou cont = 20;. Ento o bloco executado e depois de cada iterao, o contador incrementado de acordo com a expresso de incremento. Por exemplo: i++ ou cont -= 2. Ento a expresso de condio avaliada: se a condio for verdadeira, o bloco executado novamente e o ciclo recomea, se a condio falsa termina-se o lao. Esta condio , em geral, uma expresso lgica que determina o ultimo valor do contador. Por exemplo: i 0.

Exemplo: No trecho abaixo, o contador i inicializado com o valor 1. O bloco repetido enquanto a condio i = 0.0);

printf("mdia: %f",soma/num);

O outro uso da instruo break, em estruturas switch...case, serve para separar os conjuntos de instrues em cada case.

Exemplo: Estrutura switch...case com a instruo break:

int tipo;

puts("Selecione o sabor de sua pizza:");

puts("Muzzarela Calabreza Alho&Oleo:");

tipo = getch();

switch(tipo){

case M:

// prepara pizza muzzarela...

case C:

// prepara pizza calabreza...

case A:

// prepara pizza Alho&Oleo...

default:

puts("Opcao incorreta");

}

Programa Exemplo: O arquivo e0508.cpp mostra um programa que utiliza a estrutura switch com a instruo break para simular um piano no teclado do computador.

5.7.2 A instruo continue.

Esta instruo opera de modo semelhante a instruo break dentro de um lao de repetio. Quando executada, ela pula as instrues de um lao de repetio sem sair do lao. Isto , a instruo fora a avaliao da condio de conttrole do lao.

Exemplo: No trecho abaixo revemos um lao de repetio l valores para o clculo de uma mdia. Se (val < 0.0) ento o programa salta diretamente para a condio de controle, sem executar o resto das instrues.

puts("digite valores:");

do{

puts("valor:");

scanf("%f",&val);

if(val < 0.0){ // se val negativo...

continue; // ...salta para...

}

num++; // se (val < 0.0) estas instrues

soma += val; // no so executadas!

}while(val >= 0.0); // ...fim do lao

printf("mdia: %f",soma/num);

5.7.3 A instruo goto.

Esta instruo chamada de desvio de fluxo. A instruo desvia o programa para um rtulo (posio identificada) no programa. So raros os casos onde a instruo goto necessria, no entanto, h certas circunstncias, onde usada com prudncia, ela pode ser til.

Sintaxe: A sintaxe da instruo goto a seguinte:

goto rtulo;

...

rtulo:

...

onde rtulo um identificador vlido.

Exemplo: No trecho abaixo revemos um lao de repetio l valores para o clculo de uma mdia. Foram usadas duas instrues goto.

puts("digite valores:");

inicio: // rtulo

puts("valor:");

scanf("%f",&val);

if(val < 0.0){ // se val negativo...

goto fim; // ...salta para fim

}

num++; // se (val < 0.0) estas instrues

soma += val; // no so executadas!

goto inicio; // salta para inicio

fim: // rtulo

printf("mdia: %f",soma/num);

5.7.4 A funo exit().

Esta funo (no instruo) exit() , da biblioteca stdlib.h, uma funo que termina a execuo de um programa. Normalmente um programa terminado quando se executa a ltima sua instruo, porm pode-se terminar a execuo do programa a qualquer momento com o uso desta funo.

A funo exit() tem a seguinte declarao: void exit(int status). Onde o argumento da funo um valor inteiro que ser passado para o Sistema Operacional: (varivel de sistema errorlevel no DOS).

Exemplo: No trecho abaixo revemos um lao de repetio l valores para o clculo de uma mdia. Foi usado a funo exit para terminar a execuo do programa.

puts("digite valores:");

do{

puts("valor:");

scanf("%f",&val);

if(val < 0.0){ // se val negativo...

printf("mdia: %f",soma/num); // imprime resultado

exit(0); // termina programa

}

num++; soma += val;

}while(1);

6. Funes

Funes (tambm chamadas de rotinas, ou sub-programas) so a essncia da programao estruturada. Funes so segmentos de programa que executam uma determinada tarefa especfica. J vimos o uso de funes nos captulos anteriores: funes j providenciadas pelas bibliotecas-padro do C (como sqrt(), toupper(), getch() ou putchar()).

possvel ao programador, alem disso, escrever suas prprias rotinas. So as chamadas de funes de usurio ou rotinas de usurio. Deste modo pode-se segmentar um programa grande em vrios programas menores. Esta segmentao chamada de modularizao e permite que cada segmento seja escrito, testado e revisado individualmente sem alterar o funcionamento do programa como um todo. Permite ainda que um programa seja escrito por vrios programadores ao mesmo tempo, cada um escrevendo um segmento separado. Neste captulo, veremos como escrever funes de usurio em C.

6.1Estrutura das funes de usurio

A estrutura de uma funo de usurio muito semelhante a estrutura dos programas que escrevemos at agora. Uma funo de usurio constitui-se de um bloco de instrues que definem os procedimentos efetuados pela funo, um nome pelo qual a chamamos e uma lista de argumentos passados a funo. Chamamos este conjunto de elementos de definio da funo.

Exemplo: o cdigo mostrado abaixo uma funo definida pelo usurio para calcular a mdia aritmtica de dois nmeros reais:

float media2(float a, float b){

float med;

med = (a + b) / 2.0;

return(med);

}

No exemplo acima definimos uma funo chamada media2 que recebe dois argumentos tipo float: a e b. A mdia destes dois valores calculada e armazenada na varivel med declarada internamente. A funo retorna, para o programa que a chamou, um valor tambm do tipo float: o valor da varivel med. Este retorno de valor feito pela funo return()que termina a execuo da funo e retorna o valor de med para o programa que a chamou.

Depois de definimos um funo, podemos us-la dentro de um programa qualquer. Dizemos que estamos fazendo uma chamada a funo.

Exemplo: No exemplo abaixo chamamos a funo media2() dentro de um programa principal:

void main(){

float num_1, num_2, med;

puts(Digite dois nmeros:);

scanf(%f %f, &num_1, &num_2);

med = media2(num_1, num_2); // chamada a funo

printf(\nA media destes nmeros e %f, med);

}

6.2 Definio de funes

De modo formal, a sintaxe de uma funo a seguinte:

tipo_de_retorno nome_da_funo(tipo_1 arg_1, tipo_2 arg_2, ...){

[bloco de instrues da funo]

}

A primeira linha da funo contm a declarao da funo. Na declarao de uma funo se define o nome da funo, seu tipo de retorno e a lista de argumentos que recebe. Em seguida, dentro de chaves {}, definimos o bloco de instrues da funo.

O tipo de retorno da funo especifica qual o tipo de dado retornado pela funo, podendo ser qualquer tipo de dado mostrado na seo 2.3: int, float, etc. Se a funo no retorna nenhum valor para o programa que a chamou devemos definir o retorno como void, ou seja um retorno ausente. Se nenhum tipo de retorno for especificado o compilador entender que o retorno ser tipo int.

Vale notar que existe apenas um valor de retorno para funes em C. No podemos fazer o retorno de dois ou mais valores como em algumas linguagens (no MatLab: [media,desvio] = estat(a, b, c, d, e)). Porm isto no um limitao sria pois o uso de ponteiros (cap. ?) contorna o problema.

Por ser um identificador, o nome da funo segue as mesmas regras de definio de identificadores (veja seo 2.2).

A lista de argumentos da funo especifica quais so os valores que a funo recebe. As variveis da lista de argumentos so manipuladas normalmente no corpo da funo (veja seo 6.5 adiante).

A chamada de uma funo termina com a instruo return() que transfere o controle para o programa chamador da funo. Esta instruo tem duas finalidades: determina o fim lgico da rotina e o valor de retorno da funo. O argumento de return() ser retornado como valor da funo.

6.3 Localizao das funes

Existem basicamente duas posies possveis para escrevermos o corpo de uma funo: ou antes ou depois do programa principal. Podemos ainda escrever uma funo no mesmo arquivo do programa principal ou em arquivo separado.

6.3.1Corpo da funo antes do programa principal (no mesmo arquivo)

Quando escrevemos a definio de uma funo antes do programa principal e no mesmo arquivo deste, nenhuma outra instruo necessria. A sintaxe geral para isto a seguinte:

Sintaxe: Uma funo escrita antes do programa principal:

tipo nomef(...){ // definio da funo

[corpo de funo]

}

void main(){ // programa principal

...

var = nomef(...) // chamada da funo

...

}

Exemplo: Funo media2() escrita antes do programa principal.

float media2(float a, float b){ // funo

float med;

med = (a + b) / 2.0;

return(med);

}

void main(){ // programa principal

float num_1, num_2, med;

puts(Digite dois nmeros:);

scanf(%f %f, &num_1, &num_2);

med = media2(num_1, num_2); // chamada da funo

printf(\nA media destes nmeros e %f, med);

}

Programa exemplo: No arquivo e0601.cpp existe um programa que calcula o maior valor entre dois nmeros digitados. Este programa faz uso da funo max()escrita pelo usurio.

6.3.2Corpo da funo depois do programa principal (no mesmo arquivo)

Quando escrevemos a definio de uma funo depois do programa principal e no mesmo arquivo deste, devemos incluir um prottipo da funo chamada. Um prottipo uma instruo que define o nome da funo, seu tipo de retorno e a quantidade e o tipo dos argumentos da funo. O prottipo de uma funo indica ao compilador quais so as funes usadas no programa principal os tipo. A sintaxe geral para isto a seguinte:

Sintaxe: Uma funo escrita depois do programa principal:

void main(){ // programa principal

tipo nomef(...); // prottipo da funo

...

var = nomef(...) // chamada a funo

...

}

tipo nomef(...){ // definio da funo

[corpo de funo]

}

Exemplo: Funo media2() escrita depois do programa principal.

void main(){ // programa principal

float media2(float,float); // prottipo de media2()

float num_1, num_2, med;

puts(Digite dois nmeros:);

scanf(%f %f, &num_1, &num_2);

med = media2(num_1, num_2); // chamada a funo

printf(\nA media destes nmeros e %f, med);

}

float media2(float a, float b){ // funo media2()

float med;

med = (a + b) / 2.0;

return(med);

}

Observe que o prottipo de uma funo nada mais que a declarao da funo sem o seu corpo. Observe ainda que na lista de argumentos do prottipo podem ser escritos apenas os tipos dos argumentos.

Programa exemplo: No arquivo e0602.cpp existe um programa que calcula o maior valor entre dois nmeros digitados. Este programa faz uso da funo max()escrita pelo usurio.

6.3.3Corpo da funo escrito em arquivo separado

Em C, como em muitas outras linguagens, permitido que o usurio crie uma funo em um arquivo e um programa que a chame em outro arquivo distinto. Esta facilidade permite a criao de bibliotecas de usurio: um conjunto de arquivos contendo funes escritas pelo usurio. Esta possibilidade uma grande vantagem utilizada em larga escala por programadores profissionais.

Quando escrevemos a definio de uma funo em arquivo separado do programa principal devemos incluir este arquivo no conjunto de arquivos de compilao do programa principal. Esta incluso feita com a diretiva #include. Esta diretiva, vista nas sees 2.4.2 e 3.7.1, instrui o compilador para incluir na compilao do programa outros arquivos que contem a definio das funes de usurio e de biblioteca.

Sintaxe: A sintaxe de incluso de funes de usurio a seguinte:

#include path // incluso da funo

void main(){ // programa principal

...

var = nomef(...) // chamada a funo

...

}

Na diretiva #include, indicamos entre aspas duplas o caminho de localizao do arquivo onde est definida a funo chamada.

Exemplo: A funo media2() est escrita em um arquivo separado.

#include c:\tc\userbib\stat.h // incluso da funo

void main(){ // programa principal

float num_1, num_2, med;

puts(Digite dois nmeros:);

scanf(%f %f, &num_1, &num_2);

med = media2(num_1, num_2); // chamada a funo

printf(\nA media destes nmeros e %f, med);

}

Programa exemplo: No arquivo e0603.cpp existe um programa que calcula o maior valor entre dois nmeros digitados. Este programa faz uso da funo max()escrita pelo usurio no arquivo e0604.cpp.

Observao: Um arquivo pode conter a definio de uma ou mais funes. Em geral, quando o arquivo possui apenas uma funo ele nomeado com o mesmo nome da funo e extenso *.cpp ou *.c. Por exemplo, poderamos definir a funo media() no arquivo media.cpp. Quando um arquivo possui a definio de mais de uma funo, ele nomeado com a extenso *.h ou *.lib. Por exemplo: poderamos criar um conjunto de funes estatsticas chamadas media(), dsvpd(), moda(), max(), min(), etc. definindo-as em um arquivo chamado stat.h.

6.4 Hierarquia de Funes

Sempre possvel que um programa principal chame uma funo que por sua vez chame outra funo... e assim sucessivamente. Quando isto acontece dizemos que a funo chamadora tem hierarquia maior (ou superior) a funo chamada. Ou que a funo chamadora est em um nvel hierrquico superior a funo chamada.

Quando isto ocorre, devemos ter o cuidado de definir (ou incluir) as funes em ordem crescente de hierarquia, isto , uma funo chamada escrita antes de uma funo chamadora. Isto se deve ao fato de que o compilador deve conhecer uma funo antes de que chamada seja compilada.

Programa exemplo: No arquivo e0605.cpp existe um jogo de jackpot que ilustra o uso de vrias rotinas por um programa principal. Observe tambm que estas funes chamam-se umas as outras.

Neste programa exemplo, os nveis hierrquicos das funes podem ser colocados da seguinte maneira:

main()

regras() abertura() sorte() plim_plim() saida() simnao()

imprimec() roleta()

pinta() bip()

No exemplo acima temos um primeiro nvel onde se encontra a funo main() [o programa principal tambm uma funo] que chama as funes x, y, z. A funo x por sua vez chamas as funes s, r, e t. Observe que neste exemplo os prottipos das funes esto colocados de modo a que as funes de menor hierarquia so escritas antes das funes de maior hierarquia.

6.5 Regra de escopo para variveis

A regra de escopo define o mbito de validade de variveis. Em outras palavras define onde as variveis e funes so reconhecidas. Em C, uma varivel s pode ser usada aps ser declarada (ver seo 2.3.2). Isto por que o processador deve reservar um local da memria para armazenar os valores atribudos varivel. Porm o local, do programa, onde uma varivel declarada define ainda seu escopo de validade. Uma varivel pode ser local, global ou formal de acordo com o local de declarao.

Variveis Locais: Uma varivel dita local, se for declarada dentro do bloco de uma funo. Uma varivel local tem validade apenas dentro do bloco onde declarada, isto significa que podem ser apenas acessadas e modificadas dentro de um bloco. O espao de memria alocado para esta varivel criado quando a execuo do bloco iniciada e destrudo quando encerrado, assim variveis de mesmo nome mas declaradas em blocos distintos, so para todos os efeitos, variveis distintas.

Exemplo:

float media2(float a, float b){

float med;

med = (a + b) / 2.0;

return(med);

}

void main(){

float num_1, num_2, med;

puts(Digite dois nmeros:);

scanf(%f %f, &num_1, &num_2);

med = media2(num_1, num_2);

printf(\nA media destes nmeros e %f, med);

}

No exemplo acima, med uma varivel local definida pela funo media(). Outra varivel med tambm definida pela funo main(). Para todos os efeitos estas variveis so distintas.

Variveis Formais: Uma varivel formal uma varivel local declarada na lista de parmetros de uma funo. Deste modo, tem validade apenas dentro da funo onde declarada, porm serve de suporte para os valores passados pelas funes. As variaveis formais na declarao da funo e na chamada da funo podem ter nomes distintos. A nica exigncia de que sejam do mesmo tipo.

Por serem variveis locais, os valores que uma funo passa para outra no so alterados pela funo chamada. Este tipo de passagem de argumentos chamado de passagem por valor pois os valores das variveis do programa chamador so copiados para as correspondentes variveis da funo chamada. Veremos no capitulo ? como alterar os valores das variveis do programa chamador. Chamaremos esta passagem de passagem por endereo.

No exemplo acima, a e b so parmetros formais declarados na funo media2(). Observe que a funo chamada com os valores de num_1 e num_2. Mesmo que os valores de a e b fossem alterados os valores de num_1 e num_2 no seriam alterados.

Variveis Globais: Uma varivel dita global, se for declarada fora do bloco de uma funo. Uma varivel global tem validade no escopo de todas as funes, isto , pode ser acessadas e modificada por qualquer funo. O espao de memria alocado para esta varivel criado no momento de sua declarao e destrudo apenas quando o programa encerrado.

Exemplo: Uso de variveis globais.

float a, b, med;

void media2(void){

med = (a + b) / 2.0;

}

void main(){

puts(Digite dois nmeros:);

scanf(%f %f, &a, &b);

media2();

printf(\nA media destes nmeros e %f, med);

}

No exemplo acima, a, b, med so variveis globais definidas fora dos blocos das funes media() e main(). Deste modo ambas as funes tem pleno acesso as variveis, podendo ser acessadas e modificadas por quaisquer uma das funes. Assim no necessrio a passagem de parmetros para a funo.

6.6 Recursividade

A recursividade talvez seja a mais importante vantagem das funes em C. Recurso o processo pelo qual uma funo chama a si mesmarepetidamente um numero finito de vezes. Este recurso muito til em alguns tipos de algoritmos chamados de algoritmos recursivos.

Vejamos um exemplo clssico para esclarecermos o conceito: calculo do fatorial de um nmero. A definio de fatorial :

n! = n . (n-1) . (n-2) . ... . 3 . 2 . 1

0! = 1

onde n um numero inteiro positivo. Uma propriedade (facilmente verificvel) dos fatoriais que:

n! = n . (n-1)!

Esta propriedade chamada de propriedade recursiva: o fatorial de um numero pode ser calculado atravs do fatorial de