Você está na página 1de 120

Algoritmos e Programao

Departamento de Informtica

HISTRICO DA LINGUAGEM C
A linguagem C foi criada na dcada de 70, por Dennis Ritchie, nos laboratrios Bell. Para tanto, ele utilizou o sistema operacional Unix e a linguagem BCPL. Baseado nessa linguagem, um outro pesquisador, chamado Ken Thompson (que tambm trabalhou na criao de C) havia criado a linguagem B, que por sua vez foi influenciada pela linguagem BCPL criada por Martin Richards. Como a linguagem de Richie foi posterior linguagem B, recebeu o nome de C. A linguagem C estruturada, e considerada de nvel mdio, possui portabilidade do cdigo fonte e um programa objeto muito eficiente, rpido e compacto. Alguns Softwares escritos em C: Unix e Linux, Parte do Windows e seus Aplicativos, Borland Delphi, Turbo Pascal, C++Builder, etc.

ESTRUTURA BSICA DE UM PROGRAMA C

1 DICAS TEIS NA EDIO DE PROGRAMAS-FONTE


Salvar em modo texto (no DOC/WORD, RTF); Salvar SEMPRE o documento antes de compilar; A execuo do programa sempre comea na linha main(). Os parnteses so obrigatrios; O C caso sensitivo; Use SEMPRE a endentao, porque ela permite maior clareza de cdigo; necessrio o ponto-e-vrgula (;) ao final de cada comando.

2 FORMA GERAL
Consiste em uma coleo de funes, de acordo com a estrutura bsica:

main( ) //primeira funo a ser executada { incio da funo corpo da funo; } fim da funo

A funo main( ) tem que existir em algum lugar do programa marca o incio da execuo.

Programa mnimo em C:
main( ) { }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao Exemplo:


// Programa: prog1.cpp // Autor: Ivo Mathias e Jeferson Quimelli #include <stdio.h> #include <conio.h>

Departamento de Informtica

void main( ) { printf (Meu primeiro programa em Linguagem C); getch(); }

Toda instruo deve ser encerrada por < ; > (ponto e vrgula); printf uma funo, note um ( ) aps o nome, o que regra bsica para todos os comandos em linguagem C;

3 FUNO PRINTF( )
Funo de E/S No faz parte da definio de C necessita incluso da biblioteca stdio.h

SINTAXE:
printf (expresso de controle, lista de argumentos);

Exemplos somente com string na expresso de controle, sem lista de argumentos:

1) main( ) { printf (Esta e a linha numero um \n); printf (Esta e a linha numero dois); }

2) main( ) { printf (Esta e a linha numero um \nEsta e a linha numero dois); }

3) main( ) { printf (o nmero } 2);

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao Exemplo c/ nmero decimal como argumento:


4) main( ) { printf (o nmero %d, 2); }

Departamento de Informtica

Exemplo c/nmeros decimais e cadeia de caracteres (string):


5) main( ) { printf (Meu nome eh %s, \nEu tenho %d anos., Mario, 18); }

Sada:
Meu nome Mario, Eu tenho 18 anos.

obs: \n um cdigo especial que produz uma mudana de linha, como veremos logo frente, item 3.1.

Exemplo com caracteres:


6) main( ) { printf printf } ( A letra %c, a); ( vem antes de %c, b);

Sada:
A letra a vem antes de b

3.1 CARACTERES DE CONTROLE (SEQNCIAS DE ESCAPE)


\n \r \t \b \ \\ nova linha <enter> tabulao retrocesso aspas barra (= retorno de carro = <cr> = return) (tab) (volta posio do cursor, permitindo sobrescrever caracter) (para escrever aspas, sem fechar a expresso de controle) (para escrever barra, sem interpretar como caracter de controle)

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao Exemplos utilizando caracteres de controle/ seqncias de escape:

Departamento de Informtica

1) main( ) { printf (A\nB\nC); }

2) main( ) { printf (A\tB\tC); }

3) main( ) { printf (A\nB\rC); }

4) main( ) { printf (AB\bC); }

5) main( ) { printf (.\n.1\n..2\n...3\n); }

6) main( ) { printf (Comandos DOS residem no C:\\DOS); }

7) main( ) { printf (\Fique alerta!\, gritou o veterano.); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

3.2 CDIGOS DE FORMATAO


%c %d %e %f %o %s %x %lf %ld caracter decimal notao cientfica ponto flutuante octal cadeia de caracteres (string) hexadecimal double longint

Exemplos utilizando cdigos de formatao:

1) main( ) { printf (Este e o capitulo %d, 3); }

2) main( ) { printf (%d+%d = %d, 3, 4, 3+4); }

3) main( ) { printf (%d = %i, 3, 3); }

4) main( ) // cuidado!! Este programa gerar erro (imprimir:1717986918) { printf (O valor %d e um numero em ponto flutuante, 3.3); }

5) main( ) // programa corrigido: { printf (O valor %f e um numero em ponto flutuante, 3.3); }

6) main( ) // o cdigo %f gera sada com 7 algarismos significativos { printf (%f + %f = %f, 3.3, 4.4, 3.3 + 4.4); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

7) main( ) // %e permite impresso de pot. de 10 em formato cientfico { printf (%e + %e = %E, 8.2e+002, 3.36e+005, 8.2e+002 + 3.36e+005); } Obs: 8.2e+002 = 8.2x102 = 8.2x100 = 820 3.36e+005 = 3.36x105 = 3.36x100000 = 336000

8) main( ) // Um mesmo nmero, 16, escrito com formataes diferentes { printf (%d %o %x, 16, 16, 16); }

Sada:
16 20 10

Explicao:
Em decimal: Em octal: Em hexa: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 20 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, A, B, C, D, E, 10

3.2.1

TAMANHO DE CAMPO

Tamanho de campos: possvel estabelecer o tamanho mnimo para a impresso de um campo. Para nmeros inteiros (cdigo %d), o nmero colocado entre o % e o d estabelece o nmero de casas reservadas para a impresso do argumento. Para nmeros em formato de ponto flutuante (reais), pode-se especificar alm do tamanho total, o nmero de casas decimais que se deseja sejam mostradas. Ex: o cdigo %8.4f significa que sero reservadas oito casas para o nmero total, das quais quatro sero reservadas para a parte decimal.

Exemplos de estabelecimento de tamanhos de campo para inteiros:

1) main( ) { printf (os alunos sao %2d \n, 350); printf (os alunos sao %4d \n, 350); printf (os alunos sao %5d \n, 350); }

Sada: os alunos so 350 os alunos so 350 os alunos so 350

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

2) main( ) { printf (%d \n %2d \n %3d, 7, 8, 9); }

Exemplos de estabelecimento de tamanhos de campo para reais / ponto flutuante:

3) main( ) // especificador de formato %f, float { printf (%f %f\n, 535.45, 73745.66); printf (%16f %16f\n, 535.45, 73745.66); }

4) main( ) { printf ( %3.1f printf ( %10.3f } \ n, 3456.78); \ n, 3456.78);

Sada:
3456.8 3456.780

5) main( ) // especificador %f, com espaco para os decimais { printf (%6.2f %8.4f, 12.3456, 12.3456); }

6) main( ) // especificador %f, com mais de 19 digitos significativos { printf (o numero %f, 7493752094857203945087405.3453458); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

4 CONSTANTES
Objeto que tem valor fixo e inaltervel ao longo da execuo do programa. Exemplos: Uso:
1) main( ) //exemplo de constante inteira/decimal { printf ( o numero %d, 2); }

c,

8,

primeiro programa,

2.876.

2) main( ) { printf ( o numero 2); }

Embora os dois programas gerem a mesma sada, no primeiro o 2 tratado como constante e no segundo o 2 tratado como parte (caracter) da expresso (string) de controle.

3) main( ) //exemplo de constante de ponto flutuante ou real { printf ( o nmero %f, 3.141593); }

Obs: Em C no existem as constantes lgicas (.T., .F., true ou false) que so definidas em outras linguagens. Um valor falso representado pelo nmero 0 (zero), enquanto que qualquer outro valor decimal interpretado como verdadeiro. Isto ser visto frente, no assunto expresses lgicas.

5 VARIVEIS
Conceito: Objeto que pode assumir diferentes valores. Espao de memria de um certo tipo de dado associado a um nome para referenciar seu contedo. Recurso de armazenamento que guarda valores num formato especfico (int ou ponto flutuante, p. ex.)

5.1 DECLARAO DE VARIVEIS


Objetivo: reservar uma quantidade de memria para um certo tipo de dado, indicando o nome pelo qual a rea ser referenciada. Como no exemplo:
main( ) { int idade; idade = 30; printf ( mnima idade : %d, idade); }

Neste caso, reservou-se retirou-se dos endereos de memria disponveis um espao suficiente para _________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao armazenar constantes inteiras e se deu a este espao o nome de idade. Sintaxe: No modo mais simples a declarao de variveis tem a forma:
tipo ou tipo nome-da-varivel; nome1, nome2, ... nomen;

Departamento de Informtica

Exemplos de declaraes de variveis:


1) int int 2) int 3) char letra; int nmero, idade=20; //inicializando varivel na declarao a, b; a; b;

Programas-exemplo:
1) main( ) { int x; float y; x = 3; y = 3 * 4.5; printf ( %d * 4.5 = %f, x, y); } 2) main( ) { int soma; soma = 3 + 5; printf ( soma : %d, soma); }

Obs: As variveis podem ser inicializadas quando de sua declarao, como nos exemplos:
int i,contador = 0; float a, b, media = 3.3;

Esta possibilidade ajuda a melhorar a clareza e qualidade do programa, assim como sua manuteno, por definir um ponto claro no incio do programa para inicializao das variveis. Qualquer consulta ao valor ou alterao ficam assim facilitadas.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

5.2 TIPOS BSICOS


Tipos bool char unsigned char short int unsigned short int unsigned int long unsigned long float double Caractersticas Booleano Caracteres caracteres s/sinal Inteiros inteiros s/sinal inteiros c/sinal inteiros s/sinal inteiros c/sinal inteiros s/sinal preciso simples 7 dgitos preciso dupla 15 dgitos Bytes 1 1 1 2 2 4 4 4 4 4 8 Escala 0 a 1 -128 a 127 0 a 255 -32768 a 32767 0 a 65535 -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 -2.147.483.648 a 2.147.483.647 1.7e-308 a 1.7e+308

Obs: o tipo int tem sempre o tamanho da palavra da mquina.

O tamanho, em bytes, de cada tipo de varivel pode ser obtido por um programa como o abaixo:
#include <stdio.h> #include <conio.h> main( ) { bool b; printf (Tamanho em bytes da varivel tipo bool: ); printf (%d, sizeof(b)); getch(); }

5.2.1.1

MODIFICADORES DE TIPOS short aplicado a um tipo, cria um novo tipo que ocupa metade dos bytes do tipo original. Ex: short int. long - aplicado a um tipo, cria um novo tipo que ocupa o dobro dos bytes do tipo original. Ex: long int. unsigned permite que todo o domnio, que antes se aplicava a nmeros negativos e positivos, se aplique somente a nmeros positivos..

Exemplo de declarao, atribuio e impresso de variveis:


main( ) { bool a; char b; unsigned char c; short int x; unsigned short x1; int z; unsigned int z1;

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao
long z2; unsigned long z3; float r; double r1; a b c x x1 z z1 z2 z3 r r1 = = = = = = = = = = = 1; 'i'; 'I'; 32767; 65535; 2147483647; 4294967295; 2147483647; 4294967295; 2147483647; 1.7e+308; -> %d -> char -> -> short -> -> int -> -> long -> -> -> ", %c %c %d %d %d %u %d %u %f %e

Departamento de Informtica

printf ("bool printf ("\n\nchar printf ("\n\nunsigned printf ("\n\nshort printf ("\n\nunsigned printf ("\n\nint printf ("\n\nunsigned printf ("\n\nlong printf ("\n\nunsigned printf ("\n\nfloat printf ("\n\ndouble getch(); }

a); - %d", b,b); - %d ", c,c); ", x); ", x1); ", z); ", z1); ", z2); ", z3); ", r); ", r1);

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

5.3 INICIALIZAO DE VARIVEIS


a combinao de uma declarao de variveis com o operador de atribuio e um valor. Tem a vantagem de: Tornar mais claro o valor inicial da varivel Facilitar a troca de valores (sem ter que procurar a linha de inicializao)

Exemplo:
main( ) { int evento = 5; char corrida = c; float tempo = 27.25; printf ( o melhor tempo da eliminatria % c, corrida); printf ( \ n do evento %d foi % f, evento, tempo); }

5.4 NOMES DE VARIVEIS


obs: C sensvel ao caso (maisculos e minsculos):
peso <> Peso <> pEso

Quantos caracteres quiser (32). Comece com letras ou sublinhado: seguidos de letras, nmeros ou sublinhados

No pode-se definir um identificador com o mesmo nome que uma palavra chave.

Palavras Chave:
Auto if static do extern default int while long do if e outras...

6 FUNO SCANF( )
Sintaxe:
scanf(expresso de controle, lista de argumentos)

Funo de E / S - complemento de printf( ). A expresso de controle utiliza cdigos de formato que iniciam com: % ou %* A lista de argumentos composta por variveis precedidas por &: &varivel Quando usamos & precedendo uma varivel, estamos falando do endereo da mesma na memria. O que passado para a funo SCANF no o contedo da varivel, mas sim o endereo da varivel, para que a funo coloque neste endereo o valor digitado. Isto ser visto com maior detalhes ao estudarmos como o C efetua o retorno de valores de funes.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

6.1 CDIGOS DE FORMATAO


%c %d %e %f %o %x %s %lf caracter inteiro nmero ou notao cientfica ponto flutuante octal hexadecimal string (cadeia de caracteres) double

SCANF(

Exemplos:

1) main( ) { int num; char letra; scanf( %d, &num); scanf ( %c, &letra); printf(numero digitado: %d, num); printf(\nletra digitada: %c, letra); }

2) main( ) { char a ; printf ( digite um caracter ); scanf ( % c, &a ); printf ( \n %c = %d em decimal, a, a); printf (%o em octal, %x em hexadecimal, }

a,

a);

Para este ltimo exemplo, se voc digitar a tecla m, o programa ecoar:


m = 109 em decimal, 155 em octal, 6d em hexadecimal

6.1.1

CDIGO DE FORMATAO COM ASTERISCO (*) Se voc colocar um asterisco (*) no especificador de formato scanf, ele ignora na leitura o valor digitado para o campo e continua a leitura com o prximo especificador de formato. Este especificador tem maior utilidade em leitura de arquivos, para que no sejam efetivamente lidas informaes no relevantes pesquisa em curso.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao Exemplo:


main( ) { int valor;

Departamento de Informtica

printf ( digite um valor ponto flutuante e um inteiro); scanf( %*f %d, valor); printf ( \n Valor inteiro digitado %d, valor); }

7 FUNES GETCHE( ) E GETCH( )


A funo scanf obriga que a tecla <enter> seja pressionada aps a entrada dos dados. A biblioteca de C oferece funes que lem dados sem esperar <enter>.
getche( ) getch( )

l um caracter do teclado ecoando-o na tela. l um caracter do teclado sem eco-lo na tela.

Exemplos:
1) USANDO getche() ... main( ) { char ch; printf ( digite um caracter); ch = getche( ); printf ( \n todos sabem que voc digitou %c, ch); }

Executando:
digite um caracter: a todos ja sabiam que voc digitou a

2) USANDO getch() ... main( ) { char ch; ch = getch( ); printf ( \ n somente agora saberemos); printf (que voc digitou %c, ch); }

Executando:
Digite um caracter: somente agora saberemos que voc digitou b

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

8 OPERADORES
8.1 OPERADORES ARITMTICOS SIMPLES
Binrios: Unrio: Exemplos:
int a, b; b a b b = = = = 3; b + 2; a * b; 7 % 2 = + * / %

(aplicado sobre um operador somente)

resto da diviso entre inteiros. No caso, o resultado seria 1.

main() { int a, b; a = 700 / 2; b = 700 % 2; printf("divisao = %d resto = %d", a, b); )

A atribuio em C uma expresso. Logo voc pode executar do mesmo modo estas duas instrues abaixo:
a a = = 5; b =

4 * a;

Como no programa:
main( ) { int a, b; a = 5; a = b = 4*a; printf("a= %d, ", a); printf("\nb= %d, ", b); getch(); }

Obs: Em Pascal isto no seria permitido:


a := b := 4 * a; <invlido

Devendo esta instruo ser implementada em duas etapas:


b a := := 4 * a; b;

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

Ateno! Em C, as instrues:
a = 2000; 2000 = a;

vlido invlido. No se pode atribuir valor a uma constante, s a uma varivel.

Exemplos:
1) main( ) { float nota1, nota2, media; printf ( digite a primeira nota: ); scanf ( %f , &nota1); printf ( digite a segunda nota: ); scanf ( %f , &nota2); media = (nota1+nota2)/2; printf ( sua media final %f, media); }

2) main( ) { float nota1, nota2; printf ( digite as notas: ); scanf ( %f %f, &nota1, &nota2); printf ( sua media final %f, (nota1+nota2)/2); }

3) main( ) { int nota, conceito; printf ( entre com a nota e o conceito); scanf ( %d %d, &nota, &conceito); printf ( sua nota final %d, nota * conceito); }

Exerccio proposto: Expanda este ltimo exemplo, (3), de modo a ficar mais clara a digitao dos dados durante a execuo e a leitura do programa
4) main( ) { int resto, divisor, dividendo; printf(entre com 2 nmeros); scanf( %d %d , &dividendo, &divisor); resto = dividendo % divisor; printf(\nresto da diviso inteira de %d, dividendo); printf(por %d = %d, divisor, resto); }

Sada:
entre com 2 nmeros 10 4 resto da diviso inteira de 10 por 4 = 2

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

8.2 OPERADORES INCREMENTO (++) E DECREMENTO (--)


Incrementam / decrementam uma unidade de seu operando. Modos distintos pr-fixado / ps-fixado.

Exemplos:
int n; n n = = n + 1; -> n + 1; -> n = 1 n = 2

n = 0; n++; -> ++n; ->

Se o operador usado em uma expresso, o valor da varivel que incrementada ou decrementada depende se o operador pr-fixado ou ps-fixado: Exemplos:
1) n = 5; x = n++; x = 5 (usa a varivel e depois incrementa) n = 6

2) n = 5; x = n++ * 3; x = 15 (usa a varivel e depois incrementa) n = 6

3) n = 5; x = ++n * 3; x = 18 (incrementa e depois usa a varivel) n = 6

4) n = 6; x = n-- / 2;

x = 3 (usa a varivel e depois decrementa)

n = 5

5) n = 5; x = --n / 2; x = 2 (decrementa e depois usa a varivel) n = 4

6) main( ) { int num = 0; printf ( %d, num); printf ( %d, num++); printf ( %d, num); }

Sada:
0 0 1

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao
7) main( ) { int num = 0; printf ( %d, num); printf ( %d, ++num); printf ( %d, num); }

Departamento de Informtica

Sada:
0 1 1

Desafio: E se no lugar de num++ e ++num tivssemos num-- e --num, qual seria a sada? Exemplo 6: ___ ___ ___ Exemplo 7: ___ ___ ___

8) main( ) { int z=199, w=100; ++z; w--; printf(z = %d, z); printf(\nw = %d, w); }

9) main( ) { int valor1=0, valor2=0; printf(valor inicial = %d , valor1); printf(\nvalor com incremento pre-fixo = %d , ++valor1); printf(\nvalor com incremento pos-fixo = %d , valor2++); }

10) main( ) // Neste programa, a ordem - pr ou ps - faz diferena { int x, z=199, w=100; x = (++z) (w--); printf(x = %d z = %d w = %d, x, z, w); }

Exerccio: Refaa este ltimo exemplo, retirando os parnteses e alterando a ordem do operador.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

8.3 PRECEDNCIA ENTRE OS OPERADORES ARITMTICOS


A precedncia entre os operadores aritmticos simples a seguinte: Primeiramente: - (unrio) Depois: * / % + Finalmente: = (atribuio binrio)
Ou seja: x = 3 * a - b x = y = 5 % 2 -> -> x = (3 * a) - b x = (y = (5 % 2))

A precedncia dos operadores de incremento e decremento maior que a dos operadores aritmticos simples: Primeiramente: ++ e -Depois: - (unrio) Depois: * / % + Finalmente: = (atribuio binrio)
Ou seja: x = 3 * a++ - b y = 3 * --a - b z = a * b++ -> -> -> (3 * (a++)) - b (3 * (--a)) - b a * (b++)

Obs: os operadores de incremento e decremento, ++ e -- s podem ser usados com variveis. Assim, estas expresses geraro erro:
(a * b)++; 5++;

8.4 USO DE OPERADORES ++ E COM PRINTF( )


O uso de operadores de incremento e decremento, ++ e -- em argumentos da funo printf pode gerar resultados inesperados e indesejados, tendo em vista que 1) Alteram o valor da varivel 2) So avaliados da direita para a esquerda ou da esquerda para a direita dentro da lista de argumentos, dependendo de uma verso do compilador C para outra: Assim, as instrues:
n = 5; printf ( %d %d %d \n, n, n + 1, n++);

tero a sada abaixo se a avaliao for feita da direita para a esquerda (primeiro o n++) :
6 7 5

caso a avaliao dos argumentos da lista fosse feita da esquerda para a direita, a sada seria:
5 6 5

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao Outros exemplos:

Departamento de Informtica

1) main( ) { int n, i = 3; n = i * (i + 1) + (++i); printf (n = %d, n); }

Sada para avaliao direita:


n = 24

2) i = 3; printf(%d %d %d, i = i + 1, i = i + 1, i = i + 1);

Sada para avaliao direita:


6 5 4

Exerccio proposto: determine quais seriam as sadas para avaliao esquerda

8.5 OPERADORES ARITMTICOS DE ATRIBUIO


Operadores:
+=, -=, *=, /=, %=

Funcionalidade: atribui um novo valor varivel dependendo do operador e da expresso a direita. Justificativa: Obs: o uso destes operadores produz cdigo de mquina mais eficiente Sintaxe:
x op = exp

equivalente a

x = (x) op (exp)

Exemplos:
i x t p h += *= /= %= -= 2 y + 1 4 6 3 i x t p h = = = = = i x t p h + * / % 2; (y + 1) 4 6 3;

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

8.6 OPERADORES RELACIONAIS


Operadores relacionais so aqueles utilizados para comparaes:
> >= < <= == !=

maior maior ou igual menor menor ou igual igualdade diferena

Obs: em C no existe a constante dita booleana (false, .F., .T. true): O valor falso representado pelo valor zero (0);
falso = (15 == 20); ser atribudo o valor zero(0)para falso

Comparaes verdadeiras retornam o resultado um (1) (muito embora qualquer valor diferente de zero seja interpretado pelo C como verdadeiro).
verdadeiro = (15 < 20); if (4==4), if(1), ser atribudo o valor um(1) p/ verdadeiro if(33) tero o mesmo resultado.

Exemplo:
main( ) { int verdadeiro, falso; verdadeiro = (15 < 20); falso = (15 == 20); printf (Verdadeiro = %d, falso = %d, verdadeiro, falso); }

Sada:
Verdadeiro = 1 falso = 0

A precedncia dos operadores, incluindo agora os relacionais, fica:


-(unrio) ++ -* / % + -(binrio) < > <= >= == != = += -= *= /= %=

8.7 OPERADORES LGICOS


Muitas vezes necessrio colocar uma condio composta para teste de um if. Isto conseguido com os operadores lgicos, && (e), II (ou) e ! (negao/no). Estude bem os exemplos abaixo de uso de condies com operadores lgicos:

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao
1) (a > 10) || (a < 100)

Departamento de Informtica condio final verdadeira somente se a>10 e a<100

2) (a > 10) && (x < 10)

condio final verdadeira se a>10 ou x<10

3) (x 4) ! (x > 0) && y)

condio final verdadeira se x <>0 ou y<>0 condio final verdadeira se x <=0

(lembre-se: zero representa falso)

5) if ((10 < a) && (a < 100))

// verdadeiro se 10 < a < 100

6) if ((10 < a) || (a == -1))

// verdadeiro se a>10 ou se a= = -1

7) if((10 <= a) <= 100) if ((10 <= a) && (a < 100))

equivalente a: // verdadeiro se (10 <= a <= 100)

8) O programa: main( ) { char ch; printf ( digite uma letra entre A e Z); ch = getche( ); if ((ch >= A) && (ch < = Z)) printf ( Voc acertou) }

substitui, com vantagem de clareza e economia de cdigo, a estrutura if do programa abaixo:


main( ) { char ch; printf ( digite uma letra entre A e Z); ch = getche( ); if (ch >= A) if (ch < = Z) printf ( voc acertou) }

Precedncia: (maior) (! - ++ --), (* / %), (+ -) aritmticos, (< > <= >= <>), (== !=) relacionais, (&&), (||) lgicos, (= += -= *= /= %=) atribuio (menor)

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

9 COMENTRIOS
Informao acrescentada ao cdigo para facilitar sua compreenso. ignorado pelo compilador (no faz parte do cdigo objeto). Comea com /* terminando com */. Ou pode ser // no inicio da linha. Exemplo:
/* isto um exemplo de comentrio main( ) { // isto outro comentrio printf ( apenas um exemplo); } */

invlido utilizar /* ou */ dentro de um comentrio:


/* isto no um /* comentrio */

Entretanto, vlida a seguinte instruo:


/ * comentrio em mais de uma linha */

10 ESTRUTURA SEQENCIAL
a mais simples estrutura: a execuo seqencial das instrues do incio at o final. Tambm conhecida como por gravidade. Programa-exemplo:
main( ) { int x; float y; x = 3; y = 3 * 4.5; printf ( %d * 4.5 = %f, x, y); }

TAREFAS: Elaborar em algoritmo e em C os programas-soluo para os problemas: 1) Informar o dobro de um numero; 2) Dados dois nmeros, informar a diviso do primeiro pelo segundo e o resto da diviso (dica: operados MOD - %); 3) Calcule uma idade, sendo dados o ano do nascimento e o ano do ltimo aniversrio; _________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

11 ESTRUTURAS DE DECISO
Inserem inteligncia ao programa, permitindo-o tomar decises, com aes alternativas, a partir de testes, conhecidos como condies. Estas condies lgicas ou testes consistem avaliao do estado de variveis ou de expresses, avaliaes estas sempre tero resultado verdadeiro ou falso.

11.1 FORMA GERAL EM C:


if (<condicao>) { <comando_composto_1>; } else { <comando_composto_2>; }

exemplo:
if (a<b) { a=b; c=2; } else { b=a; c=4; }

Comportamento: O comando if s executa o <comando_composto_1> caso a condio de teste seja verdadeira, nada fazendo se a expresso for falsa. Caso a a expresso de teste for falsa ser executado o <comando_composto_2>. Em algoritmo/pseudo-linguagem/ portugus estruturado, a forma geral seria:
se <condio> ento <comando_composto_1>; seno <comando_composto_2>; fim_do_se

11.2 ESTRUTURA SIMPLIFICADA 1


Estrutura de deciso sem a opo do else/ seno:
if (<condicao>) { <comando_composto_1>; }

Exemplo:
if (a<b) { a=b; c=2; }

11.3 ESTRUTURA SIMPLIFICADA 2


Se os comandos no so compostos, ou seja, so instrues isoladas, as implementaes em C ficam:
if (<condicao>) <instruo_1>; else <instruo_2>;

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

Observe que a <instruo 1> finalizada com o ; (ponto e vrgula). Isto no significa o final da estrutura de deciso, mas sim da instruo. Em Pascal, este ponto e vrgula no comando intermedirio no existe. Exemplos da estrutura simplificada 2:
1) if (a<b) a=b; else b=a; 2) main( ) { if (getche ( ) == p) printf ( voc digitou p); else printf ( voc no digitou p); }

11.4 ESTRUTURA SIMPLIFICADA 3


A mais simples: uma s instruo, sem a opo else:
if (<condicao>) <instruo_1>;

exemplo:

if (a<b) a=b;

outros exemplos:
1) if (i==j) printf( I e j sao iguais);

2) if (i!==j) printf( I e j sao diferentes);

3) main( ) { char ch; ch = getche ( ); if (ch == p) printf (voc pressionou a tecla p); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao
4) main( ) { if (getche()) == p ) { printf ( voc digitou p); printf ( pressione outra tecla ); getche( ); } //fim do if } //fim do programa

Departamento de Informtica

11.5 ESTRUTURAS DE DECISO ANINHADAS


Utilizadas quando se quer efetuar um segundo ou terceiro teste dentro da estrutura.
if (<condicao>) { <comando_composto_1>; } else if (<condicao>) { <comando_composto_2>; } else { <comando_composto_3>; }

Exemplo:
main( ) { char ch; printf ( digite uma letra entre A e Z); ch = getche ( ); if (ch >= A) if (ch < = Z) printf ( voc acertou) }

11.5.1

EXECUO DA OPO ELSE EM ESTRUTURAS IF ANINHADAS PROBLEMA: Na execuo do programa abaixo, quando a instruo associada ao else, z=b, ser executada, quando n no for igual a zero, ou quando a no for maior que b?
if (n > if (a z = else z = 0) > b) a; b;

RESPOSTA: O else, em estruturas if-else-if sempre associado ao if mais interno (mais prximo). No caso, o else estar associado ao segundo if. Isto quer dizer que para a execuo das instrues sob o else somente sero executadas se as condies de todos os ifs forem falsas.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

Para que o else esteja associado ao if mais externo (o de cima), a estrutura deveria ficar:
if (n > 0) { if (a > b) z = a; } else z = b;

Este outro exemplo est errado:


if (n < 100) if ( n < 10) printf (n eh menor que 10); else printf (n eh menor que 100);

// ativada para 10<=n<100

A verso corrigida seria:


if (n < 100) if ( n < 10) printf (n eh menor que 10); else printf (n eh menor que 10);

//

mensagem corrigida

ou
if (n < 100) { if ( n < 10) printf (n eh menor que 10); } else //agora sim o else se refere ao primeiro if printf (n eh menor que 100);

Mais um exemplo correto de utilizao da estrutura if - else if else:


main( ) { int a, b, c; printf("digite o primeiro operando: "); scanf("%d", &a); printf("digite o segundo operando: "); scanf("%d", &b); printf("\n1 - soma: "); printf("\n2 - subtracao: "); printf("\n3 - multiplicacao: "); printf("\n4 - divisao: "); printf("\ninforme a operacao: "); scanf("%d", &c); if (c==1) printf("\n\n soma: %d", a+b); else if (c==2) printf("\n\n subtracao: %d", a-b); else if (c==3) printf("\n\n multiplicacao: %d", a*b); else if (c==4) printf("\n\n divisao: %d", a/b); else printf("\n\n Voce no digitou nenhum valor valido"); getch(); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

APLICAO: Elaborar um algoritmo para, dados trs nmeros, determinar o menor deles.

Implementao menos refinada, dentro da arquitetura TOP-DOWN:


Algoritmo Defina variveis Leia os nmeros Determine o menor nmero Escreva o menor nmero Fim do algoritmo

Implementao mais refinada:


Algoritmo Declare a, b, c numricos Leia a, b, c Se a<b e a<c Ento menor a Seno se b < c Ento menor b c Seno menor Fim do algoritmo

Implementar este algoritmo em C: Se a<b e a<c Dica:

if((a<b)&&(a<c))

11.6 OPERADOR CONDICIONAL TERNRIO ?:


Forma compacta de expressar uma instruo if - else. Sua forma geral :
(condio) ? expresso 1 : expresso 2

Comportamento: Se condio for verdadeira, ser executada a expresso 1. Caso contrrio, ser executada a expresso 2. Exemplo 1:
Max = (num1 > num2) ? num1 : num2;

Esta instruo equivale a:


if (num1 > num2) Max = num1; else Max = num2;

Exerccio proposto: construa a estrutura if equivalente a:


ABS = (num < 0) ? - num : num;

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

12 ESTRUTURAS DE REPETIO
Embora as estruturas seqencial e de repetio sejam essenciais em programao, so as estruturas de repetio que permitem que permitem acesso ao potencial dos computadores e executar clculos muito rpidos. Poder-se-ia conseguir a impresso dos nmeros inteiros, de 1 a 5, utilizando a estrutura seqencial, neste programa com cinco linhas de instrues:
main( ) { printf printf printf printf printf }

( ( ( ( (

1 2 3 4 5

); ); ); ); );

Sada: 1

Entretanto, no seria vivel utilizar o mesmo mtodo para imprimir os 1000 primeiros nmeros a partir de 1, porque este exigiria pelo menos 1.000 linhas de cdigo:
main( ) { printf (1); printf (2); : : : printf (1000); }

A resoluo deste problema (e de outros) a utilizao de estruturas de repetio: Em algoritmo: Enquanto..faa, repita..at e para..faa. Equivalentes em C: estruturas: while, do-while e for. Cada execuo do conjunto (bloco) de instrues subordinadas a estas estruturas chama-se de iterao ou loop.

12.1 ESTRUTURA WHILE (ENQUANTO..FAA)


Comportamento: A estrutura while examina uma expresso de teste. Se e enquanto esta condio for verdadeira (!=0), o grupo de instrues da estrutura ser executado repetidamente, at que a condio seja avaliada como falsa (=0).

Exemplo: impresso dos mil primeiros nmeros inteiros:


main( ) { int num=1; while(num<=1000) { printf ( % d, num); num++; } }

Sada: 1

3 ... 1000

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

A estrutura while possui quatro elementos fundamentais, perfeitamente identificveis no exemplo dado: o a inicializao da varivel de controle, o o teste para execuo das instrues, o as prprias instrues e o a modificao da varivel de controle. Caso o programa apresente indcios de travamento, verifique a hiptese de que ele esteja em repetio infinita (ou loop infinito). Para verificar (e corrigir) a causa deste comportamento anmalo, determine com exatido como a estrutura executa cada um dos quatro elementos fundamentais descritos: inicializao, teste, instrues e modificao.

O programa anterior poderia ser alterado para chegar sua forma simplificada, mostrando que a estrutura while no exige o uso das chaves para delimitao das instrues a serem executadas repetidamente. Observe tambm que esta estrutura tem sintaticamente a caracterstica de no possuir ; ao seu final (caracterstica esta apresentada pela estrutura do-while):
main( ) { int num=1; while(num<=1000) printf ( % d, num++); }

Desafio: Tente descobrir por que os programas abaixo entram em loop infinito e escreva a verso corrigida. Dica: teste os quatro elementos do while (que no so terra, gua, fogo e ar...). Programa 1:
main( ) { int num=1; while(num<=1000) printf ( % d, num-=5); }

Programa 2:
main( ) { int cont=20; while(cont<=800); printf ( % d, cont++); }

Programa 3:
main( ) { int num=1; while(num<=1000) printf ( % d, num); }

Seja muito criterioso ao alterar o valor da varivel de controle dentro da estrutura for. De preferncia, nunca faa isso, a no ser que no haja outro jeito. Voc pode literalmente perder o controle da execuo da estrutura.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

12.2 ESTRUTURA FOR (PARA..FAA)


A estrutura de repetio for substitui, na maioria dos casos, e com vantagens, a estrutura while. Forma geral:
for (inicializao; teste; incremento) { <bloco de instrues>; }

Comportamento: Esta estrutura inicializa a varivel de controle, testa o seu valor desta varivel e, aps, modifica o seu valor, incrementando ou decrementando. Se o teste tiver resultado positivo, a estrutura permite a execuo das instrues associadas. Se no, o controle passado prxima instruo aps a estrutura. Em outras palavras: o Inicializao: Expresso de atribuio que executada uma nica vez; o Teste: Condio que controla a execuo do lao. sempre avaliada a cada execuo: se o resultado verdadeiro, executa-se novamente as instrues associadas; se falso, interrompe-se a execuo; o Incremento: Define como a varivel de controle ser alterada; Efetuado aps execuo do corpo do lao, define o valor da varivel de controle para a prxima iterao. o Bloco de instrues: se houver somente uma instruo a executar, dispensa-se o uso das chaves. Exemplo:
main( ) { for (num=1; num<=1000; num++) printf ( % d, num); }

Perceba que a estrutura for apresenta os mesmos quatro elementos fundamentais da estrutura while: inicializao, teste, modificao e instrues. Identificando estes quatro elementos em uma estrutura while, voc poder facilmente transform-la em uma estrutura for. O que pode ser muito til se voc estiver com dificuldades em construir sua estrutura for.

Outros exemplos: 1) Inicializao e incremento diferentes de um. Programa que imprime os nmeros pares menores que 10:
main( ) { int nmero; for } (nmero=2; nmero<10; nmero += 2) printf ( %d, nmero);

Os exemplos 2 , 3 e 4, a seguir, utilizam mais de uma varivel na estrutura de controle, ou seja, a inicializao e o incremento com mais de uma varivel, separadas por vrgulas. Ateno: A estrutura for admite somente uma condio de teste.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

2) Programa que imprime simultaneamente os nmeros de 1 a 100 e de 101 a 200:


main( ) { int x, y; for (x=1, y=101; x<=100; x++, y++) printf (%d \t %d, x, y); }

3) Programa que imprime as letras do alfabeto e a sua ordem


main( ) { char ch; int i; for (i=1, ch=a; ch <= z; ch++, i++) printf (%d.a letra = %c \n, i, } ch);

4) Programa que imprime as letras de A a F, em maisculas e minsculas:


main( ) { char maiusc, minusc; printf(Maisculas \t Minusculas); for (maiusc=, minusc=a; maiusc<F; maiusc++, minusc++) printf(%c \t %c \n, maiusc, minusc); }

5) Exemplo de programa com uso de funes nas expresses do lao:


main( ) { char ch; for (ch=getch( ); ch!=x; ch=getch( )) printf ( %c, ch + 1); }

6) O programa do exemplo anterior, reescrito omitindo expresses. Permanece apenas o ;, marcando a posio do elemento omitido:
main( ) { char ch; for ( ;(ch=getch( )) != x; ) printf ( %c, ch+1); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

7) Programa com omisso da expresso de teste. Neste caso, ela considerada sempre verdadeira:
main( ) { for ( ; ; ) printf ( \n estou }

em

loop

infinito...);

8) Programa na forma geral, com mltiplas instrues no for:


main( ) { int n, codigo, num=60; float nota1, nota2; for (n=1, n<=num; n++) { printf(Codigo do aluno:); scanf(%d, codigo) printf(Nota 1:); scanf(%f, nota1); printf(Nota 2:); scanf(%f, nota2); printf(Media: %f, (nota1+nota2)/2.0) }

9) Programa que utiliza como condio para parada o valor nulo, como valor falso:
#include <stdio.h> #include <conio.h> main() { int x,y, z; for (x=0, y=4, z=1000; z; z/=10) printf ("x= %d \t y= %d \t z= %f \n", x,y,z); getch(); }

10) Programa que escreve a tabela ASCII na tela, uma tela por vez:
void main() { int cont, linha=1; printf("Decimal\t\tOctal\t\tHexadecimal\n"); for (cont=0; cont<=255; cont++) { printf("%d \t\t %o \t\t %c \t\t\n", cont, cont, cont); linha++; if (linha==24) { linha=1; getch(); } } }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao Desafio: Descubra o erro do programa abaixo:


main( ) { int i; for ( i = 0; i printf ( i ); } < 100; i++ ) ;

Departamento de Informtica

Sada desejada: 1 2 ... 99 100

Sada obtida: 100

12.2.1

LAOS ANINHADOS

Quando um lao for, while ou do-while est dentro de outro, dizemos que o lao interior est aninhado. Exemplo:

main( ) { int linha, coluna; for (linha=1; linha<=2; linha++) { for (coluna=1; coluna<=3; coluna++) printf (linha %d coluna %d \t, linha, coluna); printf(\n); } }

Sada:

linha 1 coluna 1 linha 2 coluna 1

linha 1 coluna 2 linha 2 coluna 2

linha 1 coluna 3 linha 2 coluna 3

12.2.2 while VERSUS for

estrutura for Sabe-se a princpio o nmero de interaes; estrutura while No se sabe a princpio o nmero de interaes. Ou seja, quando no se tem como determinar o nmero de repeties do lao, usa-se estrutura while quando se pode determinar o nmero de repeties do lao, usa-se estrutura for Exemplo do uso do while:Contar o nmero de caracteres de uma frase at que <Enter> seja digitado.
main( ) { int cont = 0; printf (digite uma frase: \n); while (getche( ) != \r) cont++; printf (\n Nmero de caracteres: %d, cont); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

12.3 DO-WHILE
Implementao em C da estrutura em algoritmo repita..at; Cria um ciclo repetitivo at que a expresso de teste seja falsa (=0). Similar ao lao while, entretanto a condio avaliada no final da estrutura.

Forma Geral:
do { <bloco de instrues> } while (expresso de teste);

1) Exemplo de aplicao imediata com bloco de instrues:


main( ) { int n=1; do { printf (n= %d, n); n++ } while (n<=100); }

2) Simplificao do programa anterior, uma nica instruo (chaves opcionais):


main( ) { int n=1; do printf (n= %d, n++); while (n<=100); }

3) Programa que testa a capacidade de adivinhar uma letra, utilizando estruturas while e do-while:
main( ) { char ch; int tentativas; do { printf (digite uma letra); tentativas = 1; while ((ch = getch( )) != t) { printf (%c incorreto \n, c); tentativas++; printf (tente novamente \n); } printf (%c correto, c); printf (acertou em %d vezes, tentativas); printf (continua? (s / n):); } while (getche( ) == s); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

13 SWITCH
Forma de substituir a estrutura ifelse if-else ao se executar vrios testes com maior flexibilidade e formato limpo;

Forma geral:
switch (expresso) { case constante1: <instrues;> break; case constante2: <instrues> break; default: <instrues> }

As instrues colocadas aps cada case e a instruo break associada so opcionais e podem ser omitidas, conforme podem ser ver nos exemplos colocados a seguir. A expresso de controle do switch deve resultar em um valor inteiro ou caracter. obrigatrio o uso de constantes aps a palavra reservada case. Expresses ou variveis sero rejeitadas pelo compilador se inseridas neste local. Caso a condio deva ser expressada por uma expresso ou por um domnio/extenso (2 a 20, p. ex.), deve se usar a estrutura if else if else. A instruo break, que pode ser usada em qualquer estrutura de repetio em C, causa a sada imediata do lao. Quando estiver presente em laos aninhados afetar somente o lao que o contm (e os internos, obviamente). Comportamento: O switch avalia o resultado da expresso e procura este valor na lista de opes. Se encontrar, executa a lista de opes associada a esta opo. Se no encontrar, passa-se a executar a primeira instruo aps a estrutura switch. Caso no haja um comando break aps a lista de instrues associada opo encontrada, o programa continuar na execuo das instrues associadas s outras opes abaixo. Veja no exemplo:

main( ) { char letra; for (letra=A; letra <= Z; letra++) switch(letra) { case A: printf("%c, letra); case E: printf("%c, letra); case I: printf("%c, letra); case O: printf("%c, letra); case U: printf("%c, letra); } }

a sada ser: AAAAAEEEIIIOOU Este resultado indesejado ocorre porque cada vez que o switch recebe para teste uma letra para a qual existe uma opo, esta letra impressa no printf correspondente e em todos abaixo. Para que o programa funcione como desejado, necessrio colocar uma instruo break aps cada opo case, do seguinte modo: _________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao
main( ) { char letra; for (letra=A; letra <= Z; letra++) switch(letra) { case A: printf("%c, letra); break; case E: printf("%c, letra); break; case I: printf("%c, letra); break; case O: printf("%c, letra); break; case U: printf("%c, letra); break; } }

Departamento de Informtica

agora, sim, a sada ser: AEIOU Em algumas vezes pode ser til a utilizao da tcnica de encadeamento em um switch, ou seja, permitir que uma instruo (ou mais) possa ser ativada por vrios case, pela no utilizao da instruo break, mas isto pode resultar em erros de difcil deteco. Veja uma boa utilizao da tcnica no exemplo:
main( ) { char letra; for (letra=A; letra <= Z; letra++) switch(letra) { case A: case E: case I: case O: case U: printf("%c, letra); } } cuja sada ser: AEIOU

O rtulo default em uma estrutura switch tem o mesmo efeito que uma clusula else em um if, ou seja, permite especificar instrues alternativas caso nenhuma opo do switch seja ativada. Veja o exemplo que imprime o nmero de vogais e consoantes do alfabeto:
main( ) { char letra; int vogais = 0; int consoantes = 0; for (letra=A; letra <= Z; letra++) switch(letra) { case A: case E: case I: case O: case U: vogais++; break; default : consoantes++; } printf("Vogais: %d Consoantes: %d, vogais, consoantes); }

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Algoritmos e Programao

Departamento de Informtica

O programa calculadora da p. 26 seria substitudo com vantagem pelo abaixo, que utiliza a estrutura switch:
main( ) { int a, b, c; printf("digite o primeiro operando: "); scanf("%d", &a); printf("digite o segundo operando: "); scanf("%d", &b); printf("\n1 - soma: "); printf("\n2 - subtracao: "); printf("\n3 - multiplicacao: "); printf("\n4 - divisao: "); printf("\ninforme a operacao: "); scanf("%d", &c); switch(c) { case 1: printf("\n\n soma: %d", a+b); break; case 2: printf("\n\n subtracao: %d", a-b); break; case 3: printf("\n\n multiplicacao: %d", a*b); break; case 4: printf"\n\n divisao: %d", a/b); break; default: printf("\n\n Voce no digitou nenhum valor valido"); } getch(); }

14 BREAK
Pode ser usado em qualquer estrutura de lao em C. Causa a sada imediata do lao. Quando presente em laos aninhados afetar somente o lao que o contm (e os internos, obviamente).

Exemplo:
main( ) { int num; while (1) { printf ( \n digite um nmero, zero para encerrar: ); scanf (%d, &num); printf ( 2 * %d = %d, num, 2*num); if (num == 0) break; } }

15 CONTINUE
Faz que seja executada a prxima interao do lao (ignorando o cdigo que estiver abaixo). No caso de while ou do-while, o comando continue desvia o controle para o teste condicional. No caso de um lao for, primeiro o incremento executado e depois o teste condicional.

Obs: Deve-se evitar o uso do comando continue, pois dificulta a manuteno de um programa.

_________________________________________________________________________________ Professores: Jeferson Antonio Quimelli e Ivo Mrio Mathias

Estrutura de Programao

Departamento de Informtica

$:

CONTINUE
8or)a a pr#ima intera)*o do la)o (ignorando o cdigo %ue esti,er abai#o+. Co caso de wRile, 5o wRile, o comando continue fa! com %ue o controle ,1 direto para o teste condicional. Co caso de um la)o for, primeiro o incremento e#ecutado e depois o teste condicional.

6bs2 De,e se e,itar o comando continue, pois dificulta a manuten)*o de um programa.

$= E3ERCTCIOS #RO#OSTOS F ESTRUTURAS DE SELE&'O E RE#ETI&'O


>. Dados tr;s ,alores distintos, escre,; los em ordem crescente. E. Dados os ,alores de a, b e c, determinar os ,alores das ra/!es da e%ua)*o do segundo grau %ue tenha estes fato res. J. 8a!er um programa %ue calcule e imprima a soma dos nFmeros pares desde >00 at E00, inclusi,e. "tili!e es trutura 4hile. L. 8a!er o mesmo e#erc/cio anterior utili!ando estrutura 8or. N. 8a!er um programa %ue calcule CX (fatorial de C+, sendo C um ,alor inteiro e positi,o. P. $eia um nFmero pre,iamente indeterminado de ,alores representando idades de indi,/duos. 6 Fltimo ,alor, %ue n*o entrar1 nos c1lculos, de,er1 conter o ,alor !ero. Calcule e escre,a a mdia das idades deste grupo de in di,/duos. 7. 8a!er um programa %ue calcule e escre,a o nFmero de gr*os de milho %ue se pode colocar num tabuleiro de #adre!, colocando > no primeiro %uadro e nos %uadros seguintes o dobro do %uadro anterior. Q. A con,ers*o de graus 8ahrenheit para cent/grados obtida por C H (8 JE+VN7S. 8a!er um programa %ue calcule e escre,a uma tabela em graus cent/grados em fun)*o de graus 8ahrenheit, %ue ,ariam de N0 a >N0, de > em >.

S. 5upondo %ue a popula)*o de um pa/s A se0a da ordem de S0.000.000 de habitantes com uma ta#a anual de crescimento de JM e %ue a popula)*o de um pa/s B se0a, apro#imadamente, de E00.000.000 de habitantes com uma ta#a anual de crescimento de >,NM, fa!er um programa %ue calcule e escre,a o nFmero de anos necess1rios para %ue a popula)*o do pa/s A ultrapasse ou se iguale . popula)*o do pa/s B, mantidas essas ta#as de cresci mento. >0. "m determinado material radioati,o perde metade de sua massa a cada N0 segundos. Dada a massa inicial, _________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quime i JQ

Estrutura de Programao

Departamento de Informtica

em gramas, fa!er um programa %ue determine o tempo necess1rio para %ue essa massa se torne menor %ue 0,N grama. :scre,a a massa inicial, a massa final e o tempo calculado em horas, minutos e segundos. >>. "ma companhia de teatro plane0a dar uma srie de espet1culos. A dire)*o calcula %ue a RdN0,00 o ingresso ser*o ,endidos >E0 ingressos, e as despesas montar*o em Rd E.000,00 (,alor fi#o+. A uma diminui)*o de Rd N,00 no pre)o dos ingressos, espera se %ue ha0a um aumento de EP ingressos ,endidos. 8a!er um programa %ue escre,a uma tabela de ,alores do lucro esperado em fun)*o do pre)o do ingres so, fa!endo se ,ariar este pre)o de Rd N0,00 a Rd >0,00, de Rd N,00 em Rd N,00. :scre,a ainda o lucro m1#imo esperado , o pre)o e o nFmero de ingressos correspondentes. >E. 8a!er um programa %ue calcule e escre,a o ,alor de 52 > 5H > [ E J [ J N [ L 7 [ N S [ ... [ N0 SS

>J. 8a!er um programa para calcular e escre,er o ,alor do nFmero PR, com precis*o de 0,000>, usando a srie abai#o. Para obter a precis*o dese0ada, adicionar apenas os termos cu0o ,alor absoluto se0a maior ou igual a 0,000>. L PR H L J [ N 7 L L [ S >> L L [ ...

>L. :laborar um programa %ue calcule e escre,a o ,alor da srie abai#o com erro menor %ue um dcimo de mili onsimo (0,000000>+ e indi%ue %uantos termos foram usados. P> 5 H PJ [ >X termos da srie2 [ EX NS [ JX N7 [ LX NN [ NX NJ [ .....

>N. 8a!er um programa %ue calcule o ,alor do co seno de um engulo #, fornecido como entrada, atra,s de E0

#E co seno(#+ H > EX [

#L

#P [

#Q ... QX

LX

PX

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quime i JS

Algoritmos e Programao

Departamento de Informtica

16 VARIVEIS COMPOSTAS HOMOGNEAS VETORES E MATRIZES


16.1 TIPOS DE VARIVEIS
a) Simples b) Compostas Homogneas vetores/matrizes (arrays/arranjos) elementos do mesmo tipo unidimensionais vetores multidimensionais matrizes Heterogneas registros elementos podem ser (e geralmente so) de tipos diferentes estrutura prpria para armazenar informaes em arquivos

16.2 DEFINIO DE VARIVEIS HOMOGNEAS:


Estruturas de dados utilizadas para representar uma coleo de variveis de um mesmo tipo. Maneira de armazenar na memria uma srie de informaes do mesmo tipo, referenciando-as por um nico nome. Cada informao isolada diferenciada e acessada por um ndice;

16.3 VETORES - DECLARAO DE TIPO E MANIPULAO


16.3.1 Declarao
Sintaxe:
tipo nome[<tamanho mximo>]

Exemplos:
float nota[60]; int vetor[100];

16.3.2 Acesso e manipulao:


Atribuio de um valor a um elemento (o quarto) do vetor:
nota[3] = 9.5;

Impresso/leitura de um elemento de um vetor:


printf(%d, exemplo[3]); scanf(%d, &vetor[5]); printf(%d, exemplo[0]); // impresso do quarto elemento do vetor // leitura do sexto elemento do vetor // impresso do primeiro elemento do vetor

Importante: O primeiro elemento de um vetor tem ndice zero (0). O segundo elemento o de ndice um (1). Se um vetor tem m elementos, o ndice do ltimo elemento ser m-1.

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 39

Algoritmos e Programao

Departamento de Informtica

Exemplo de aplicao: Se tivssemos que ler as notas de 3 alunos e calcular a mdia destas notas utilizando variveis simples, o faramos com o seguinte cdigo:
main() { float

nota0, nota1, nota2;

printf(entre com a 1a. nota); scanf(%f, &nota0); printf(entre com a 2a. nota); scanf(%f, &nota1); printf(entre com a 3a. nota); scanf(%f, &nota2); printf(media = %f, (nota0 + nota1 + nota2) / 3)); }

Imagine agora que tivssemos que calcular a mdia entre as notas de 300 alunos utilizando variveis simples. Nosso programa teria pelo menos 600 linha de cdigo, o que seria invivel:
main() { float

nota0, nota1, nota2;

printf(entre com a 1a. nota); scanf(%f, &nota0); printf(entre com a 2a. nota); scanf(%f, &nota1); . . . . . . . . . printf(entre com a 300a. nota); scanf(%f, &nota299); printf(media = %f, (nota0 + nota1 + ... + nota299) / 300)); }

A soluo utilizar um array/arranjo unidimensional (vetor) para guardar as notas e utilizar uma estrutura de repetio while ou for para gerar o ndice, do primeiro (zero) ao ltimo. A implementao utilizando estrutura while seria:
main() { int i; float notas[300], media=0.0; i = 0; while (i<300) { printf (entre com a nota %d, i+1); scanf (%f, &notas[i]); media = media + notas[i]; i++; } printf (Media= %f \n, media/300); i = 0; while (i<300) { printf (\n Nota do aluno %d= , i+1); printf (%f \n, notas[i]); i++; } }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 40

Algoritmos e Programao

Departamento de Informtica

O mesmo programa implementado com estrutura for seria (com pequenos melhoramentos):
main() { int i; float notas[300], media=0.0; for (i=0; i<300; i++) { printf (entre com a nota %d, i+1); scanf (%f, &notas[i]); media += notas[i]; } printf (Media= %f \n, media/300); for (i=0; i<300; i++) { printf (\n Nota do aluno %d= , i+1); printf (%f \n, notas[i]); } }

Ficou bem mais simples, no? s imaginar que cada lao de repetio while ou for ser executado 300 vezes (neste exemplo), cada um com um ndice maior (incrementalmente crescente), at que todos os elementos do vetor sejam considerados. Seja na leitura, no clculo da mdia ou na impresso. Proposta: Altere este programa, de forma que imprima o vetor em ordem reversa (do ltimo ao primeiro). Dica:
for (cont=tamanho-1; cont>=0; cont--)

Segundo exemplo: Leitura de um vetor de nmeros, de tamanho informado informado pelo usurio, determinando o seu menor elemento:
#include <stdio.h> #include <conio.h> #define TAM 100 void main () { int vetor[TAM]; int cont, tamanho, menor; printf("\nDigite o numero de elementos do vetor (max=100): "); scanf("%d", &tamanho); printf("\nDigite os elementos do vetor: \n"); for (cont=0; cont<tamanho; cont++) scanf("%d",&vetor[cont]); menor = vetor[0]; for (cont=1; cont<tamanho; cont++) if(vetor[cont]<menor) menor=vetor[cont]; printf("\nMenor elemento= %d", menor); getch(); }

Tarefa proposta: Altere o programa acima de forma que ele informe tambm a posio do menor elemento dentro do vetor original. _________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 41

Algoritmos e Programao

Departamento de Informtica

Terceiro exemplo: Leitura das trs notas de um grupo de alunos, com o clculo da mdia de cada um e determinao de seus critrios de aprovao. Impresso dos valores em forma de tabela (cdigo, notas, mdias e critrio).
#include <stdio.h> #include <conio.h> void main() { float nota1[100], nota2[100], nota3[100], media[100]; int cod[100]; int i, n; printf("\n Num. alunos (max=100): "); scanf("%d", &n); printf("\nDigite os codigos e notas dos alunos: \n"); for (i=0; i<n; i++) { printf("codigo: "); scanf("%d",&cod[i]); printf("nota 1: "); scanf("%f", &nota1[i]); printf("nota 2: "); scanf("%f", &nota2[i]); printf("nota 3: "); scanf("%f", &nota3[i]); media[i] = (nota1[i] + nota2[i] + nota3[i])/3.0; } printf("\nImpressao dos codigos, media e condicao: \n"); printf("Codigo Nota 1 Nota 2 Nota 3 Media Criterio\n");

for (i=0; i<n; i++) { printf("\n%d %f %f %f %f", cod[i], nota1[i], nota2[i], nota3[i], media[i]); if (media[i]>=5) printf("Aprovado"); else printf("Reprovado"); } getch(); }

16.4 INICIALIZANDO VETORES


Vimos anteriormente que as variveis simples poderiam ser inicializadas, isto , poderamos atribuir valor a elas quando da sua declarao. Considere, por exemplo, como a varivel inteira nmero poderia ser inicializada com o valor 0 (zero) quando da sua declarao:
int numero = 0;

Do mesmo modo podemos inicializar um vetor, como no exemplo:


int notas[5] = {0,0,0,0,0};

Isto equivaleria a:
int notas[5]; for (i=0; i<5; i++) notas[I] = 0;

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 42

Algoritmos e Programao

Departamento de Informtica

A linguagem C aceita a omisso do tamanho do vetor quando da sua inicializao. Neste caso, ele assume o tamanho do vetor como o nmero de valores relacionados. Ou seja, Indicando-se os inicializadores, o compilador fixar a dimenso do arranjo. Como no exemplo:
int notas[ ] = {0,0,1,3};

que tem o mesmo efeito de:


int notas[4] = {0,0,1,3}

Pode se inicializar apenas os primeiros elementos do vetor. Porm no se pode inicializar um elemento sem se inicializar todos os anteriores. Assim, so vlidas as inicializaes como as do primeiro exemplo:
int notas [5] = {1,2}

que equivale a:
int notas [5] = {1,2,0,0,0}

Por outro lado, so invlidas as inicializaes:


int notas [5] = { , ,0, , } int notas [ ] = { , ,0, , } // // ERRO ERRO

16.5 VARIVEIS HOMOGNEAS - VERIFICANDO LIMITES


A linguagem C no realiza verificao de limites em vetores e matrizes. Isto , nada impede que uma instruo C efetue o acesso alm do limite do vetor, o que gerar resultados imprevisveis. Por este motivo, sempre muito importante garantir os corretos valores dos ndices e, de preferncia, efetuar a verificao dos limites, como no exemplo:
#define TAM 100 int alunos[TAM], quantidade; // equivalente a: int alunos[100], quantidade; do { printf (Informe numero de alunos (max = 100): ); scanf(%d, &quantidade); if (quantidade >100) printf (Numero excessivo de alunos (>100).); } while(quantidade>TAM);

Isto , esta estrutura de leitura do tamanho do vetor no permitir a leitura de um valor alm do limite (100, no caso).

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 43

Algoritmos e Programao

Departamento de Informtica

16.6 VETORES ORDENAO


16.6.1 HISTRICO
O estudo e a aplicao de algoritmos de ordenao sempre estiveram ligados histria da informtica de forma muito marcante: 1880 Hermann Holerith Censo decenal americano a grande massa de dados a ordenar levou inveno da mquina de ordenar, que utilizava cartes perfurados, utilizados para leitura de dados at a dcada de 80; 1940 Primeiro programa significativo do primeiro computador digital rotina de ordenao; 1952 Primeira anlise de algoritmos: Anlise do tempo de vrios mtodos de ordenao.

16.6.2 APLICAO
Onde existirem dados, sendo mais clara a sua relevncia em: - Listas telefnicas; - Cadastros; - Dicionrios.

16.6.3 CLASSIFICAO DOS MTODOS DE ORDENAO


A) Quanto ao local da ordenao Memria Arquivo grandes arquivos / processamento em batch (Merge Sorts) B) Quanto complexidade Diretos Seleo direta Troca direta (+ lento) Insero direta

Avanados Heapsort Quick sort (+ rpido) Shell sort

16.6.4 MTODOS DIRETOS


16.6.4.1 SELEO DIRETA Para cada posio do vetor, coloca nele o menor elemento do sub-vetor que comea nesta posio e vai at a ltima. O primeiro for fixa posies incrementalmente crescentes para nelas colocar os menores elementos dos sub-vetores. O segundo for varre o sub-vetor procura do seus menor elemento. Selecionado este menor elemento, realiza a troca deste elemento com o da posio fixada no primeiro for.
for (i=0; i<=n-2; i++) { k = i; menor = vetor[i]; for (j=i+1; j<=n-1; j++) if(vetor[j]<menor) { k = j; menor = vetor[k]; { vetor[k] = vetor[i]; vetor[i] = menor; }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 44

Algoritmos e Programao 16.6.4.2

Departamento de Informtica

INSERO DIRETA Analisa cada elemento do vetor, da segunda posio (ndice 1) at a ltima (posio n-1), e o insere na sua posio ordenada, abaixo no vetor. O primeiro for fixa posies incrementalmente crescentes para analisar os elementos nestas posies. Salva-se este elemento na varivel aux. A estrutura while faz que enquanto existirem, abaixo no vetor, valores maiores que o elemento, estes ltimos sejam alados a uma posio acima. Quando for encontrada uma posio [j1] com valor menor que o elemento em questo (quando vetor[j-1]<aux), a execuo da estrutura while interrompida e na posio [j] (cujo valor j foi alado a uma posio superior na iterao anterior) inserido o elemento em anlise. A nfase colocar cada elemento na posio relativa correta.
for (i=1; i<=n-1; i++) { aux = vetor[i]; j = i; while ((j>0)&&(aux<vetor[j-1])) { vetor[j]= vetor[j-1]; j=j-1; } vetor[j] = aux; }

A expresso (j>0) dentro da condio de continuao do while necessria para o caso do elemento em anlise ser o menor do vetor, para que no seja testada uma posio menor que a [0]. Capice?

16.6.4.3

TROCA DIRETA Tambm coloca em cada posio do vetor, a partir do primeiro, o menor elemento do sub-vetor que comea nesta posio e vai at a ltima, como no mtodo da seleo direta, porm traz este menor elemento realizando trocas entre os elementos. O primeiro for fixa posies incrementalmente crescentes para nelas colocar os menores elementos dos sub-vetores. Com o segundo for comea comparando se o penltimo elemento maior que o ltimo. Se for, efetua a troca, utilizando a varivel auxiliar aux. E continua com as comparaes e trocas em posies incrementalmente descrescentes, at comparar o elemento da posio fixada no primeiro for e seu subseqente. Como este mtodo vai trazendo os menores elementos para cima, semelhana de bolhas que sobem superfcie, este mtodo tambm chamado de bubblesort.
for (i=0; i<=n-1; i++) for (j=n-2; j>=i; j--) if(vetor[j]>vetor[j+1]) { aux = vetor[j]; vetor[j] = vetor[j+1]; vetor[j+1] = aux; }

Tarefa: Implementar os algoritmos propostos em programas, testar com conjunto de elementos pr-determinados e analisar os seus modos de operao.

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 45

Algoritmos e Programao

Departamento de Informtica

Soluo da implementao proposta para ordenao pelo mtodo da troca direta (bolha):
#include <stdio.h> #include <conio.h> void main () { int vetor[100]; int i, j, n, aux, menor; printf("\nDigite o numero de elementos do vetor (max=100): "); scanf("%d", &n); printf("\nDigite os elementos do vetor: \n"); for (i=0; i<=n-1; i++) scanf("%d",&vetor[i]); for (i=0; i<=n-1; i++) for (j=n-2; j>=i; j--) if (vetor[j] > vetor[j+1]) { aux = vetor[j]; vetor[j] = vetor[j+1]; vetor[j+1] = aux; } printf("\nImpressao vetor ordenado: "); for (i=0; i<n; i++) printf("\n%d", vetor[i]); getch(); }

ATENO: Se voc ficou com alguma dvida em vetores, estude bem o assunto de novo, porque iremos ver frente como passar vetores a funes, quando estas dvidas no podem mais existir.

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 46

Algoritmos e Programao

Departamento de Informtica

16.7 ARRANJOS MULTIDIMENSIONAIS MATRIZES


16.7.1 MATRIZES DECLARAO/MANIPULAO
Sintaxe:
tipo nome[tamanho1][tamanho2]...[tamanhon], onde: tamanho1, tamanho2, ..., tamanhon

nmero mximo de elementos da dimenso.

Exemplos:
float distancia[100][80][120]; int tabela[10][10];

A manipulao de uma matriz bidimensional efetuada utilizando-se duas estruturas for aninhadas, uma para gerar os nmeros das linhas e a outra para gerar os ndices das colunas. Do mesmo modo, uma matriz com n dimenses precisar de n estruturas for para ser manipulada, ou seja, para que cada elemento possa ser referenciado individualmente. Em C interpreta-se que uma matriz um vetor de vetor(es), ou seja, um vetor em que cada posio temos um outro vetor (ou um vetor de vetores). Por exemplo, o array multidimensional int matria[4][40] pode ser interpretado como sendo a representao de 4 matrias, cada uma com 40 alunos. Uma rotina para leitura deste array seria:
int i,j, matria[4][40]; for (i=0; i<4; i++) { printf (\nEntre com as notas da matria %d, i+1); for (j=0; j<40; j++) { printf (\nEntre com a nota do aluno %d: , j+1); scanf (%d, &materia [i][j]); } }

16.7.2 INICIALIZANDO MATRIZES


Uma matriz bidimensional pode ter seus valores inicializados j em sua declarao, como no exemplo:
int nota[3][4] = {{0, 0, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}};

Esta instruo substitui com vantagem o seguinte grupo de instrues:


int nota[3][4]; for (i=0; i<linhas; i++) for (j=0; j<colunas; j++ ) nota[i][j] = 0;

Que por sua vez substitui as instrues: _________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 47

Algoritmos e Programao
int nota[3][4]; nota[0][0] nota[0][1] nota[0][2] nota[0][3] nota[1][0] nota[1][1] nota[1][2] nota[1][3] nota[2][0] nota[2][1] nota[2][2] nota[2][3] = = = = = = = = = = = = 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0;

Departamento de Informtica

16.7.3 MATRIZES PROGRAMAS-EXEMPLO DE APLICAO


A) Inicializar os elementos de uma matriz com valores crescentes e imprimir os seus elementos:
main() { int tabela[10][10], linha, coluna, i=0; for (linha=0; linha<10; linha++) for (coluna=0; coluna<10; coluna++) tabela[linha][coluna] = i++; for (linha=0; linha<10; ++linha) { for (coluna=0; coluna<10; ++coluna) printf("%4d", tabela[linha][coluna]); printf("\n"); } }

B) Ler uma matriz com dimenses fornecidas pelo teclado e depois imprimir os seus elementos:
main() { int tabela[10][10],linhas,colunas,i,j,lm,cm,menor; printf("digite o numero de linhas: "); scanf("%d",&linhas); printf("digite o numero de colunas: "); scanf("%d",&colunas); for(i=0;i<linhas;i++) for(j=0;j<colunas;j++) { printf("elemento [%d,%d]:",i+1,j+1); scanf("%d",&tabela[i][j]); } for(i=0;i<linhas;i++) { for(j=0;j<colunas;j++) printf("%0.2d ",tabela[i][j]); printf("\n"); } }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 48

Algoritmos e Programao

Departamento de Informtica

C) Buscar e imprimir o menor elemento de uma matriz:


menor=tabela[0][0]; lm=0; cm=0; for (i=0;i<linhas;i++) for(j=0;j<colunas;j++) if(tabela[i][j]<menor) { menor=tabela[i][j]; lm=i; cm=j; } printf("menor elemento e %d na posicao [%d][%d]",menor,lm+1,cm+1);

D) Ler duas matrizes e fornecer a matriz soma: Condio necessria: as matrizes precisam ter as mesmas dimenses.
main() { int m1[10][10], m2[10][10], msoma[10][10], linhas, colunas, i, j; printf("digite o numero de linhas das matrizes: "); scanf("%d",&linhas); printf("digite o numero de colunas das matrizes: "); scanf("%d",&colunas); printf("entrada da matriz1:); for(i=0;i<linhas;i++) for(j=0;j<colunas;j++) { printf("elemento [%d,%d]:",i+1,j+1); scanf("%d",&m1[i][j]); } printf("entrada da matriz2:); for(i=0;i<linhas;i++) for(j=0;j<colunas;j++) { printf("elemento [%d,%d]:",i+1,j+1); scanf("%d",&m2[i][j]); msoma[i][j] = m1[i][j] + m2[i][j] ; } printf("impressao da matriz soma:); for(i=0;i<linhas;i++) { for(j=0;j<colunas;j++) printf("%d ",matsoma[i][j]); printf("\n"); } }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 49

Algoritmos e Programao E) Ler duas matrizes e fornecer a matriz resultado (multiplicao):

Departamento de Informtica

Condio necessria: o nmero de colunas da primeira matriz precisa ser igual ao nmero de linhas da segunda matriz.
main() { int ma[10][10], mb[10][10], mc[10][10], lina, colb, calb, i, j, k; // lina = numero de linhas da matriz A // colb = numero de colunas da matriz B // calb = colunas da matriz A = linhas da matriz B printf("digite o numero de linhas da matriz A: "); scanf("%d",&lina); printf("colunas da matriz A (= linhas da matriz B): "); scanf("%d",&calb); printf("digite o numero de colunas da matriz B: "); scanf("%d",&colb); // Leitura da matriz A printf("entrada da matriz A:\n"); for(i=0;i<lina;i++) for(j=0;j<calb;j++) { printf("elemento [%d,%d]:",i+1,j+1); scanf("%d",&ma[i][j]); } // Leitura da matriz B printf("entrada da matriz B:\n"); for(i=0;i<calb;i++) for(j=0;j<colb;j++) { printf("elemento [%d,%d]:",i+1,j+1); scanf("%d",&mb[i][j]); } // Calculo da matriz resultado for(i=0;i<lina; i++) for(j=0;j<colb;j++) { mc[i][j] = 0; for(k=0;k<calb; k++) mc[i][j] = mc[i][j] + ma[i][k]*mb[k][j]; } // Saida da matriz resultado printf("impressao da matriz resultado:\n"); for(i=0;i<lina;i++) { for(j=0;j<colb;j++) printf("%d ",mc[i][j]); printf("\n"); } getch(); }

DICA: A mesma dica quanto aos vetores. Se voc ficou com alguma dvida quanto s matrizes, volte e tire esta dvida, para que esta dvida no atrapalhe o entendimento de passagem de matrizes como argumento de funes.

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 50

Algoritmos e Programao

Departamento de Informtica

17 STRINGS/CADEIAS DE CARACTERES
17.1 DEFINIAO DE STRING - IMPRESSO
Uma string de caracteres ou cadeia de caracteres uma seqncia de caracteres delimitada por aspas duplas. Exemplo de impresso de strings:
#include #include main() { printf printf } <stdio.h> <conio.h> ("Teste de impressao de string de caracteres, "); ("%s", "tambem chamada de cadeia de caracteres");

getch();

Lembrando que a forma geral da funo printf : printf (expresso de controle, lista de argumentos), percebe-se que o No primeiro printf a string de caracteres compe a expresso de controle, visto que no existe argumentos na lista, enquanto que o o segundo printf trata a string como argumento a ser impresso com cdigo de formatao %s. No momento da compilao, o computador coloca ao final da string o caracter null, o ASCII 0, inserindo a seqncia de escape \0. Este caracter null indica, para as funes de manipulao, o fim da string. Este caracter, frise-se, no tem nada a ver com o caracter zero, 0.

17.2 VARIVEL STRING DECLARAO E INICIALIZAO


As strings de caracteres podem ser armazenadas em C em variveis strings, que nada mais so do que vetores de caracteres, aos quais as funes de leitura e atribuio adicionam aps o ltimo caracter significativo o caracter null, \0. Por esta razo, strings de caracteres so tambm chamadas de strings ASCII zero. Exemplos de declaraes de variveis string:
char nome[20], palavro[128];

As strings tambm podem ser inicializadas quando de sua declarao, como no exemplo:
main() { char cadeia1[10]= exemplo1; char cadeia2[10]= {exemplo2}; char cadeia3[10]= {e,x,e,m,p,l,o,3,\0; printf ("cadeia1 = %s", cadeia1); printf ("cadeia2 = %s", cadeia2); printf ("cadeia3 = %s", cadeia3); getch(); }

Note que cadeia3 inicializada como vetor de caracteres, incluindo o caracter null ao final.

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 51

Algoritmos e Programao

Departamento de Informtica

17.3 I/O COM SCANF E PRINTF


Utiliza o cdigo de formatao %s para leitura e escrita. O scanf l a string digitada at que um caracter branco seja encontrado. Como no exemplo:

#include <stdio.h> #include <conio.h> main() { char frase[128]; printf ("Digite uma frase e encerre com <Enter>: "); scanf ("%s", &frase); printf ("%s", frase); getch(); }

Atividade proposta: Teste este exemplo e verifique a sua limitao para leitura de frases (palavras separadas por espaos). O programa abaixo tambm vlido. Ao invs de passar para a funo scanf o endereo da varivel, &frase, passa o endereo do seu primeiro elemento, &frase[0]. Veremos a razo disto quando
estudarmos passagem de parmetros por referncia para funes.

#include <stdio.h> #include <conio.h> main() { char frase[128]; printf ("Digite uma frase e encerre com <Enter>: "); scanf ("%s", &frase[0]); printf ("frase = %s", frase); getch(); }

Outra limitao do uso de scanf para leitura de strings de caracteres exemplificado abaixo. Este programa, juno dos dois ltimos, no funciona adequadamente o segundo scanf no l nenhum valor digitado pelo teclado. Isto acontece porque o <Enter> digitado para a leitura da primeira frase permanece no buffer de leitura e ser interpretado como o valor a ser lido pelo segundo scanf. A diferena entre as duas implementaes da funo scanf (&frase e &frase[0])) no influi em nada neste resultado.
main() { char frase[128]; printf ("Digite uma frase e encerre com <Enter>: "); scanf ("%s", &frase); printf ("frase = %s", frase); getch(); printf ("Digite uma frase e encerre com <Enter>: "); scanf ("%s", &frase[0]); printf ("frase = %s", frase); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 52

Algoritmos e Programao

Departamento de Informtica

17.4 I/O COM GETS E PUTS


A linguagem C prov as funes gets e puts para leitura mais facilitada de strings. A funo gets (get string) l os caracteres digitados at encontrar um caracter \n. Ento atribui estes caracteres varivel string, substituindo o \n por \0. A funo puts (put string) imprime no dispositivo de sada padro (no caso, o vdeo) o valor do seu argumento. S aceita um argumento.

Veja as aplicaes no exemplo:


#include <stdio.h> #include <conio.h> main() { char frase[128]; printf ("Digite uma frase e encerre com <Enter>: "); gets (frase); // Esta instrucao funciona puts (frase); printf ("Digite uma frase e encerre com <Enter>: "); gets (&frase[0]); // Esta instrucao tambm funciona puts("Frase digitada: "); puts (frase); // // } gets (&frase); Esta instrucao NAO funciona puts("Frase digitada: ", frase); Tambm NAO funciona // A funcao puts s aceita um argumento getch();

O caracter \n (ASCII 10, LF, Line Feed, Avano de Linha), o caracter introduzido quando se digita o <Enter>. A digitao do <Enter> tambm introduz outro caracter, o ASCII 13, CR, Carriage Return, ou Retorno de Carro de Impresso.

17.5 MANIPULAO DE STRINGS COMO VETOR DE CARACTERES


A leitura e a impresso de strings de caracteres pode ser feita caracter a caracter, utilizando as funes getchar() e putchar(). O primeiro exemplo abaixo l os caracteres digitados no teclado e ao ser digitado <Enter>, leitura do caracter '\n', interrompe a leitura e coloca o caracter nulo, '\0', no final da string. Este caracter sinaliza o final da string para outras as funes de manipulao, como vimos.
#include <conio.h> #include <stdio.h> #define FIM '\0' main() { char vetor[128]; int tamanho=0; printf("\nDigite uma frase e pressione <Enter>: \n"); while ((vetor[tamanho] = getchar()) != '\n') tamanho++; vetor[tamanho]=FIM; printf("A string %s contem %d caracteres. \n",vetor, tamanho); puts("Impressao da string utilizando puts: "); puts(vetor); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 53

Algoritmos e Programao

Departamento de Informtica

Tarefa: Incremente neste ltimo programa-exemplo a impresso da string caracter a caracter, utilizando a funo putchar().

Exemplo 2: Programa que conta o nmero de vezes que um dado caractere aparece em um texto:
#include <stdio.h> #include <conio.h> #define TAM 256 main( ) { int i=0, c, ocorrencias=0; char frase[TAM], caracter; printf("Digite uma frase: "); gets(frase); printf("Digite o caracter a ser procurado nesta frase: "); c = getche(); while (frase[i] != '\0') { if (frase[i] == c) ocorrencias++; i++; } printf ( "\nO caracter %c ", c); printf ( "aparece %d vezes na frase: %s", ocorrencias, frase); getch(); }

Exemplo 3: Programa que demonstra que uma string pode ser tratada como um vetor de caracteres no printf, imprimindo elementos isolados(caracteres) ou a string toda:
#include <stdio.h> #include <conio.h> main() { char nome[40]; printf ("Digite seu nome: "); gets(nome); printf ("%c\n", nome[3]); printf ("%c\n", nome[0]); printf ("%s\n", nome); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 54

Algoritmos e Programao

Departamento de Informtica

17.6 FUNES DE MANIPULAO DE STRINGS


17.6.1 strlen(str) Definio: Retorna o tamanho do string, ou seja, o nmero de caracteres que a compe. No inclui na contagem o caracter de controle final null, \0. Requer a incluso da biblioteca <string.h>. Exemplo 1:
#include <stdio.h> #include <conio.h> #include <string.h> main( ) { char nome[40]; printf("Digite seu nome: " ); gets (nome); printf(Tamanho = %d, strlen(nome)); }

Exemplo 2:
main() { char nome[40]="Joao", sobrenome[20]=" da Silva"; int tamanho; // Demonstra o uso da funcao strlen printf ("\nTamanho do nome (%s) = %d ", nome, strlen(nome)); tamanho = strlen(&sobrenome[0]); printf ("\nTamanho do sobrenome (%s)= %d", sobrenome, tamanho); getch(); }

17.6.2 strcat (str1, str2) Definio: Concatena a string str2 ao final da string str1. O tamanho de str1 deve ser suficiente para comportar a string final, concatenao das duas. Exemplo1:
main( ) { char nome[40] = "James ", sobrenome[30] = "Bond"; strcat(nome, sobrenome); puts (sobrenome); puts (nome); getch(); }

Saida:
Bond James Bond

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 55

Algoritmos e Programao

Departamento de Informtica

Exemplo2:
#include <stdio.h> #include <conio.h> #include <string.h> main() { char nome[40]="Joao", sobrenome[20]=" da Silva"; strcat(nome, sobrenome); printf ("\nSeu nome completo = %s", nome); // ou puts ("\nSeu nome completo = "); puts (nome); getch(); }

17.6.3 strcmp (str1, str2) Compara dois strings retornando um valor inteiro que indica o status da comparao, que feita por ordem alfabtica:

Negativo 0 (zero) positivo

se str1 < str2 se str1 = str2 se str1 > str2

em um if, considerado como falso (armadilha do C)

A armadilha no uso do strcmp que a comparao entre duas cadeias iguais retorna valor zero, o que para uma instruo if considerado valor falso. Cuidado, portanto, na montagem do if.

Exemplo 1:
main( ) { char nome1[40] = "Jose", nome2[30] = "Pedro"; if (strcmp(nome,sobrenome)) puts ("os nomes so diferentes"); else puts ("os nomes so identicos"); } }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 56

Algoritmos e Programao Exemplo 2:


main() { char senhai[40]="abcdefg", senhaf[40]; int result;

Departamento de Informtica

printf ("Digite a senha de alta complexidade: "); gets(senhaf); result = strcmp(senhai, senhaf); if (result) // se result for diferente de zero, verdadeiro puts("Senha invalida"); // result diferente de zero else puts("Senha valida"); // result igual a zero, // interpretado como falso getch(); }

17.6.4

strcpy (str1, str2)

Copia o valor de str2, que pode ser uma varivel string ou uma constante string, para str1, que DEVE ser uma varivel string. A implementao ISO da linguagem C no permite que se faa atribuio para uma varivel string do contedo de outra varivel string ou de uma constante string. Exemplo:
main() { char sobrenome[20] = "da Silva", nome[20]="Paulo", nome2[20]="Jose"; printf ("\nNome original= %s", nome); printf ("\nSobrenome original= %s\n\n", sobrenome); // nome = nome2; Instruo invalida // sobrenome = "de Souza"; Tambm invalido // Um vetor nao pode receber atribuio do desta maneira strcpy(nome,nome2); // Tambem valido printf ("\nnome apos o uso de strcpy= %s", nome); strcpy(sobrenome,"de Souza"); // Instrucao valida printf ("\nSobrenome apos o uso de strcpy= %s", sobrenome); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 57

Algoritmos e Programao

Departamento de Informtica

18 MODULARIZAO - FUNES E PROCEDIMENTOS


medida que aumenta a complexidade de um programa, torna-se cada vez mais imperativo quebrar o programa em pedaos menores, isolando em cada um destes pedaos as instrues logicamente relacionadas. A esta tarefa se d o nome de modularizao. Todo programa em C tem pelo menos uma funo, denominada main(), que sempre a primeira a ser executada. Ao encontrar a chamada a uma funo, o controle do programa desviado para esta funo. Aps executadas as instrues desta, o controle volta ao ponto da funo que fez a chamada. Vantagens: Simplificao na programao: Os mdulos so menores, e mais simples; Qualidade: Projeto, implementao e teste por etapas controladas; Reusabilidade do cdigo pode-se usar as mesmas funes em outros programas. Se uma funo est bem implementada e testada, no h por que desenvolver de novo; Legibilidade do programa cada funo tem uma tarefa especfica e facilmente reconhecvel; Particionamento do trabalho em equipes diviso das tarefas por grupos de pessoas. Encapsulamento da funcionalidade - determina-se O QUE a funo deve fazer e QUAL a interface dela com o restante do programa. COMO feita a implementao pode ser oculto. Caso se deseje alterar esta implementao, mantendo-se a funcionalidade e a interface, o programa no ser afetado, o que influi em todos as vantagens anteriores.

18.1 PROCEDIMENTOS
As funes podem ou no retornar valores para o ponto de onde so chamadas. Na linguagem C, quando no retornam valores recebem o nome especial de procedimentos1. Como no retornam valores, devem ter a palavra void colocada antes do seu nome. Exemplo:
#include <stdio.h> #include <conio.h> void desenha( ) { int i; for (i =0; i<=10; i++) printf (-); } main( ) { desenha( ); printf (" tracejado efetuado pela funcao desenha() "); desenha( ); getch(); }

Cada vez que executada uma chamada funo desenha() so impressos 10 traos na tela. Observe que a funo no retornou nenhum valor e que tambm, neste caso, no foi passado funo nenhum valor.

Em Algoritmos e em Pascal, procedimentos so mdulos que retornam nenhum ou vrios valores. Funes retornam somente

um valor.

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 58

Algoritmos e Programao

Departamento de Informtica

18.1.1 PROCEDIMENTOS SEM PARMETROS / QUE NO RECEBEM VALORES Quando o procedimento no precisa de nenhum valor para executar a sua funcionalidade, a chamada a este procedimento programada colocando-se na instruo o nome da funo/procedimento seguida de (). Veja os exemplos:

Exemplo 1: Programa com procedimento que imprime valor na tela. No h envio de valores do main() para o procedimento e nem retorno de valores para o main().
void mostra_numero() { printf("33\n"); } main() { mostra_numero(); getch(); }

Exemplo 2: O mesmo programa do exemplo anterior, com a exceo de que a funo/procedimento colocada aps o main().Neste, para que no ocorra erro no momento da compilao, colocado o cabealho da funo no incio do main(). Isto permite que o compilador, no momento da traduo da instruo de chamada funo verifique se esta chamada est correta quanto ao nome, nmero e tipo de argumentos/parmetros, se existirem.
main() { void mostra_numero(); printf("33\n"); mostra_numero(); getch(); } void mostra_numero() { printf("33\n"); }

Exemplo 3: Impresso de mensagens no main() antes e depois da chamada funo e na funo, antes e depois da impresso do valor numrico.
void mostra_numero() { printf("Imprimindo no inicio da funcao \n"); printf("66\n"); printf("imprimindo no final da funcao\n"); } main() { printf("\nImprimindo do main(),antes de chamar a funcao \n"); mostra_numero(); printf("imprimindo do main(), apos a chamada aa funcao\n"); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 59

Algoritmos e Programao

Departamento de Informtica

Exemplo 4: Programa que chama 5 vezes a funo/procedimento que imprime o alfabeto. Note que a varivel i, apesar de ter sido declarada como do tipo inteiro, recebe caracteres, sem nenhum problema. Poderia, sem nenhuma alterao para o comportamento do programa, ter sido declarada do tipo char.
void mostra_alfabeto() { int i; for (i='A';i<='Z';++i) putchar(i); putchar('\n'); } main() { int i; for(i=1;i<=5;i++) mostra_alfabeto(); getch(); }

18.1.2 PASSAGEM DE PARMETROS PARA PROCEDIMENTOS - POR VALOR

Quando o procedimento ou funo precisa de um ou vrios valores para executar a sua funcionalidade, no seu cabealho (primeira linha) so colocadas as variveis que recebero cpia dos valores enviados nas chamadas, precedidas de suas declaraes de tipo. Estas variveis so chamadas de parmetros da funo/procedimento e devem combinar em nmero e tipo com os valores ou variveis colocados nas chamadas, que so chamados de argumentos do procedimento ou funo. Algumas bibliografias usam os termos parmetro formal e parmetro real para os parmetros e argumentos, respectivamente. Veja os exemplos:

Exemplo 1: Programa com procedimento que recebe e imprime um valor inteiro. O recebimento efetuado atravs da varivel int digito, que receber cpia do valor do argumento do tipo int, constante ou varivel, na chamada ao procedimento. A primeira chamada funo usa como argumento a constante inteira 5. A segunda chamada usa como argumento a varivel inteira i. A declarao do parmetro digito no cabealho da funo tem efeito de declarao de varivel local.
void mostra_digito(int digito) { printf("Valor passado para a funcao= %d\n",digito); } main() { int i=10; mostra_digito(5); mostra_digito(i); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 60

Algoritmos e Programao

Departamento de Informtica

Exemplo 2: Programa com as mesmas funes do exemplo anterior, porm com a funo colocada aps o main(). Para que a compilao deste programa seja possvel, necessrio colocar o cabealho da funo no incio do main(), com a colocao dos tipos dos parmetros da funo (no preciso colocar o parmetro). Isto possibilita que o compilador possa conferir se a chamada funo est correta, incluindo nome da funo, nmero e tipo dos parmetros.
main() { void mostra_digito(int); mostra_digito(5); getch(); } void mostra_digito(int digito) { printf("%d\n",digito); }

Exemplo 3: Este programa executa 10 chamadas funo mostra_digito, cada chamada passando um valor diferente.
void mostra_digito(int digito) { printf("%d\n",digito); } main() { int i; for (i=1;i<=10;i++) mostra_digito(i); getch(); }

Exemplo 4: Utilizao de parmetros tipo float (reais). Observe que um dos argumentos inteiro. Isto no causa erro nem de compilao nem de execuo. Caso ocorresse o contrrio parmetro do tipo int e argumento do tipo float somente a parte inteira do argumento seria passado para a funo. Experimente.
void mostra_soma(float a, float b) { printf("%6.2f+%6.2f=%6.2f\n",a,b,a+b); } main() { mostra_soma(45,53.7); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 61

Algoritmos e Programao

Departamento de Informtica

A passagem de parmetros por valor funciona do mesmo modo para funes, genericamente, da mesma forma como funciona para os procedimentos, de forma especfica. O que j no acontece com passagem por referncia, haja vista que este a maneira para retorno de valores da funo para o ponto de chamada, o que no se aplica aos procedimentos. Veremos passagem de parmetros por referncia um pouco mais frente.

18.1.3 VARIVEIS LOCAIS E GLOBAIS As variveis declaradas dentro de uma funo ou procedimento so denominadas locais e somente so visveis, ou seja, podem ser usadas, dentro do prprio bloco, ou seja. Elas so criadas na entrada do bloco e destrudas na sada (automticas). As variveis globais so as declaradas fora das funes, geralmente antes do main()e podem ser usadas em qualquer parte do programa, por qualquer funo e tambm ser alterada. O uso de variveis globais fortemente desaconselhado, por permitir a comunicao entre os mdulos adicional interface de entrada e sada das funes, determinada pelos parmetros e comando de retorno. Um uso desapercebido do mesmo nome de varivel dentro de um mdulo pode ter conseqncias imprevisveis e geralmente desastrosas. Exemplo de programa utilizando somente variveis locais. As variveis i do main() e da funo mostra_digito so independentes e no tem relao nenhuma uma com a outra. Inclusive o incremento de i dentro da funo no ter repercusso nenhuma no contedo da varivel i do main:

void mostra_digito(int i) { i++; printf("%d\n",i); } main() { int i; for (i=0; i<10; i++) mostra_digito(i); getch(); }

Exemplo de programa utilizando varivel global. O incremento da varivel i dentro da funo faz com que sejam feitas somente 5 chamadas esta funo e no 10, como se esperaria:
int i; void mostra_digito(int digito) { i++; printf("i= %d digito= %d\n",i, digito); } main() { for (i=0; i<10; i++) mostra_digito(i); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 62

Algoritmos e Programao

Departamento de Informtica

18.2 FUNES
Mdulos que retornam um ou mais valores ao retornar ao ponto de onde foram chamados. 18.2.1 O COMANDO return A execuo de um comando return em uma funo faz com que uma o controle da execuo retorne funo que a chamou. Ele pode opcionalmente retornar um valor ao ponto de chamada. Exemplos:
return a return a+b return (a+b)

18.2.2 A PASSAGEM DE VALORES PARA A FUNO E O RETORNO DE VALORES A passagem de parmetros por valor para uma funo tem o mesmo comportamento descrito anteriormente para os procedimentos. O retorno de valor pode ser feito utilizando passagem de parmetros por referncia, a ser visto mais frente, ou atravs do comando return. O valor retornar no ponto da chamada funo. Veja os exemplos:

Exemplo 1: Programa com funo que recebe dois valores inteiros e retorna a sua soma. Na primeira chamada so utilizados como argumentos duas constantes inteiras, cujas cpias so passadas (por valor) aos parmetros a e b, deste modo declaradas variveis locais da funo. A execuo do comando return fora o retorno do controle ao local de chamada, levando consigo o resultado do valor colocado direita do return, no caso a avaliao da expresso (a+b). Este valor substitui a chamada funo e atribudo varivel esquerda.
int soma_valores(int a,int b) { return(a+b); } main() { int res1, res2, c=7, d=8; res1=soma_valores(10,53); printf("Resultado=%d\n",res1); res2=soma_valores(c,d); printf("Resultado=%d\n",res2); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 63

Algoritmos e Programao

Departamento de Informtica

Exemplo 2: O mesmo programa anterior, com duas alteraes principais: a) sem os parnteses aps o return e b) utilizando a chamada diretamente como parte do argumento de outra funo, no caso, a printf, o que dispensa a declarao das variveis res1 e res2, com economia de cdigo:
float soma_valores(float a,float b) { return a+b; } main() { float c=7.3, d=8.7; printf("Resultado=%d\n", soma_valores(10,53.7)); printf("Resultado=%d\n", soma_valores(c,d)); getch(); }

Exemplo 3: Programa com funo que recebe dois valores e retorna a sua mdia:
float media(float a,float b) { return (a+b)/2; } main() { float media(float,float); printf("Media=%f\n",media(7.88,8.37)); getch(); }

Exemplo 4: Programa com funo que retorna o fatorial de um numero inteiro passado como argumento:
int { int fatorial (int n)

i, resultado = 1; for ( i = 1; i <= n; i ++) resultado *= i; return resultado;

} main( ) { printf ( o fatorial de 4 = %d, fatorial(4) ); printf ( o fatorial de 3 = %d, fatorial(3) ); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 64

Algoritmos e Programao

Departamento de Informtica

Exemplo 5: Programa que utiliza uma funo para ler um caracter e o transformar o caracter em minscula, caso ele no o seja:

char minsculo( ) { char ch; ch = getche( ); if ((ch >= A) && (ch <= Z)) return (ch + a - A); else return (ch); } main( ) { char letra; printf ( digite uma letra em minsculo); letra = minsculo ( ); if (letra == a) // if (minusculo( ) == a) printf (ok); }

Tarefas propostas: 1) Programa com funo que receba a altura e a base de um retngulo e devolva a sua rea; 2) Modifique a funo deste ltimo programa para que ela receba uma letra e a transforme em minscula, se ainda no o for. 3) Desenvolva uma funo que retorne o absoluto de um nmero passado como argumento. 4) Funo que receba base e expoente, inteiros, e calcule a sua potenciao, ou seja, a base elevada ao expoente. Resoluo ao final do captulo. Mas voc no vai dar uma de mole e preguioso e ver a resposta antes de quebrar a cabea um pouco, vai?

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 65

Algoritmos e Programao

Departamento de Informtica

18.3 USANDO VRIAS FUNES


Um aplicativo, em sua verso final, pode ter vrios mdulos, cada um desempenhando uma funcionalidade do programa. O correto projeto possibilitar que se desfrute todas as vantagens do uso da modularizao. Veja o exemplo de um programa que utiliza trs funes: Problema - calcular a seguinte seqncia: Soluo:
int fat(int n) { int i, resultado= 1; for(i=1; i<= n; i++) resultado *= i; return resultado; } float potencia(float base, int expoente) { int i; float resultado = 1; if (expoente == 0) return 1; for(i=1; i<=expoente; i++) resultado *= base; return resultado; } float serie (float x, int n) { int i; float resultado= 0; for (i= 1; i<= n; i++) resultado += potncia(x,i)/fat(i); return resultado; } void main( ) { float x; int termos; printf(entre com o numero de termos: ); scanf(%d, &termos); printf(entre com o valor de X: ); scanf(%f, &x); printf(O valor de srie = %f , serie(x, termos)); }

2 3 n S(x, n) = x/1! + x /2! + x /3! + ... + x / n!

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 66

Algoritmos e Programao

Departamento de Informtica

18.4 RECURSIVIDADE
Recursividade a chamada de uma funo por si mesma. muito utilizada em estruturas de dados avanadas como rvores e mtodos de ordenao avanados. Seu uso pode gerar cdigos extremamente eficientes e concisos para as necessidades, muito embora possa trazer como efeito colateral a complexidade. A maior dificuldade no uso da recursividade estabelecer um critrio exato e controlado para a parada das chamadas. No exemplo abaixo, a funo repete() chamada uma vez pelo main(). Na execuo da funo, esta escreve a mensagem Subindo...n, onde n o nmero da chamada funo. Ao este nmero chegar a trs, a funo para de chamar a si mesma e passa a executar o restante da funo, escrevendo na tela a mensagem Descendo...n, onde n o nmero da chamada funo que est sendo executada. Tente, antes de digitar o programa, descobrir como funciona o programa e qual ser a sua sada. Dica: Sacuda a preguia, use o caderno e lpis e faa as cpias necessrias do texto da funo para visualizar melhor a execuo do programa.

#include <stdlib.h> #include <stdio.h> #include <conio.h> int repete (int n) { n++; printf("Subindo...%d\n",n); if (n<3) repete (n); printf("Descendo ... %d\n",n); } main() { int m; m=0; repete(m); getch(); }

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 67

Algoritmos e Programao

Departamento de Informtica

Resoluo das tarefas propostas sobre funes: 1) Funo que recebe a altura e a base de um retngulo e devolve a rea;
float rea_retngulo (float largura, float altura) { return largura*altura; }

2) Funo que recebe uma letra e a transforme em minscula, se ainda no o for.


char minsculo (char ch) { if ((ch >= A) && (ch <= Z)) return (ch + a - A); else return (ch); } main( ) { printf ( %c, minsculo (A) ); }

3) Desenvolva uma funo que retorne o absoluto de um nmero passado como argumento.
int abs (int x) { return ( ( x < 0 ) ? -x : x ); } main( ) { int num, b; b = abs (-3); printf (Valor absoluto de -3 = %d, b); printf (entre com um nmero: ); scanf (%d, &num ); printf (Valor absoluto de num = %d, abs(num)); }

4) Funo que receba base e expoente, inteiros, e calcule a sua potenciao, ou seja, a base elevada ao expoente.
float potncia (float base, int expoente) { int i; float resultado = 1; if (expoente == 0) return 1; for (i = 1; i <= expoente; i++) resultado *= base return resultado; }

Falaremos sobre passagem de argumentos por referncia aps abordarmos o prximo tpico, ponteiros.

_________________________________________________________________________________ Professores: Ivo Mrio Mathias e Jeferson Antonio Quimelli 68

Algoritmos e Programao

Departamento de Informtica

19 PONTEIROS
Variveis ponteiro so as que podem armazenar endereos de memria.

19.1 OPERADOR DE ENDEREO - &


Como registramos oportunamente, variveis so localizaes da memria que possuem: a !m nome pelo qual so re"erenciadas# $ !m conte%do. c !m endereo determinado na memria. &ara se o$ter este endereo onde se localiza uma varivel, utiliza'se o operador de endereo (. !m endereo ) o ponto inicial da memria do espao ocupado pelo valor. * utilizamos o operador de endereo ( em leituras com scan", como mostrado a$ai+o. ,este caso, o endereo da varivel numero ) passado como argumento para a "uno, para que esta coloque neste endereo o valor digitado.
printf ("Numero: "); scanf ("%d", &numero); printf ("Numero = %d", numero);

-+emplo .:
#include <stdio.h> #include <conio.h> main() int contador = !; printf (""alor = %d ", contador); printf ("#ndereco = %$", &contador); %etch();

&

!tiliza'se o especi"icador de "ormato /0 1 "ormato 2e+adecimal ' para imprimir um endereo de memria. !m endereo de memria ) e+presso em dois termos: um segmento e um deslocamento dentro do segmento, que ) e+i$ido pelo especi"icador de "ormato /0. -+emplo 3:
#include <stdio.h> #include <conio.h> main() int contador = !; float numero = '.'; printf (""alor inteiro = %d #ndereco inteiro = %()$ *n", contador, &contador); printf (""alor float = %f #ndereco float = %()$", numero, &numero); %etch();

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 64

Algoritmos e Programao

Departamento de Informtica

-ste %ltimo e+emplo demonstra que endereos do tipo int tem o mesmo "ormato de endereos de valor 5variveis do tipo float, apesar destes dois tipos de dados ocuparem taman2os di"erentes de espao de armazenamento.

19.2 DECLARAES DE VARIVEIS PONTEIRO


Como eu posso guardar6armazenar o valor de um endereo para uso posterior7 !tilizando um tipo especial de varivel, os p !"#$% &. &ara declarar uma varivel ponteiro para um tipo especi"icado, coloque: a 8 tipo da varivel cu9o endereo poder ser armazenado na varivel ponteiro# $ 8 nome da varivel ponteiro a ser criada, precedido de asterisco5: . &or e+emplo, a instruo a$ai+o cria a varivel ponteiro ptr, capaz de armazenar o endereo de uma varivel simples do tipo int:
int +ptr; ;eclarao de ptr

-sta declarao deve ser lida da direita para a esquerda:


ptr ) uma varivel p !"#$% , capaz de armazenar o endereo de um int.

-+emplo completo:
#include <stdio.h> #include <conio.h> main() int contador = !; int +ptr; ptr = &contador; printf (""alor inteiro = %d ", contador); printf ("#ndereco inteiro = %$ *n", &contador); printf (""alor de ptr = %$", ptr); %etch();

&

19.3 OPERADOR DE INDIRE'O (


&ara acessar ou alterar o conte%do da varivel cu9o endereo est armazenado em uma varivel ponteiro, utiliza'se o operador de indireo, que ) implementado pela colocao de um asterisco antes da varivel ponteiro. &or e+emplo:
,ontador = !; ptr = &contador;

6: 6:

o endereo de contador ) atri$u<do a ptr ptr aponta para contador

:6 :6 :6 :6 :6

numero = +ptr;

6: numero rece$e ., o valor de contador 66 acesso indireto a contador 6: 6: imprime o conte%do de contador
contador rece$e 0

-rintf (.%d/, +ptr); +ptr = 0;

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 6=

Algoritmos e Programao

Departamento de Informtica

>i+e $em: ?eia a e+presso +ptr como valor da varivel cu9o endereo est em ptr. -sta "orma de acesso indireto a uma varivel, atrav)s da varivel que armazena o seu endereo deve ser per"eitamente assimilada, porque ) uma das $ases para criao din@mica de variveis.
+ptr = 0 tem o mesmo e"eito que contador = 0, porque ptr aponta para contador.

-+emplo completo .:
#include <stdio.h> #include <conio.h> main() int a, 1; int +pa, +p1; a = 6; 1 = 7; pa = &a; p1 = &1; +pa = !(; +p1 = '; 2+ ou: pa aponta para a 4ari54el a 2+ ou: pa aponta para a 4ari54el a 2+ ou: 2+ ou: a rece1e !( 1 rece1e ' +2 +2 ou: pa rece1e o endere8o de a ou: p1 rece1e o endere8o de 1 22 pa e p1 s3o 4ari54eis do tipo ponteiro para int

printf ("no4o 4alor de a = %d *n", +pa); printf ("no4o 4alor de 1 = %d *n", +p1); %etch();

-+emplo completo 3:
#include <stdio.h> #include <conio.h> main() int contador = !; int +ptr; ptr = &contador; printf (""alor contador= %d #ndereco contador = %()$ *n", contador, &contador); printf (""alor de ptr = %()$ *n", ptr); 22 = a contador printf (",onteudo da 4aria4el int cu9o endere8o esta em ptr = %d *n", +ptr); printf ("#ndereco de ptr = %()$ *n", &ptr); printf (""alor de ptr = %()$ ", ptr); 22 endere8o de contador, :ue est5 em ptr printf (""alor de +ptr = %d "alor de &ptr = %()$", +ptr, &ptr); %etch();

A ,o e+emplo: optr endereo de outra varivel, contador, armazenado na varivel ponteiro ptr# o+ptr conte%do da varivel 5contador que tem o seu endereo em ptr, para onde Bptr apontaC# o&ptr endereo da varivel ponteiro 5raramente utilizado . _________________________________________________________________________________ Professor Jeferson Antonio Quimelli 7D

Algoritmos e Programao

Departamento de Informtica

19.4 PASSA)E* DE AR)+*ENTOS POR RE,ER-NCIA ATRAV.S DE PONTEIROS


Euando um programa passa argumentos por valor em uma c2amada, a "uno que rece$e este valor pode utiliza' lo, mas o conte%do da varivel colocado na c2amada no ) alterado, qualquer que se9a o tratamento dado ao valor passado F "uno. &or e+emplo, no programa a$ai+o, o conte%do da varivel contador ) passado F "uno muda;4alor, o valor da varivel a, que rece$e cpia deste valor ) alterado, por)m o conte%do da varivel contador no ) alterado:
4oid muda;4alor(int a) a<=); printf(""alor dentro da funcao = %d *n", a);

&

main() int contador = 7; printf (""alor inicial = %d *n", contador); muda;4alor(contador); printf (""alor final = %d *n", contador); & %etch();

G sa<da deste programa ser:


"alor inicial = 7 "alor dentro da funcao == "alor final =7

He quisermos que o conte%do da varivel contador se9a alterado pela "uno muda;4alor, devemos passar o endereo da varivel. ,o ca$eal2o da "uno, a varivel que rece$er este valor deve ser uma varivel ponteiro. ;este modo, o programa anterior "ica alterado para:
4oid muda;4alor(int +a) 2+ rece1e endereco +2

&

+a<=); 2+ soma ) a +a, mesmo endereco de mem>ria :ue contador +2 printf(""alor dentro da funcao = %d *n", +a);

main() int contador = 7; printf (""alor inicial = %d *n", contador); muda;4alor(&contador); 2+ passando endereco printf (""alor final = %d *n", contador); & %etch(); +2

G sa<da deste novo programa ser agora:


"alor inicial = 7 "alor dentro da funcao == "alor final ==

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 7.

Algoritmos e Programao

Departamento de Informtica

&erce$a $em as di"erenas no ca$eal2o da "uno, na manipulao da varivel dentro da "uno e na c2amada da "uno: no ca$eal2o da "uno, a varivel a, que rece$e o endereo da varivel argumento ) do tipo ponteiro o conte%do da varivel contador ) alterado indiretamente, porque o seu endereo est armazenada na varivel a a c2amada F "uno muda;4alor passa o endereo da varivel
contador

4oid muda;4alor(int +a);

+a<=);

muda;4alor(&contador);

He imprimirmos tam$)m o endereo das variveis utilizadas pelo programa "ica mais "cil entender o que acontece:
4oid muda;4alor(int +a) +a<=); printf(""alor dentro da funcao = %d *n", +a); printf("#ndereco %uardado em a = %$ *n", a); & main() int contador = 7; printf (""alor inicial = %d *n", contador); printf ("#ndereco de contador = %$ *n", &contador); muda;4alor(&contador); printf (""alor final = %d *n", contador); & %etch();

G sa<da ser agora:


"alor inicial = 7 #ndereco de contador = 66??@) "alor dentro da funcao == #ndereco %uardado em a = 66??@) "alor final == 2+ este 4alor pode mudar, +2 2+ dependendo do uso da mem>ria +2 2+ 2+ mas ser5 sempre i%ual a este 4alor +2 +2

Isto con"irma que realmente a "uno alterou o mesmo endereo de memria da varivel utilizada no main(). G instruo +a<=); alterou, indiretamente, o conte%do da varivel contador, porque o conte%do de a era o prprio endereo de contador, passado na c2amada.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 73

Algoritmos e Programao

Departamento de Informtica

Gtividade proposta .: >azer programa que utilize uma "uno que do$re o valor de uma varivel. Jesoluo:
4oid do1ra;4alor(int +4) +4 +=6; & 2+ rece1e endereco +2

2+ do1ra o 4alor de +4 e, indiretamente, de contador +2 printf(""alor dentro da funcao = %d *n", +4);

main() int contador = 7; printf (""alor inicial = %d *n", contador); do1ra;4alor(&contador); 2+ passando endereco printf (""alor final = %d *n", contador); & %etch(); +2

Gtividade proposta 3: >azer programa que utilize uma "uno para trocar o conte%do de duas variveis. Jesoluo:
4oid troca;4alores(int +pa, int +p1) int temp; temp = +pa; +pa = +p1; +p1 = temp;

&

main() int a = 6, 1 = '; printf (""alor inicial de a = %d e de 1= %d*n", a, 1); troca;4alores(&a, &1); 2+ passando enderecos printf (""alor final de a = %d e de 1= %d*n", a, 1); & %etch(); +2

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 7K

Algoritmos e Programao

Departamento de Informtica

19.5 PASSA)E* DE VETORES E *ATRI/ES PARA ,+NES


19.5.1 PASSA)E* DE VETORES G passagem de vetores e matrizes como argumentos para "uno &#0p%# ocorre p % %#1#%2!3$4. Como esperado, isto implica em que as alteraes que "orem e"etuadas no vetor passado como argumento dentro da "uno sero mantidas no mdulo que c2amar esta "uno. Lesmo sem e+plicitamente utilizar endereos na c2amada 5&4ari54el ou ponteiros para rece$er estes valores no ca$eal2o da "uno 5tipo +p4aria4el , 56# 7 p4&&48 para a "uno c2amada ) #!8#%#9 8 p%$0#$% #:#0#!" do vetor6matriz, valor este assumido pelo elemento do vetor6matriz declarada no ca$eal2o da "uno. ,ote, entretanto, que quando se passam elementos individuais do vetor6matriz, isto ) "eito por valor 5e+:
4etorA6B .

G mec@nica da passagem de vetores6matrizes como argumentos segue as seguintes regras: a ,a c2amada da "uno: ) colocado o nome da varivel composta, do mesmo modo como so colocadas as variveis simples. &or e+emplo:
imprime;4etor(4etor,:uant);

$ ,o ca$eal2o da "uno ) declarada a varivel composta sem a especi"icao de taman2o. &or e+emplo:
4oid imprime;4etor (float 4etorAB,int n)

-+emplo completo .: &rograma que lM um vetor e o passa como argumento, para "uno que o imprime:
4oid imprime;4etor (float 4etAB,int n) int i; for (i=(; i<n; i<<) printf("%f", 4etAiB); & main() float 4etorA!((B; int :uant, tamanho; printf("*nCi%ite o numero de elementos do 4etor (maD=!((): "); scanf("%d", &tamanho); printf("*nCi%ite os elementos do 4etor: *n"); :uant=(; Ehile (:uant<tamanho) scanf("%f",&4etorA:uantB); :uant<<; & imprime;4etor(4etor,:uant); %etch(); &

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 7N

Algoritmos e Programao

Departamento de Informtica

-+emplo 3: programa que passe um vetor para uma "uno e o$ten2a de retorno o seu menor elemento:
#include <stdio.h> #include <conio.h> float menor;elemento (float 4etAB,int n) int i; float menor; menor=4etA(B; for (i=(; i<n; i<<) if (4etAiB < menor) menor = 4etAiB; return menor;

&

main() float 4etorA!((B; int cont, tamanho; float menor;elemento(floatAB,int); printf("*nCi%ite o numero de elementos do 4etor (maD=!((): "); scanf("%d", &tamanho); printf("*nCi%ite os elementos do 4etor: *n"); cont=(; Ehile (cont<tamanho) scanf("%f",&4etorAcontB); cont<<; & printf ("Fenor elemento do 4etor: *n"); printf("%f *n", menor;elemento(4etor,cont)); %etch();

&

Oare"a proposta .: programa que passe um vetor para uma "uno e o$ten2a de retorno a soma de seus elementos. Jesoluo:
float soma;elementos (float 4etAB,int n) int i; float soma; menor=(; for (i=(; i<n; i<<) soma <= 4etAiB; & return soma;

e a c2amada F "uno:
soma;elementos (4etor,cont));

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 7P

Algoritmos e Programao

Departamento de Informtica

-+emplo K: &rograma que passe um vetor para uma "uno e o rece$a duplicado.
#include <stdio.h> #include <conio.h> 4oid do1ra;4etor (int 4etAB,int n) int i; for (i=(; i<n; i<<) 4etAiB = 4etAiB+6; & main() int 4etorA!((B; int cont, tamanho; printf("*nCi%ite o numero de elementos do 4etor (maD=!((): "); scanf("%d", &tamanho); printf("*nCi%ite os elementos do 4etor: *n"); for (cont=(; cont<tamanho; cont<<) scanf("%d",&4etorAcontB); printf (",hamando a funcao de duplicacao... *n"); do1ra;4etor(4etor,tamanho); printf("*nGaida do 4etor duplicado: *n"); for (cont=(; cont<tamanho; cont<<) printf("%d *n",4etorAcontB); %etch(); &

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 76

Algoritmos e Programao

Departamento de Informtica

-+emplo N: &rograma que passe um vetor de inteiros para uma "uno e o rece$a ordenado.
#include <stdio.h> #include <conio.h> 4oid ordena;4etor (int 4etAB,int n) int i, H, 9, menor; for (i=(; i<=nI6; i<<) H=i; menor=4etAiB; for(9=i<!; 9<=nI!; 9<<) if (4etA9B < menor) H=9; menor = 4etAHB; & 4etAHB = 4etAiB; 4etAiB = menor;

&

&

main() int 4etorA!((B; int cont, tamanho; printf("*nCi%ite o numero de elementos do 4etor (maD=!((): "); scanf("%d", &tamanho); printf("*nCi%ite os elementos do 4etor: *n"); cont=(; Ehile (cont<tamanho) scanf("%d",&4etorAcontB); cont<<; & printf (",hamando a funcao de ordenacao... *n"); ordena;4etor(4etor,tamanho); printf("*nGaida do 4etor ordenado: *n"); cont=(; Ehile (cont<tamanho) printf("%d",4etorAcontB); cont<<; & %etch(); &

Oare"a proposta 3: Je"aa o programa utilizando outro m)todo de ordenao 5item .6.6, p. N= .

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 77

Algoritmos e Programao

Departamento de Informtica

-+emplo P: &rograma que passe um vetor de caracteres para uma "uno e o rece$a ordenado.
#include <stdio.h> #include <conio.h> #define #NC J*(J 4oid ordena;4etor (char 4etorAB,int n) int i, H, 9; char menor; for (i=(; i<=nI6; i<<) H=i; menor=4etAiB; for(9=i<!; 9<=nI!; 9<<) if (4etA9B < menor) H=9; menor = 4etAHB; & 4etAHB = 4etAiB; 4etAiB = menor;

&

&

main() char 4etorA!((B; int cont, tamanho=(; printf("*nCi%ite os caracteres a ordenar e <#nter>: *n"); Ehile ((4etorAtamanhoB = %etchar()) K= J*nJ) tamanho<<; 4etorAtamanhoB=#NC; 2+ ,hamando a funcao de ordenacao... +2 ordena;4etor(4etor,tamanho); printf("*nGaida do 4etor ordenado: *n"); cont=(; Ehile (cont<tamanho) printf("%c",4etorAcontB); cont<<; & strin%:+2 2+ Lepetindo saMda com fun83o puts, tratando 4etor de char como printf("*n"); puts(4etor);

%etch(); &

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 74

Algoritmos e Programao

Departamento de Informtica

19.5.2 PASSA)E* DE *ATRI/ES CO*O AR)+*ENTO PARA ,+NES G di"erena entre a passagem por valor de matrizes em relao F passagem de vetores ) que no ca$eal2o da "uno deve se colocar pelo menos os <ndices da colunas, como no e+emplo:
menor;elemento (int matABA!((B,int m, int n)

-+emplo completo .: "azer um programa que passe uma matriz a uma "uno e o$ten2a de retorno o seu menor elemento:
#include <stdio.h> #include <conio.h> menor;elemento (int matABA!((B,int m, int n) int i,9, menor; menor=matA(BA(B; for (i=(; i<m; i<<) for (9=(; 9<n; 9<<) if (matAiBA9B < menor) menor = matAiBA9B; return menor;

&

main() int matriNA!((BA!((B; int i, 9, colunas, linhas; printf("*nCi%ite o numero de linhas da matriN (maD=!((): "); scanf("%d", &linhas); printf("*nCi%ite o numero de colunas da matriN (maD=!((): "); scanf("%d", &colunas); printf("*nCi%ite os elementos da matriN: *n"); for (i=(; i<linhas; i<<) for (9=(; 9<colunas; 9<<) printf("*nCi%ite o elementoA%dBA%dB da matriN: *n", i, 9); scanf("%d", &matriNAiBA9B);

&

printf ("Fenor elemento da matriN: *n"); printf("%d *n", menor;elemento(matriN,linhas, colunas)); %etch(); &

Oare"a proposta: &rograma que passe uma matriz para uma "uno e o$ten2a de retorno a soma de seus elementos.
soma;elementos (int matABA!((B,int m, int n) int i,9, soma; soma = (; for (i=(; i<m; i<<) for (9=(; 9<n; 9<<) soma <= matAiBA9B; return soma;

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 7=

Algoritmos e Programao

Departamento de Informtica

-+emplo 3: &rograma que passe uma matriz para uma "uno e a rece$a duplicada.
#include <stdio.h> #include <conio.h> 4oid do1ra;matriN(int matABA!((B,int m, int n) int i,9; for (i=(; i<m; i<<) for (9=(; 9<n; 9<<) matAiBA9B = matAiBA9B+6;

&

main() int matriNA!((BA!((B; int i, 9, colunas, linhas; printf("*nCi%ite o numero de linhas da matriN (maD=!((): "); scanf("%d", &linhas); printf("*nCi%ite o numero de colunas da matriN (maD=!((): "); scanf("%d", &colunas); printf("*nCi%ite os elementos da matriN: *n"); for (i=(; i<linhas; i<<) for (9=(; 9<colunas; 9<<) printf("*nCi%ite o elementoA%dBA%dB da matriN: *n", i<!, 9<!); scanf("%d", &matriNAiBA9B);

&

2+ ,hamada aa funcao :ue do1ra os elementos da matriN +2 do1ra;matriN(matriN,linhas,colunas); printf("*nOmpressao da matriN do1rada: "); for (i=(; i<linhas; i<<) printf("*n"); for (9=(; 9<colunas; 9<<) printf("%Pd", matriNAiBA9B);

&

& %etch();

DESA,IO; >azer um programa que leia um con9unto de nomes, passe estes nomes a uma "uno, que os devolva ordenados. ;icas: !m nome nada mais ) que uma string de caracteres# !ma string de caracteres ) tratada pelo compilador C como vetor de c2ar# !m vetor de nomes ), ento, um vetor de vetor, ou se9a, uma matriz de caracteres, onde cada lin2a da matriz ) um nome.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 4D

Algoritmos e Programao

Departamento de Informtica

19.6 *ANIP+LA'O AVANADA DE STRIN)S +TILI/ANDO PONTEIROS


19.6.1 I*PRESS'O DE STRIN)S +TILI/ANDO PONTEIROS
!ma cadeia de caracteres pode ser declarada, inicializada e impressa utilizando as instrues do programa:
-ro%ramaIeDemplo !: main() int i; char cadeiaA6(B= JFJ,JeJ,JnJ,JsJ,JaJ,J%J,JeJ,JmJ&; for (i=(; cadeiaAiB K= J*(J; <<i) putchar(cadeiaAiB); %etch();

&

He imprimirmos tam$)m os endereos que cada caracter ocupa na memria, como no programa a$i+o, teremos como resultado algo interessante:
-ro%ramaIeDemplo 6: main() int i; char cadeiaA6(B= JFJ,JeJ,JnJ,JsJ,JaJ,J%J,JeJ,JmJ&; for (i=(; cadeiaAiB K= J*(J; <<i) printf("%$ %c*n", &cadeiaAiB, cadeiaAiB); %etch();

&

G sa<da deste novo programa ser, dependendo do uso atual da memria do computador, algo como:
66??)( 66??)! 66??)6 66??)' 66??)) 66??)7 66??)P 66??)@ F e n s a % e m

Isto quer dizer que os caracteres desta string ocupam endereos de memria sucessivos. -ste "ato tam$)m vale, do mesmo modo para vetores e matrizes num)ricos. Lesmo as matrizes multidimensionais tem os seus valores armazenados seqQencialmente. -nto, se sou$ermos o endereo do primeiro caracter, poderemos imprimir os demais, incrementando o valor do prprio endereo.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 4.

Algoritmos e Programao &rograma'e+emplo K:


main() int i; char +p; char cadeiaA6(B= p= &cadeiaA(B; Ehile (+p K= J*(J) putchar(+p); p<<; & %etch();

Departamento de Informtica

JFJ,JeJ,JnJ,JsJ,JaJ,J%J,JeJ,JmJ&;

&

8u, de "orma mais compacta, &rograma'e+emplo N:


main() int i; char +p; char cadeiaA6(B= p= &cadeiaA(B; Ehile (+p K= J*(J) putchar(+p<<); %etch();

JFJ,JeJ,JnJ,JsJ,JaJ,J%J,JeJ,JmJ&;

&

Oare"as propostas: Implementar os programas anteriores, utilizando "unes para e"etuar as impresses das cadeias a elas transmitidas. Jesoluo programa .:
#include <stdio.h> #include <conio.h> 4oid mostra;cadeia(char cadeiaAB) int i; for (i=(; cadeiaAiB K= J*(J; <<i) putchar(cadeiaAiB);

&

main() char nomeA7(B; printf("Ci%ite nome: "); scanf("%s", nome); mostra;cadeia(nome); %etch();

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 43

Algoritmos e Programao Jesoluo programa 3:


#include <stdio.h> #include <conio.h> 4oid mostra;cadeia(char cadeiaAB) int i;

Departamento de Informtica

&

for (i=(; cadeiaAiB K= J*(J; <<i) printf("%$ %c*n", &cadeiaAiB, cadeiaAiB);

main() mostra;cadeia("Fensa%em a eDi1ir"); %etch();

&

Jesoluo programa K:
#include <stdio.h> #include <conio.h> 4oid mostra;cadeia(char +pcadeia) Ehile (+p K= J*(J) putchar(+p); p<<; &

& main()

&

mostra;cadeia("Fensa%em a eDi1ir"); %etch();

Jesoluo programa N:
#include <stdio.h> #include <conio.h> 4oid mostra;cadeia(char +pcadeia) Ehile (+pcadeia) putchar (+pcadeia<<);

&

main() mostra;cadeia("Fensa%em a eDi1ir"); %etch();

&

?em$re'se de que: ' 8 caracter J*(J ) tratado pelo C da mesma "orma como trata o ( 5zero # ' Q ( 5zero ) tratado como falso nas condies lgicas 5qualquer outro n%mero ) tratado como 4erdadeiro # ' quando +pcadeia tiver o conte%do *(, ser considerado resultado falso e interromper a e+ecuo do Ehile.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 4K

Algoritmos e Programao

Departamento de Informtica

19.6.2 C<PIA DE STRIN)S +TILI/ANDO PONTEIROS


!ma string de caracteres no pode ser copiada para outra utilizando uma instruo de atri$uio porque as strings no so variveis simples. Ho, na verdade, consideradas pelo compilador C como vetores de strings. &ara copiar o conte%do de uma string de caracteres em uma varivel string, pode'se utilizar a "uno strcpR, mostrada no item .7.6.N, ou desenvolver que "aa esta cpia, caracter a caracter. G$ai+o, duas maneiras de implementar esta cpia: a primeira utilizando vetores e a segunda, ponteiros. Cpia de uma string de caracteres em uma varivel string utilizando vetores:
#include <stdio.h> #include <conio.h> 4oid copia;cadeia(char fonteAB, char destinoAB) int i = (; Ehile (destinoAiB = fonteAiB) <<i;

&

main() char destinoA!60B; copia;cadeia(",adeia a ser copiada", destino); puts(destino); & %etch();

Cpia de uma string de caracteres em uma varivel string utilizando ponteiros:


#include <stdio.h> #include <conio.h> 4oid copia;cadeia(char +fonte, char +destino) Ehile (+destino<< = +fonte<<) ;& & main() char destinoA!60B; copia;cadeia(",adeia a ser copiada", destino); puts(destino); & %etch();

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 4N

Algoritmos e Programao

Departamento de Informtica

19.7 *ANIP+LA'O AVANADA DE VETORES +TILI/ANDO PONTEIROS


8s mesmos conceitos aplicados Fs strings ' que so tratadas pelo compilador C como vetores de caracteres ' so tam$)m vlidos para outros vetores num)ricos, como demonstrado no programa a$ai+o, que utiliza ponteiros para e+i$ir os valores de um vetor com P valores num)ricos:
4oid mostra;4alores(float +p4alor, int tamanho) int i=!; Ehile (i<< <= tamanho) printf("%f *n", +p4alor<<);

&

main() float 4aloresA7B = !.!, 6.6, '.', ).), 7.7&; mostra;4alores(4alores,7); %etch();

&

,ote'se, novamente, que na passagem de vetores6matrizes como argumento, o que ) passado ) o endereo do primeiro elemento, e que o incremento no ponteiro "az com que ele aponte para o pr+imo elemento. Glterando'se o programa para que ele imprima tam$)m o endereo de cada elemento, guardado em
p4alor, temos o cdigo: 4oid mostra;4alores(float +p4alor, int tamanho) int i=!; Ehile (i<< <= tamanho) printf(""alor %f #ndereco %$ *n", +p4alor, p4alor); p4alor = p4alor<!; &

&

main() float 4aloresA7B = !.!, 6.6, '.', ).), 7.7&; mostra;4alores(4alores,7); %etch();

&

- o resultado ser:
"alor "alor "alor "alor "alor

!.!((((( 6.6((((( '.'((((( ).)((((( 7.7(((((

#ndereco #ndereco #ndereco #ndereco #ndereco

66??7( 66??7) 66??70 66??7, 66??P(

Isto quer dizer que se incrementamos em uma unidade uma varivel ponteiro, no ) "eita simplesmente a soma do valor . a esta varivel, mas, sim, ) acrescentado o valor necessrio para que ele aponte para o pr+imo elemento. ,o e+emplo anterior, incrementando a varivel ponteiro em uma unidade, o valor e"etivamente somado "oi N, o taman2o em $Rtes da varivel cu9o endereo a varivel ponteiro pode armazenar.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 4P

Algoritmos e Programao

Departamento de Informtica

20 ESTR+T+RAS E +NIES
>orma de manter unidas variveis de di"erentes tipos. >acilita passagem de argumentos relacionados a "uno. He temos vrios dados relacionados a um mesmo o$9eto, ao inv)s de pass'los todos como argumentos para a "uno, passa'se apenas uma varivel do tipo estrutura. Oam$)m c2amadas de =4%$>=#$& 3 0p &"4& ?#"#% @2!#4& 5Gs variveis compostas 2omogMneas so as matrizes, como vimos . -m outras linguagens de programao como o &ascal, as estruturas so c2amadas de %#@$&"% &. -+emplo de aplicao imediata:
main() struct eDemplo int num; char ch; &; eDemplo 4arD; 4arD.num = 6; 4arD.ch = RST; 22 declara83o do tipo de dado struct eDemplo 22 as 4ari54eis do tipo eDemplo ter3o campo num 22 as 4ari54eis do tipo eDemplo ter3o campo ch 22 22 22 22 declara83o de uma 4ari54el do tipo eDemplo 4arD possui dois campos, num e ch atri1ui83o de 4alor ao campo num de 4arD atri1ui83o de constante ao campo ch de 4arD 22 impress3o do campo num 22 impress3o do campo ch

&

printf(.%d/, 4arD.num); printf(.%c/, 4arD.ch);

20.1 DECLARA'O
.S "orma:
struct pessoa charA7(B nome; int idade; float salario; &; struct pessoa maria; pessoa marcos, 9oao = 22 declara83o do tipo estrutura pessoa

22 declara83o de 4ari54eis estrutura 6P, ')7.P@&; 22 forma tam1Um aceita

3S "orma, utilizando tRpede":


tVpedef struct pessoa charA7(B nome; int idade; float salario; &cliente; pessoa marcos, 9oao = cliente maria;

22 defini83o de um alias p o identificador 6P, ')7.P@&; 22declara83o de 4ari54eis 22declara83o utiliNando o alias

!ma estrutura tem trMs componentes principais: . a palavra reservada struct, 3 o identi"icador da estrutura e K a declarao dos campos. Ino$stante algumas re"erMncias indicarem que cliente, neste %ltimo e+emplo, seria a declarao de uma varivel, testes nos compiladores C indicam que ele 5cliente "unciona como um alias 5apelido do nome do identi"icador, podendo su$stitu<'lo.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 46

Algoritmos e Programao

Departamento de Informtica

EA#0p: 8# 4p:$349B 1: declarao e manipulao de dados estrutura 53 campos num)ricos e . varivel Identi"ique: a a de"inio do tipo# $ a declarao da varivel# c a de"inio dos valores dos campos atrav)s de atri$uio e leitura e d a impresso dos valores dos campos.
main() tVpedef struct pessoa int idade; float salario; &cliente; cliente maria; maria.idade = '(; printf("Galario: "); scanf("%f", &maria.salario); printf("Cados da Faria: *n"); printf("Odade = %d ",maria.idade); printf("Galario = %f *n *n",maria.salario); %etch();

&

EA#0p: 8# 4p:$349B 2: declarao e manipulao de dados estrutura 53 campos num)ricos e K variveis ,este e+emplo, demonstra'se como proceder F de"inio dos valores dos campos de trMs modos: a na inicializao# $ por atri$uio e c pelo teclado.
main() struct pessoa int idade; float salario; &; struct pessoa maria, marcos, 9oao = maria.idade = '(; maria.salario = 7((.0=; printf("Onforme os dados do Farcos: *n"); printf("Odade: "); scanf("%d", &marcos.idade); printf("Galario: "); scanf("%f", &marcos.salario); printf("*n Cados do Woao: *n"); printf("Odade = %d ",9oao.idade); printf("Galario = %f *n *n",9oao.salario); printf("Cados da Faria: *n"); printf("Odade = %d ",maria.idade); printf("Galario = %f *n *n",maria.salario); printf("Cados do Farcos: *n"); printf("Odade = %d ",marcos.idade); printf("Galario = %f ",marcos.salario); & %etch(); 6P, ')7.P@&;

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 47

Algoritmos e Programao

Departamento de Informtica

EA#0p: 8# 4p:$349B 3: declarao e manipulao dados estrutura, incluindo campo do tipo string de caracteres. ;emonstra'se, tam$)m, que o identi"icador cliente no ) uma varivel 5e sim um alias do identi"icador do tipo ao se tentar atri$uir o valor KK ao 2ipot)tico campo cliente.idade. - como pode ser Batri$u<doC um valor a um campo string 5via "uno strcpV .
#include #include #include #include main() tVpedef struct pessoa char nomeA7(B; int idade; float salario; &cliente; cliente maria, marcos, 9oao = 22 cliente.idade = '' "Woao Gil4a",6P, ')7.P@&; <stdli1.h> <stdio.h> <conio.h> <strin%.h>

atri1uicao inde4ida I d5 erro atri1 inde4ida I erro

22 maria.nome = . Faria ?erreira/;

strcpV(maria.nome, "Faria ?erreira"); maria.idade = '(; maria.salario = 7((.0=; printf("Onforme os dados do Farcos: *n"); printf("Nome: "); %ets(marcos.nome); 22 + printf("Odade: "); scanf("%d", &marcos.idade); printf("Galario: "); scanf("%f", &marcos.salario); printf("*n Cados do Woao: *n"); printf("Nome = %s ",9oao.nome); printf("Odade = %d ",9oao.idade); printf("Galario = %f *n *n",9oao.salario); printf("Cados da Faria: *n"); printf("Nome = %s ",maria.nome); printf("Odade = %d ",maria.idade); printf("Galario = %f *n *n",maria.salario); printf("Cados do Farcos: *n"); printf("Nome = %s ",marcos.nome); printf("Odade = %d ",marcos.idade); printf("Galario = %f ",marcos.salario); & %etch();

: 8 programa no "uncionar adequadamente se implementarmos a leitura do campo marcos.nome utilizando a "uno scan". &or esta razo ) mais adequado utilizar a "uno %ets.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 44

Algoritmos e Programao

Departamento de Informtica

20.2 ACESSANDO ESTR+T+RAS ATRAV.S DE PONTEIROS


&ara manipular estruturas atrav)s de ponteiros, tem'se que: a ;eclarar uma varivel ponteiro que possa apontar para o tipo estrutura criado# $ Grmazenar o endereo da varivel estrutura na varivel ponteiro. c Gcessar o conte%do da varivel estrutura indiretamente utilizando: c.. (+4arp).campo ou 66 a instrucao +4arp.campo = P; gera erro. c.3 4arp I>campo -stas duas "ormas de acesso indireto so equivalentes e podem ser interpretadas como: BCampo da varivel para a qual 4arp apontaC. 8u: BCampo da varivel cu9o endereo est em 4arpC. Implementao ., sem ponteiros:
main() tVpedef struct int lado!; int lado6; int lado'; int perimetro; & trian%ulo; trian%ulo isosceles; isosceles.lado!=P; isosceles.lado6=P; isosceles.lado'=P; isosceles.perimetro = isosceles.lado'; isosceles.lado! < isosceles.lado6 <

printf("perimetro = %d ",isosceles.perimetro); & %etch();

Implementao 3, com ponteiros:


main() tVpedef struct int lado!; int lado6; int lado'; int perimetro; & trian%ulo; trian%ulo isosceles; trian%ulo +p; p=&isosceles; pI>lado!=P; pI>lado6=P; pI>lado'=P; pI>perimetro = pI>lado! < pI>lado6 < pI>lado'; 22 ou: (+p).perimetro = (+p).lado! < (+p).lado6 < (+p).lado'; printf("perimetro = %d ",isosceles.perimetro); 22 ou: pI>perimetro ou: (+p).perimetro %etch();

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli 4=

Algoritmos e Programao

Departamento de Informtica

20.3 TARE,AS PROPOSTAS


T4%#14 p% p &"4 1: ;esenvolver programa que implemente o programa de aplicao imediata 5item 3D, p. 46 de "orma que permita o acesso indireto aos campos das variveis do tipo estrutura, utilizando ponteiros. T4%#14 p% p &"4 2: Implementar o programa anterior utilizando uma "uno para imprimir os elementos. ,a c2amada F "uno dever ser passado como argumento a varivel estrutura e no seus campos individualmente. T4%#14 p% p &"4 3: Gltere o programa anterior para que se9am incrementados em uma unidade os valores dos campos. 8$s: Go se incrementar uma varivel caracter, a ela ser atri$u<do o pr+imo caracter da ta$ela GHCII.

R#& :69B 84 "4%#14 1;


main() struct eDemplo int num; char ch; &; eDemplo 4arD; eDemplo +p4; p4 = &4arD; (+p4).num = 6; (+p4).ch = RST; printf(.%d/, (+p4).num); printf(.%c/, (+p4).ch);

&

Implementao alternativa: su$stitua as ocorrMncias de (+p4) por p4I>, conforme e+posto no item 3D.3:
main() struct eDemplo int num; char ch; &; eDemplo 4arD; eDemplo +p4; p4 = &4arD; p4I>num = 6; p4I>ch = RST; printf(.%d/, p4I>num); printf(.%c/, p4I>ch);

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =D

Algoritmos e Programao R#& :69B 84 "4%#14 2;


struct eDemplo int num; char ch; &; 4oid imprime;struct(eDemplo +pe) printf("%d", peI>num); printf("%c", peI>ch);

Departamento de Informtica

&

main() eDemplo 4arD; eDemplo +p4; p4 = &4arD; p4I>num = 6; p4I>ch = JSJ; imprime;struct(p4);

&

R#& :69B 84 "4%#14 3;


struct eDemplo int num; char ch; &; 4oid incrementa;struct(eDemplo +pe) peI>num<<; peI>ch<<; 22 ou: peI>num = peI>num < !; 22 ou: peI>ch = peI>ch < !;

&

main() eDemplo 4arD; eDemplo +p4; p4 = &4arD; p4I>num = 6; p4I>ch = JXJ; incrementa;struct(p4); printf("%d", p4I>num); printf("%c", p4I>ch);

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =.

Algoritmos e Programao

Departamento de Informtica

20.4 VETORES DE ESTR+T+RAS


G manipulao de vetores de estruturas segue $asicamente as mesmas regras da manipulao de variveis simples, com a di"erena $sica que os campos devem ser acessados separadamente, como nos e+emplos:
scanf("%d", &clientelaAiB.idade); printf("Odade: %d : ", clientelaAiB.idade); clientelaAiB.idade = 66; menor = clientelaAiB.idade; leitura impress3o atri1ui83o atri1ui83o

8 programa completo a$ai+o e+empli"ica mel2or o uso destas instrues:


main() tVpedef struct pessoa int idade; float salario; &cliente; cliente clientelaA!((B; int i, n; printf("Onforme o nYmero de clientes: "); scanf("%d", &n); printf("*n*n#ntrada dos dados dos clientes *n*n"); for (i=(; i<n; i<<) printf("Onforme os dados do ,liente %d: *n", i<!); printf("Odade: "); scanf("%d", &clientelaAiB.idade); printf("Galario: "); scanf("%f", &clientelaAiB.salario); & printf("*n*nOmpressao dos dados dos clientes *n*n"); for (i=(; i<n; i<<) printf(",liente %d Odade: %d : *n", i<!, clientelaAiB.idade); printf(",liente %d Galario: %f: *n", i<!, clientelaAiB.salario); & & %etch();

Oare"a proposta .: Implementar, no programa anterior, tem$)m o campo nome.

Oare"a proposta 3: programa que de"ina vetor de estrutura, que possuam campos nome, idade e salrio. !tilize uma "uno para leitura do vetor e outra para sua impresso.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =3

Algoritmos e Programao Jesoluo da tare"a proposta 3:


#include <conio.h> #include <stdio.h> #include <stdli1.h> tVpedef struct int idade; float salario; char nomeA!(B; & cliente;

Departamento de Informtica

int insere;clientes(cliente clientelaAB) 22retorna nYmero de elementos int n,i; printf("Zuantos clientes 4c ira inserir:"); scanf("%d",&n); i=(; Ehile (i<n) printf("*n*n#ntrada dos dados dos clientes *n*n"); printf("Onforme os dados do cliente %d: *n", i<!); printf("Nome:"); scanf("%s",&clientelaAiB.nome); printf("Odade:"); scanf("%d", &clientelaAiB.idade); printf("Galario:"); scanf("%f",&clientelaAiB.salario); i<<; & return n; & 4oid mostra;clientes(cliente clientelaAB,int n) int i; i=(; Ehile (i<n) printf("*n ++++++,liente:A%dB++++++", i<!); printf("*nNome: %s *n",clientelaAiB.nome); printf("Odade: %d *n",clientelaAiB.idade); printf("Galario: %f *n",clientelaAiB.salario); i<<; & & main() cliente clientelaA7(B; int m; m=insere;clientes(clientela); mostra;clientes(clientela,m); & %etch();

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =K

Algoritmos e Programao

Departamento de Informtica

20.5 +NIES
G unies so declaradas e manipuladas de maneira muito parecida com as estruturas. G di"erena entre elas ) que os campos de uma varivel declarada de tipo unio ocupam um s espao na memria. 8u se9a: pode'se armazenar di"erentes tipos de dados, por)m um s deles por vez. G maior vantagem do uso das unies ) a economia de memria, visto que no so declarados campos que no so utilizados. Ve9a o e+emplo:
main() union tipouniao int inteiro; float real; char caracter; &; tipouniao 4aruniao; 4aruniao.inteiro = 6; 22 campo rece1eu dado int printf(""alor atual da uniao = %d *n", 4aruniao.inteiro); 4aruniao.real = '.!)!7=6; 22 campo rece1eu dado float printf(""alor atual da uniao = %f *n", 4aruniao.real); 4aruniao.caracter = JXJ; 22 campo rece1eu dado char printf(""alor atual da uniao = %c *n", 4aruniao.caracter); & %etch();

8$serva'se que deve se manter estrito controle so$re qual dado est armazenado no momento na unio. 8 grupo de instrues a$ai+o geraria um resultado errTneo em tempo de e+ecuo:
4aruniao.inteiro = 6; printf(""alor atual da uniao = %f *n", 4aruniao.real);

8 espao que ) reservado pelo compilador para uma varivel unio ) o su"iciente para armazenar o maior campo da unio.
main() struct stru int inteiro; float real; char caracter; &; union uni int inteiro; float real; char caracter; &; uni uniao; stru estrutura; printf("[amanho da estrutura= %d 1Vtes*n",siNeof(estrutura)); 22!6 printf("[amanho da uniao= %d 1Vtes*n", siNeof(uniao)); 22 )

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =N

Algoritmos e Programao

Departamento de Informtica

21 ALOCA'O DINC*ICA
G alocao esttica de memria, que ) a que temos implementado at) o momento resolve muitas, por)m no todas as necessidades de programao. Euando se coloca a seguinte declarao em um programa:
int a;

o compilador esta$elece que ser alocado, em tempo de e+ecuo, o espao de memria necessrio para o armazenamento de um int e permitir colocar e retirar valores deste espao atri$uindo a ele um nome, no caso, a. &or outro lado, a seguinte declarao reservar espao su"iciente para o armazenamento de .DD variveis do tipo int, dando o nome a para apontar para o primeiro elemento:
int aA!((B;

-ntretanto, o que se pode "azer se o espao reservado no "or su"iciente, ou se9a, se precisarmos utilizar mais espao do que o originalmente previsto7 G soluo ) implementarmos a 4: 349B 8$!D0$34 8# =4%$>=#$&, atrav)s de ponteiros e das "unes malloc() e siNeof().

21.1 A ,+N'O SI/EO,E F


G "uno siNeof() retorna o taman2o, em $Rtes, do argumento passado para a "uno. -ste argumento pode ser uma constante, uma varivel ou um tipo. Ve9a o e+emplo:
#include <stdio.h> #include <conio.h> main() 1ool 1; printf("siNeof(6)= %d*n", siNeof(6)); 22 printf("siNeof(JXJ)= %d*n", siNeof(JXJ)); 22 printf("siNeof(char)= %d*n", siNeof(char)); 22 ! printf("siNeof('.)!7=6)= %d*n", siNeof('.!)!7=6)); 22 printf("siNeof(1ool)= %d", siNeof(1)); 22 6 ! 0 !

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =P

Algoritmos e Programao

Departamento de Informtica

21.2 A ,+N'O *ALLOCE F


G "uno malloc() aloca o n%mero de $Rtes passados a ela como argumento e retorna o endereo do in<cio desta rea de memria alocada. &or e+emplo, a instruo a$ai+o aloca N $Rtes de memria e coloca o endereo inicial deste espao na varivel ponteiro, p:
p = malloc());

G alocao de memria compreende, ento: ' localizar espao de memria dispon<vel, ' marcar este espao como em uso 5retirar da relao dos espaos6$Rtes livres e ' o$ter o endereo do in<cio desta rea, atri$uindo'o a uma varivel ponteiro. 8 endereo retornado ) de "ormato padro, no "ormatado para nen2um tipo de ponteiro 5em C, diz'se que ) retornado um ponteiro para 4oid . Euais as conseqQMncias disto7 8portunamente vimos que no momento da criao de uma varivel ponteiro deve'se especi"icar o tipo de dado 5int, float, char, struct,... para o qual o ponteiro pode apontar 5item .=.3D . Vimos ta$)m que quando incrementamos uma varivel ponteiro, o pr+imo endereo apontado depende do tipo de dados apontado 5itens .=.6.. e .=.6.3 . 8u se9a, quando incrementamos um ponteiro 5p. e+: p<< que aponta para o in<cio de um vetor ou string, esta varivel ponteiro apontar para o pr+imo elemento do vetor ou para o pr+imo caracter da string, con"orme o caso. &ortanto, para que possamos armazenar o endereo retornado em "ormato padro, deve'se trans"orm'lo para o tipo espec<"ico do ponteiro que ir rece$er este endereo. G utilizao prtica da "uno malloc() ) demonstrada a$ai+o:
#include <stdio.h> #include <conio.h> #include <stdli1.h> main() int +p; p = (int +)malloc()); +p = !!; printf ("+p= %d", +p); & %etch(); 22 ou: p = (+int)malloc(siNeof(int)); 22 +p = !!

&ara que o endereo retornado pela "uno malloc() possa ser armazenado na varivel ponteiro p, que, neste caso, pode armazenar o endereo de um inteiro, utiliza'se uma 3 !=#%&B 8# "$p 5type cast , colocando'se antes da "uno malloc() o tipo para o qual se quer converter o endereo. ,o e+emplo, o tipo ) (int +), ponteiro para int, ou se9a, o endereo ser trans"ormado para o tipo #!8#%#9 8# 604 =4%$>=#: int.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =6

Algoritmos e Programao

Departamento de Informtica

21.3 LISTAS SI*PLES*ENTE ENCADEADAS


ESTR+T+RA PARA DECLARA'O DE N<S DE +*A LISTA SI*PLES*ENTE ENCADEADA -struturas que possuem um campo ponteiro que pode armazenar um endereo de uma outra varivel estrutura do mesmo tipo so especialmente %teis para criar listas encadeadas. G declarao da estrutura dos ns desta lista dever conter um campo que permita armazenar o endereo do pr+imo n. Ve9a o e+emplo a$ai+o:
main() struct elemento int 4alor; elemento +proDimo; &; elemento noh, +primeiro; primeiro = &noh;

,este caso, a varivel primeiro poder guardar o endereo de 5apontar para um n da lista. 8$serve que cada n que "or criado utilizando este tipo estrutura elemento ter tam$)m um campo pr>Dimo, que poder guardar o endereo do pr+imo n. - assim por diante. ,este caso "oi criada 5estaticamente a varivel noh, do tipo estrutura elemento que, portanto, ter os campos 4alor e pr>Dimo. 8 campo 4alor desta varivel noh, declarada do tipo elemento, poder ser acessado como a$ai+o:
noh.4alor = 6; (+primeiro).4alor = !(; 22acesso direto ou

22 acesso indireto, atra4Us de primeiro 22altera o conteYdo de noh.4alor para !( 22 ou: primeiroI>4alor = !(;

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =7

Algoritmos e Programao -+emplo de aplicao .:

Departamento de Informtica

8 programa a$ai+o demonstrar de maneira simpli"icada o tipo de operaes que so e"etuadas para listas simplesmente encadeadas: ' Inicialmente declara o tipo struct [ficha, com o campo ponteiro proD. ' Cria, tam$)m, um tipo ponteiro -ficha, ponteiro para [ficha. ' Gps mostrar o taman2o em $Rtes do tipo [ficha, aloca uma varivel do tipo [ficha dinamicamente, colocando o seu endereo inicial em novo. ' -ste endereo ) atri$u<do a corrente, que tam$)m pasa a apontar para a nova varivel. ' Gtri$ui'se e imprime'se valor para o campo nome desta nova varivel.

#include #include #include #include

<stdio.h> <conio.h> <stdli1.h> <strin%.h> 22 ou: struct [ficha

tVpedef struct [ficha char nomeA'(B; struct [ficha +proD;

&;

tVpedef [ficha +-ficha; main()

22 Cefine tipo ponteiro -ficha 22 Guas 4ari54eis poder3o apontar para 22 4ari54eis do tipo [ficha

char nome6A'(B; 22 ou: [ficha +corrente, +no4o -ficha corrente, no4o; printf("siNeof([ficha)= %d*n", siNeof([ficha)); 22'P no4o = ([ficha +) malloc(siNeof([ficha)); 22 ou: no4o = (-ficha) malloc(siNeof([ficha)); corrente = no4o; printf("Ci%ite nome: "); scanf("%s", &correnteI>.nome); correnteI>proD = N\]]; 22 ou: 22 scanf("%s", &(+corrente).nome); 22 ou: (+corrente).proD = N\]];

printf("Nome: %s", correnteI>nome); 22 ou: printf("Nome: %s", (+corrente).nome); & %etch();

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli =4

Algoritmos e Programao

Departamento de Informtica

-+emplo de aplicao 3: 8 programa a$ai+o utiliza a estrutura e variveis de"inidas no e+emplo anterior, criando trMs variveis din@micas encadeadas e mostrando os seus conte%dos.
#include #include #include #include <stdio.h> <conio.h> <stdli1.h> <strin%.h>

tVpedef struct [ficha char nomeA'(B; struct [ficha +proD;

&;

tVpedef [ficha +-ficha; main() -ficha primeiro=N\]], corrente, no4o; no4o = (-ficha) malloc(siNeof([ficha)); primeiro = no4o; corrente = no4o; printf("Nome: "); scanf("%s", &correnteI>nome); correnteI>proD = N\]]; no4o = (-ficha) malloc(siNeof([ficha)); correnteI>proD = no4o; corrente = no4o; printf("Nome: "); scanf("%s", &(+corrente).nome); correnteI>proD = N\]]; no4o = (-ficha) malloc(siNeof([ficha)); correnteI>proD = no4o; corrente = no4o; printf("Nome: "); scanf("%s", &(+corrente).nome); correnteI>proD = N\]]; 22 impress3o dos nomes da lista printf("*nNomes armaNenados na lista: *n"); corrente=primeiro; printf("Nome: %s*n", correnteI>nome); corrente=correnteI>proD; printf("Nome: %s*n", correnteI>nome); corrente=correnteI>proD; printf("Nome: %s*n", correnteI>nome); & %etch();

8$s: ,ote a criao, neste e+emplo, do tipo -ficha, ponteiro para [ficha, tipo ao qual pertencem as variveis ponteiro primeiro, corrente e no4o. G criao deste tipo torna mais simples e intelig<vel o uso da "uno malloc na instruo: no4o = (-ficha) malloc(siNeof([ficha));

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli ==

Algoritmos e Programao

Departamento de Informtica

G impresso dos nomes armazenados na lista poderia ser implementada no e+emplo anterior de maneira gen)rica para qualquer n%mero de nomes inclu<dos atrav)s do algoritmo:
printf("*nNomes armaNenados na lista: *n"); corrente=primeiro; Ehile (corrente K= N\]]) printf("Nome: %s*n", correnteI>nome); corrente=correnteI>proD;

&

Oare"a proposta .: Implementar um programa que crie, insira nomes e os liste, atrav)s de uma lista simplesmente encadeada, utilizando "unes para insero e listagem dos nomes. ;ica: VocM pode utilizar os ca$eal2os para as "unes e respectivas c2amadas, como mostrado:
4oid insere(-ficha +p, -ficha +c) 4oid lista(-ficha primeiro) insere(&prim, &corr); lista(prim); 22 ou: 4oid lista([ficha +primeiro)

Oare"a proposta 3: Jeescrever o programa proposto na tare"a ., inserindo tam$)m uma "uno para a e+cluso de um nome dese9ado.

21.4 LISTAS D+PLA*ENTE ENCADEADAS


DECLARA'O DE TIPO ESTR+T+RA PARA N< DE LISTA D+PLA*ENTE ENCADEADA G di"erena em relao F lista simplesmente encadeada ) que os ns de uma lista duplamente encadeada precisam de dois campos do tipo ponteiro, um para armazenar o endereo do n anterior al)m do campo para armazenar o endereo do pr+imo n. G ligao de cada n com o n anterior e com o posterior, al)m de permitir a eliminao de ns com maior "acilidade, possi$ilita percorrer a lista no modo inverso, do %ltimo ao primeiro n, para manipular ou imprimir os dados.
struct [ficha char nomeA)(B; char emailA'(B; char telefoneAPB; [ficha +proD; [ficha +ant; &; [ficha +primeiro,+no4o,+ultimo,+corrente;

&rogramas que manipulam listas duplamente encadeadas necessitam, al)m das variveis tipo estrutura com dois campos ponteiro 5no caso, [ficha , tam$)m de variveis ponteiro que possam armazenar as posies do primeiro, do ultimo n, assim como para armazenar os valores temporrios do no4o n e do n corrente, necessrios para a criao e manipulao da lista. _________________________________________________________________________________ Professor Jeferson Antonio Quimelli .DD

Algoritmos e Programao

Departamento de Informtica

-+emplo de aplicao .: 8 programa a$ai+o cria dinamicamente trMs ns de uma lista duplamente encadeada e lista os nomes na ordem de insero e na ordem inversa.
tVpedef struct ficha char nomeA'(B; struct ficha +ant; struct ficha +proD; & [ficha; tVpedef [ficha +-ficha; main() -ficha primeiro=N\]], corrente, no4o, ultimo; no4o = (-ficha) malloc(siNeof([ficha)); corrente = no4o; printf("Nome: "); scanf("%s", &correnteI>nome); 22 ou: 22 scanf("%s", &(+corrente).nome); correnteI>proD = N\]]; primeiro = no4o; ultimo = no4o; correnteI>ant = N\]]; no4o = (-ficha) malloc(siNeof([ficha)); correnteI>proD = no4o; no4oI>ant = corrente; corrente = no4o; ultimo = no4o; printf("Nome: "); scanf("%s", &correnteI>nome); correnteI>proD = N\]]; no4o = (-ficha) malloc(siNeof([ficha)); correnteI>proD = no4o; no4oI>ant = corrente; corrente = no4o; ultimo = no4o; printf("Nome: "); scanf("%s", &correnteI>nome); correnteI>proD = N\]]; printf("*nNomes armaNenados na lista: *n"); corrente=primeiro; printf("Nome: %s*n", correnteI>nome); corrente=correnteI>proD; printf("Nome: %s*n", correnteI>nome); corrente=correnteI>proD; printf("Nome: %s*n", correnteI>nome); printf("*nNomes armaNenados na lista, do ultimo ao primeiro: *n"); corrente = ultimo; printf("Nome: %s*n", correnteI>nome); corrente=correnteI>ant; printf("Nome: %s*n", correnteI>nome); corrente=correnteI>ant; printf("Nome: %s*n", correnteI>nome); & %etch();

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli .D.

Algoritmos e Programao

Departamento de Informtica

-+emplo de aplicao 3: -ste programa amplia as "uncionalidades do programa'e+emplo anterior, permitindo a criao de um n%mero inde"inido de ns e a listagens dos nomes na mesma ordem da insero e na ordem inversa.
#include #include #include #include <stdio.h> <conio.h> <stdli1.h> <strin%.h>

tVpedef struct ficha char nomeA'(B; struct ficha +ant; struct ficha +proD; & [ficha; tVpedef [ficha +-ficha; main() -ficha primeiro=N\]], corrente, no4o, ultimo; int cont=!; Ehile(cont) no4o = (-ficha) malloc(siNeof([ficha)); if (primeiro== N\]]) primeiro=no4o; no4oI>ant=N\]]; & else no4oI>ant=corrente; correnteI>proD=no4o; & corrente = no4o; printf("Nome: "); scanf("%s", &(+corrente).nome); correnteI>proD = N\]]; ultimo = no4o; printf("Ci%ite (() para listar ou (!) para continuar insercao:"); scanf("%d",&cont);

&

printf("*nNomes armaNenados na lista: *n"); corrente=primeiro; Ehile (corrente K= N\]]) printf("Nome: %s*n", correnteI>nome); corrente=correnteI>proD; & printf("*nNomes armaNenados na lista, do ultimo ao primeiro: *n"); corrente = ultimo; Ehile (corrente K= N\]]) printf("Nome: %s*n", correnteI>nome); corrente=correnteI>ant; & & %etch();

Oare"a proposta: Implementar um programa que crie, insira nomes e os liste, atrav)s de uma lista duplamente encadeada, utilizando "unes para insero, listagem e e+cluso de nomes.

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli .D3

Algoritmos e Programao

Departamento de Informtica

!ma das poss<veis solues para a tare"a proposta nU . so$re listas simplesmente encadeadas:
#include #include #include #include <stdio.h> <conio.h> <stdli1.h> <strin%.h>

tVpedef struct [ficha char nomeA'(B; struct [ficha +proD; &; tVpedef [?icha +-?icha; 4oid insere(-?icha +p, -?icha +c) -?icha no4o; no4o=(-?icha)malloc(siNeof([?icha)); if (+p== N\]]) +p=no4o; else (+c)I>proD=no4o; no4oI>proD=N\]]; printf("Nome:"); scanf(" %s",&no4oI>nome); +c=no4o;

&

4oid lista(-?icha primeiro) -ficha corrente; printf("Nomes armaNenados na lista: "); corrente=primeiro; Ehile (correnteK=N\]]) printf("*n Nome:%s",correnteI>nome); corrente=correnteI>proD; &

&

main () -?icha prim=N\]], corr; int cont=!; Ehile (cont) insere(&prim, &corr); printf("Ci%ite (() para encerrar ou (!) para continuar:"); scanf("%d",&cont);

&

&

lista(prim); %etch();

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli .DK

Algoritmos e Programao

Departamento de Informtica

!ma das poss<veis solues para a tare"a proposta so$re o assunto listas duplamente encadeadas:
22 ]OG[X C\-]XF#N[# #N,XC#XCX 22 c fun8^es, s 4ar %lo1ais, c passa%em 4ar p2 referencia, c eDclus3o #include #include #include #include <stdio.h> <conio.h> <stdli1.h> <strin%.h>

tVpedef struct ficha char nomeA'(B; struct ficha +ant; struct ficha +proD; & [ficha; tVpedef [ficha +-ficha;

4oid insere(-ficha +p, -ficha +u) -ficha no4o; no4o = (-ficha) malloc(siNeof([ficha)); if (+p==N\]]) +p=no4o; no4oI>ant=N\]];

& else

&

& printf("Nome: "); scanf("%s", &no4oI>nome); no4oI>proD = N\]]; +u = no4o;

no4oI>ant=+u; (+u)I>proD=no4o;

4oid listadireta(-ficha auD) int cont=!; printf("*nNomes armaNenados na lista, do primeiro ao ultimo: *n"); Ehile (auD K= N\]]) printf("%d I Nome: %s*n", cont<<, auDI>nome); auD=auDI>proD; &

&

4oid listain4ersa(-ficha auD) printf("*nNomes armaNenados na lista, do ultimo ao primeiro: *n"); Ehile (auD K= N\]]) printf("Nome: %s*n", auDI>nome); auD=auDI>ant;

&

&

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli .DN

Algoritmos e Programao

Departamento de Informtica

4oid deleta(-ficha +p, -ficha +u) int escolha, D,cont=!; -ficha auD; printf("]ista%em dos re%istros: *n"); listadireta(+p); auD=+p; 22 auD aponta para o primeiro no printf("Numero do re%istro a eDcluir: *n"); scanf("%d",&D); Ehile (cont<D) auD = auDI>proD; cont<<;

&

& printf("Le%istro a eDcluir: "); printf("%s*n",auDI>nome); if (auD==+p) 22 auD aponta para o primeiro no +p = (+p)I>proD; (+p)I>ant=N\]]; & else if (auD==+u) 22 auD aponta para o ultimo no +u = auDI>ant; (+u)I>proD = N\]]; & else 22 auD aponta para no intermediario auDI>antI>proD = auDI>proD; 22 campo proD no anterior aponta p proD no auDI>proDI>ant = auDI>ant; 22 campo ant proD no ponta p no anterior & free(auD); printf("No4a lista apos eDclusao: *n"); listadireta(+p);

main() -ficha primeiro=N\]], ultimo=N\]]; int escolha=!; Ehile (escolha) 22cont==! printf("#scolha: (()?im, (!)Onserir, (6)]istar, (')]ista in4ersa, ())#Dcluir noJ: *n"); scanf("%d", &escolha); if (escolha==() printf ("?im do pro%rama I Q1ri%ado pelo usoK*n"); else if (escolha==!) insere(&primeiro, &ultimo); else if (escolha==6) listadireta(primeiro); else if (escolha==') listain4ersa(ultimo); else if (escolha==)) deleta(&primeiro,&ultimo); else printf ("Qpcao in4alidaK*n"); & %etch(); &

_________________________________________________________________________________ Professor Jeferson Antonio Quimelli .DP

Algoritmos e Programao

Departamento de Informtica

22.PROGRAMAO ORIENTADA A OBJETOS


Os conceitos da programao orientada a objetos foram desenvolvidos no Centro de Pesquisas da Xerox em Palo Alto, U A, na d!cada de "# e aplicados na linguagem malltal$, desenvolvida especialmente para esse fim pelos pesquisadores %oldberg e &obson, descrita e divulgada em '()*'+ Os conceitos de orientao a objetos foram incorporados , linguagem C atrav!s da biblioteca iostream+.ou iostream/, gerando a linguagem C00, que manteve, deste modo, o paradigma da programao estruturada em adio ao novo paradigma de orientao a objetos+ A grande vantagem da utili1ao dos objetos ! que se pode implementar um mel-or controle de quais fun2es .m!todos ou outras fun2es externas ao objeto/ podem ou no manipular determinadas propriedades .vari3veis membros dos objetos/+

22.1.CLASSE
Uma classe ! uma estrutura de dados, equivalente , struct da linguagem C+ As classes declaram quais os atributos .vari3veis/ e quais m!todos .fun2es/ tero os objetos que forem declarados desta classe+ Podemos di1er que a classe define a composio do objeto, o seu tipo+ Os atributos e os m!todos so os membros da classe+ Al!m desses, temos ainda os construtores e os destrutores .ver seo 44+''/+

22.2.OBJETO
Objetos so inst5ncias de classes+ Um objeto ! um elemento que ter3 todas as propriedades definidas na classe, do mesmo modo como uma vari3vel i, declarada como do tipo int, possui todas as propriedades deste tipo+ 6este modo, o objeto possuir3 todos os atributos e m!todos definidos na classe+

22.3.ENCAPSULAO
7ncerrar, como em c3psula, as propriedades de um objeto+ Os componentes do objeto, atributos e m!todos, no podem ser diretamente acessados ou manipulados por outros objetos, a no ser quando isto for expressamente permitido .label de permisso public8/+

22.4.MTODO
Cada uma das fun2es membros da classe e, por conseq9:ncia, dos seus objetos+

22.5.MENSAGEM
;aneira de ativao dos m!todos do objeto e de acessar ou manipular os seus atributos, se permitido+

22.6.ABSTRAO
<uando se cria uma classe de objetos, representao de um objeto do mundo real, apenas alguns de seus elementos so implementados, tendo em vista que no ! poss=vel considerar a sua totalidade+ 6e acordo com o dicion3rio8 >Ato de separar mentalmente um ou mais elementos de uma totalidade complexa, os quais s mentalmente podem subsistir fora desta totalidade.? Assim, quando criamos uma classe clientes, implementamos nesta classe apenas alguns dos seus dados cadastrais, abstraindo@nos das outras informa2es, no necess3rias para a implementao+
'

%OA6B7&%,A+C &OB OD, 6+ malltal$ E )#8 t-e language and its implementation+ &eading8 Addison@ FesleG, '()*+ ____________________________________________________________________________ Professor Jeferson Antonio Quimelli

'#H

Algoritmos e Programao

Departamento de Informtica

22.7.CONCEITOS BSICOS - E EMPLO DE APLICAO


#include<conio.h> #include<iostream.h> class A { public: void f(); int i, j; ; void A::f() { i ! "; j ! #; main() { A $bjA; $bjA.f(); cout << $bjA.i; cout << $bjA.j; $bjA.i ! %; $bjA.j ! &; cout << '(ovo valor de i: ) << $bjA.i; cout << '(ovo valor de j: ) << $bjA.j; *etch();

Coment3rios8 '+ Cria@se a classe A, que possui dois elementos membros pIblicos8 a funo m!todo f() e os atributos i e j, ambos do tipo int+ Jsto quer di1er que o m!todo f() e os atributos i e j dos objetos da classe A podem so acess=veis em qualquer ponto do programa+ 4+ A implementao do m!todo f() ! feita fora da definio da classe .no@ inline), pela utili1ao do operador de escopo 88+ 6este modo, a lin-a void A::f() quer di1er que ali se inicia a implementao a funo f() da classe A. 6entro da classe fica apenas o protKtipo do m!todo, void f();. O que o m+todo f() fa1, ao ser ativado, ! iniciali1ar os atributos i e j com os valores 4 e ', respectivamente+ L+ Do main()! criado o objeto $bjA, inst5ncia da classe A+ 6este modo este objeto possui os atributos i e j e o m!todo f(). H+ A instruo $bjA.f(); ! mensagem que ativa o m!todo f() de $bjA+ 7ste iniciali1a os atributos i e j de $bjA com os valores 4 e '+ 7stes valores so mostrados na unidade de sa=da padro pela utili1ao da vari3vel cout, dispon=vel com o uso da biblioteca iostream+-, e com o operador MM+ *+ As instru2es $bjA.i ! %C e $bjA.j ! &C so mensagens que atribuem valores aos atributos i e j, alterando os valores iniciali1ados pelo m!todo f(). Percebe@se que o acesso direto aos atributos, como o feito neste caso, pode levar ao descontrole dos valores atuais destes atributos, contrariando o paradigma dos objetos que ! exatamente proteger estes atributos de altera2es acidentais ou no desejadas, permitindo acesso a eles somente pelo m!todo do objeto+ N+ Os novos valores dos atributos so exibidos, com o uso da vari3vel cout .l:@se c@out/+ ____________________________________________________________________________ Professor Jeferson Antonio Quimelli '#*

Algoritmos e Programao

Departamento de Informtica

Dote que como os m!todos e os atributos da classe foram criadas dentro do label de permisso public, elas podem ser acessadas ou manipuladas por qualquer funo externa ao objeto+

22.!.LABELS DE PERMISSO
7xistem tr:s labels de permissso, private, public e protected, que indicam o n=vel de permisso de acesso que tem os membros declarados dentro deles+ Os membros public podem ser acessados de qualquer funo ou objeto, de onde a classe e o objeto so vis=veis+ Os membros protected podem ser acessados somente atrav!s dos membros de objetos da mesma classe, de classes declaradas friend .amigas/ e tamb!m de membros de objetos de classes derivadas .ver Oerana/+ Os membros private so acess=veis comente por membros de objetos da mesma classe ou por membros de objetos de classes friend+ Peja o exemplo '8
#include<conio.h> #include<iostream.h> class , { public: void f#(); int i#; private: void f"(); int i"; ; void ,::f#() { i" ! -; f"(); i#!#; void ,::f"() { i# ! -; i" ! -; f#(); main() { , .#; .#.i# ! -; .#.f#(); // .#.i" ! -; // .#.f"(); // cout << .#.i#; cout << .#.i"; *etch();

se compiladas, estas duas linhas *erar0o erro. i" e f"() s0o private, somente acess1veis por f#() o mesmo erro ocorrer2 com esta linha

Deste exemplo, cria@se o objeto .# que, por conseq9:ncia passa a possuir os m!todos f#() e f"() e os atributos
int i# e i".

____________________________________________________________________________ Professor Jeferson Antonio Quimelli

'#N

Algoritmos e Programao

Departamento de Informtica

A funo void f"() e o atributo int i" so private, portanto somente acess=veis pelo m!todo f#()+ Qentativa de acesso por outro modo gerar3 erro em tempo de compilao+ 7xemplo 48
#include <iostream.h> class 34etan*ulo { int base, altura; public: void define5valores (int,int); int area (void) {return (base6altura); ; void 34etan*ulo::define5valores (int a, int b) { base ! a; altura ! b; int main () { 34etan*ulo 4et; 4et.define5valores (%,7); cout << 8area: 8 << 4et.area();

Coment3rios8 '+ Os atributos base e altura so considerados private, porque esta ! a permisso padro que os membros de uma classe recebem+ 4+ A classe possui dois m!todos public, as fun2es void define5valores e int area (void). L+ Como o cKdigo da funo m!todo int area (void) ! implementado na prKpria definio da classe, esta ! dita inline, ou >em lin-a? .Jsto significa que o compilador seguir3 a ordem natural das lin-as do cKdigo e no precisar3 procurar a implementao do m!todo mais , frente/+ H+ A funo main() cria o objeto 4et, inst5ncia da classe 34etan*ulo+ *+ Os dois m!todos do objeto so ativados atrav!s das mensagens no main(). Qarefa proposta '8 &efa1er o exemplo anterior, criando dois objetos de ret5ngulos, 4et# e 4et".

22.".DE#INIO DE CLASSES COM A PALA$RA STRUCT


A linguagem C00 estendeu para a palavra@c-ave struct de C a mesma funcionalidade da palavra@c-ave class de C00, exceto pelo fato de que seus membros so public por padro ao inv!s de serem private+ 6e qualquer maneira, devido ao fato de class e struct terem quase a mesma funcionalidade em C00, struct geralmente ! usado para estruturas somente com dados e class para classes que possuem procedimentos e fun2es membro+

22.1%.SOBRECARGA
____________________________________________________________________________ Professor Jeferson Antonio Quimelli '#"

Algoritmos e Programao

Departamento de Informtica

7m OO, sobrecarga ! o ato de declarar dois elementos com o mesmo nome+ Podemos ter sobrecarga de fun2es, de m!todos e at! de operadores+ Do caso das fun2es .incluindo fun2es@membro/, isto ocorre quando duas ou mais fun2es so definidas com o mesmo nome+ Deste caso, ! exigido que eles ten-am assinaturas diferentes, ou seja, a quantidade e o tipo dos par5metros do cabeal-o das fun2es devem ser diferentes+ er3 c-amada a funo cujos par5metros .tipo e nImero/ forem iguais aos da c-amada+ 7sta determinao ! feita em tempo de compilao+
9.emplo #: #include <iostream.h> #include <conio.h> void mostra5mensa*em() { cout << 8 meu livro8 << endl; void mostra5mensa*em(char 6mensa*em) { cout << mensa*em; main() { mostra5mensa*em(8o melhor livro eh::: 8); // chama o parametro do # ; void mostra5mensa*em(); // chama o parametro do "; void *etche();

9.emplo ": #include <stdio.h> #include <stdlib.h> #include <conio.h> int .#, .", .%; void iniciali<a() { .#!."!.%!-; void iniciali<a(int valor) { .#!."!.%!valor; void mostra() { printf(8.#! =d>n8, .#); printf(8."! =d>n8),."; printf(8.%! =d>n8),.%; main() { iniciali<a(); mostra(); iniciali<a(%); mostra(); *etch();

____________________________________________________________________________ Professor Jeferson Antonio Quimelli

'#)

Algoritmos e Programao

Departamento de Informtica

22.11.CONSTRUTORES E DESTRUTORES
Como comentamos na seo 44+', Classes, al!m dos m!todos e dos atributos, as classes podem ter Construtores e 6estrutores+ o fun2es espec=ficas para criar e destruir objetos e no tem tipo nem so do tipo void+ Caso no sejam definidos na classe, no momento da criao e destruio dos objetos so ativados o construtor e o destrutor padr2es .default/+ O destrutor padro ! ativado quando o ! encerrado o escopo no qual o objeto foi criado, seja ao final do bloco .funo/ onde foi criado ou, mesmo, ao final do programa+ O construtor padro cria o objeto, com seus m!todos, por!m no iniciali1a os atributos+ Jsto pode ser um problema, caso o programa utili1e os valores dos atributos antes destes serem iniciali1ados+ O resultado ser3 um erro+ Para se criar uma funo construtora, declara@se dentro da classe uma funo com o mesmo nome da classe+ 7sta funo ser3 c-amada automaticamente quando um novo objeto da classe for criado+ Pamos agora adaptar o exemplo anterior, incluindo um construtor8
// e.emplo de classes #include <iostream.h> class 34etan*ulo { int base, altura; public: 34etan*ulo (int,int); int area (void) {return (base6altura); ; 34etan*ulo::34etan*ulo (int a, int b) { base ! a; altura ! b; int main () { 34etan*ulo 4et (%,7); 34etan*ulo 4et" (&,?); cout << 8Area de 4et: 8 << 4et.area() << endl; cout << 8Area de 4et": 8 << 4et".area() << endl; Area de Ret: 12 Area de Ret2: 30

Coment3rios8 ' E As fun2es construtoras so facilmente identific3veis porque possuem o mesmo nome da classe e no tem tipo .int, float,char/, nem mesmo especificado como void+ Jsto porque elas no retornam valor 4 E Perceba que a instanciao .criao/ dos objetos 4et e 4et" inclui a passagem dos par5metros com os quais os atributos dos objetos devem ser iniciali1ados+ L @ Do temos mais a funo m!todo define5valores, porque o construtor j3 prov: esta funcionalidade+ ____________________________________________________________________________ Professor Jeferson Antonio Quimelli '#(

Algoritmos e Programao

Departamento de Informtica

A funo destrutora ! c-amada automaticamente um objeto deixa de existir+ Jsto pode ocorrer ao final do programa, ao final do bloco onde o objeto foi criado ou quando um objeto criado dinamicamente deixa de existir+ A no ser no Iltimo caso, da destruio de um objeto din5mico, a destruio ! feita sem maiores problemas, , semel-ana das fun2es e vari3veis comuns, que deixam de existir quando o escopo onde so criados deixa de existir+ Consideraremos, portanto, em exemplo, a implementao de uma funo destrutora de objetos din5micos+ Objetos din5micos tem atribu=do a si espaos de memKria que precisam ser liberados no momento de sua destruio e a implementao de um uma funo destrutora que cuide destes detal-es ! muito Itil+ O nome da funo destrutora ! o mesmo nome da classe, precedido por um R .til/+ S semel-ana das fun2es construtoras, um destrutor no deve possuir tipo nem ser void+
// e.emplo de construtores e destrutores #include <iostream.h> class 34etan*ulo { int 6base, 6altura; public: 34etan*ulo (int,int); @34etan*ulo (); ; int area (void) {return (6base 6 6altura);

34etan*ulo::34etan*ulo (int a, int b) { base ! neA int; altura ! neA int; 6base ! a; 6altura ! b; 34etan*ulo::@34etan*ulo () { delete base; delete altura; int main () { 34etan*ulo 4et(%,7), 4et" (&,?); cout << 8Area de 4et: 8 << 4et.area() << endl; cout << 8Area de 4et": 8 << 4et".area() << endl; return -; Area de Ret: 12 Area de Ret2: 30

Coment3rios8 ' E A classe 34etan*ulo possui um construtor que cria duas vari3veis din5micas do tipo int e arma1ena seus endereos nas vari3veis ponteiro base e altura+ O valor para base e altura, recebidos atrav!s dos par5metros a e b do m!todo construtor so colocados nestas vari3veis din5micas atrav!s das vari3veis ponteiro base e altura+ 4 E O m!todo 2rea() acessa as dimens2es do ret5ngulo indiretamente, atrav!s das vari3veis ponteiro base e altura e retorna a 2rea+ L E <uando o programa ! encerrado os dois objetos ativam suas fun2es destrutoras, que por sua ve1 liberam os espaos de memKria alocados pelos construtores de 4et e 4et"+ ____________________________________________________________________________ Professor Jeferson Antonio Quimelli ''#

Algoritmos e Programao

Departamento de Informtica

22.11.1.S&'()*+(,+ -) *&./0(10&()/
Os construtores tamb!m podem ser sobrecarregados, ou seja, podem@se ter dois ou mais construtores com o mesmo nome em uma classe, desde que o nImero e tipo de par5metros @ a assinatura do cabeal-o E sejam diferentes+ Como exemplo de sobregarga de construtores, , temos o seguinte programa, cuja classe Cretangulo declara dois construtores, um que possui dois par5metros do tipo int+ e outro que no possui nen-um argumento+ 7ste Iltimo, ao ser ativado, cria os atributos base e altura, iniciali1ando@os com os valores padro * e N+ O outro construtor ir3 iniciali1ar os atributos base e altura com os valores passados como argumento+ O que ir3 determinar qual dos dois construtores ser3 ativado ! o nImero e o tipo de argumentos colocados instruo de criao do objeto .instanciao/+
// sobrecar*a de construtores de classe #include <iostream.h> class 34etan*ulo { int base, altura; public: 34etan*ulo (); 34etan*ulo (int,int); ;

// 3onstrutor B sem parametros // $utro construtor B com parCmetros

int area (void) {return (base6altura);

34etan*ulo::34etan*ulo (int a, int b) { base ! a; altura ! b; 34etan*ulo::34etan*ulo () { base ! &; altura ! ?; int main () { 34etan*ulo 4et(%,7); 34etan*ulo 4et"; cout << 8Area de 4et: 8 << 4et.area() << endl;

cout << 8Area de 4et": 8 << 4et".area() << endl; Area de Ret: 12 Area de Ret2: 30

Coment3rios8 ' @ O objeto 4et foi criado passando@se como argumentos os valores L e H+ O construtor ativado foi o primeiro, que iniciali1a os atributos base e altura com os valores passados como argumento s+ Do caso, L e H+ 4 E T3 o objeto 4et" foi declarado .instanciado/ sem nen-um argumento, e sem par:nteses+ Uoi ento iniciali1ado com o segundo construtor que no possui nen-um par5metro, que declara base e altura com os valores * e N+ L @ V importante observar que se declararmos um objeto novo e no quisermos passar argumentos para ele, nKs no inclu=mos par:nteses ./+ Ou seja, na ativao do segundo construtor, que no recebe argumentos, no se devem colocar os par:nteses+ Assim8
34etan*ulo 4et"; 34etan*ulo 4et"(); // certo // erradoD

____________________________________________________________________________ Professor Jeferson Antonio Quimelli

'''

Algoritmos e Programao

Departamento de Informtica

22.12.2ERANA
7m uma linguagem Orientada a Objetos, Oerana ! a capacidade de construir classes, ditas derivadas, que recebem, em sua definio, os elementos vis=veis definidos em outras classes, ditas classes@base+ 6este modo, a classe derivada possuir3, por -erana, antes mesmo de serem definidos seus membros prKprios, os membros vis=veis que foram definidos na classe base, como pIblicos+ A definio de uma classe derivada ! feita nos seguintes moldes8
class classe5derivada: public classe5base;

Poderiam, ainda, ser utili1ados os labels protected ou private, o que determinaria que os elementos vis=veis na classe base tornar@se@o protegidos ou privados na classe derivada+ A propriedade da -erana ! muito Itil quando temos v3rias classes com membros em comum+ Assim, para no termos que reescrever esta parte do cKdigo em cada uma das classes, cria@se uma classe base que conten-a esta parte em comum e se criam classes derivadas que -erdam este cKdigo compartil-ado+ 6este modo tem@se economia de cKdigo, facilidade de manuteno, pois as implementa2es e altera2es sero feitas somente uma ve1, em um sK lugar, que se reflete em maior garantia de qualidade+ Como exemplo, podemos estudar as classes que permitiriam criar objetos ret5ngulo e tri5ngulo+ Pemos que ambas possuem os atributos base e largura, e ambas possuem os m!todos define5valores(int, int) e 2rea( ). Como somente este Iltimo m!todo, area( ), possui implementao diferente, os outros membros compartil-ados podero compor uma classe base, c-amada 3Eoli*ono, e podero ser -erdados pelas classes 34etan*ulo e 3trian*ulo+ 6este modo, o Inico membro a ser declarado nas classes derivadas ! o m!todo 2rea().
// heranFa B classe base e classes derivadas #include <iostream.h> class 3Eoli*ono { protected: int base, altura; public: void define5valores (int a, int b) { base!a; altura!b; ; class 34etan*ulo: public 3Eoli*ono { public: int area (void) { return (base 6 altura); ; class 3Grian*ulo: public 3Eoli*ono { public: int area (void) { return (base 6 altura / "); ; int main () { 34etan*ulo 4et; 3Grian*ulo tr*l; 4et.define5valores (7,&); tr*l.define5valores (7,&); cout << 4et.area() << endl; cout << tr*l.area() << endl; return -;

2% 1% ____________________________________________________________________________ Professor Jeferson Antonio Quimelli ''4

Algoritmos e Programao O 31) 4 5)(-+-& -+ *6+//) '+/)7

Departamento de Informtica

7m princ=pio todo membro da classe base ! -erdado por uma classe derivada com exceo de8
3onstrutor e destrutor Hembro operator!() friends

7mbora o construtor e destrutor da classe base no sejam -erdados, o construtor padro .ex8 construtor sem par5metros/ e o destrutor da classe base sempre so c-amados quando um novo objeto da classe derivada ! criado ou destru=do+

22.12.1.2ERANA M8LTIPLA
7m C00 ! perfeitamente poss=vel que uma classe -erde campos e m!todos de mais de uma classe simplesmente separando as classes base diferentes com v=rgulas na declarao da classe derivada+ Por exemplo, se tiv!ssemos uma classe espec=fica para imprimir na tela . 3Iaida/ e quis!ssemos que nossas classes 34etan*ulo e 3Grian*ulo tamb!m -erdassem seus membros al!m dos de 3Eoli*ono, poder=amos ter escrito8
class 34etan*ulo: public 3Eoli*ono, public class 3Grian*ulo: public 3Eoli*ono, public 3Iaida { 3Iaida {

aqui est3 um exemplo completo8


// heranFa mJltipla #include <iostream.h> class 3Eoli*ono { protected: int base, altura; public: void define5valores (int a, int b) { base!a; altura!b; ; class 3Iaida { public: void saida (int i); ; void 3Iaida::saida (int i) { cout << i << endl; class 34etan*ulo: public 3Eoli*ono, public 3Iaida { public: int area (void) { return (base 6 altura); ; class 3Grian*ulo: public 3Eoli*ono, public 3Iaida { public: int area (void) { return (base 6 altura / "); ; int main () { 34etan*ulo 4et; 3Grian*ulo tr*l; 4et.define5valores (7,&); tr*l.define5valores (7,&);

____________________________________________________________________________ Professor Jeferson Antonio Quimelli

''L

Algoritmos e Programao
4et.saida (4et.area()); tr*l.saida (tr*l.area()); return -;

Departamento de Informtica

22.13.POLIMOR#ISMO
V a exist:ncia de fun2es com o mesmo nome em classes diferentes+ Apesar de terem o mesmo nome, elas executam tarefas peculiares a cada classe+
#include <iostream.h> #include <conio.h> class cao { public: char nomeK#-L; float tamanho; private: void imprime(); //funF0o imprime tbem ;

pode ser utili<ada nas outras classe

class *ato { public: char nomeK#-L; float tamanho; private: void imprime(); // tem a mesma funF0o da #; classe mas parametros diferentes ; void cao::imprime() { strcpM(cao::nome,nome); printf(8=s8,nome); void *ato::imprime() { strcpM(*ato::nome,nome); printf(8=s8,nome);

Coment3rios8 ' E o criadas as classes gato e cac-orro, ambas possuindo o m!todo imprime(). 4 E 7mbora ten-am o mesmo nome e assinatura, cada m!todo ! intr=nseco a cada classe .e portanto aos seus objetos/+ <uando for ativado, cada objeto ativar3 o seu m!todo espec=fico+

____________________________________________________________________________ Professor Jeferson Antonio Quimelli

''H

Algoritmos e Programao &esoluo tarefas propostas+ Qarefa proposta'8 .Altera@se somente a funo main()/
int main () { 34etan*ulo 4et#, 4et"; 4et#.define5valores (%,7); cout << 8area: 8 << 4et#.area(); 4et".define5valores (%,7); cout << 8area: 8 << 4et".area();

Departamento de Informtica

Obs8 7ste resumo de POO em C00 teve como refer:ncia b3sica o tutorial8 >B3sico de C00?, de Tuan ouli!, cujo original est3 em8 -ttp8XXYYY+cplusplus+com, cuja traduo, feita por ;3rcio Uranco, est3 dispon=vel a partir de8 -ttp8XXYYY+lin-adecodigo+com+brXArtigo+aspxZid['4N) Dele podero ser vistos alguns itens b3sicos ainda no inclu=dos neste resumo, como8 Ponteiros para classes, A palavra c-ave t-is, ;embros est3ticos, Classes friend, ;embros virtuais, Classes base abstratas+

____________________________________________________________________________ Professor Jeferson Antonio Quimelli

''*