Académique Documents
Professionnel Documents
Culture Documents
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.
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( ) { }
Departamento de Informtica
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);
1) main( ) { printf (Esta e a linha numero um \n); printf (Esta e a linha numero dois); }
Departamento de Informtica
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.
Sada:
A letra a vem antes de b
Departamento de Informtica
Algoritmos e Programao
Departamento de Informtica
4) main( ) // cuidado!! Este programa gerar erro (imprimir:1717986918) { printf (O valor %d 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); }
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.
1) main( ) { printf (os alunos sao %2d \n, 350); printf (os alunos sao %4d \n, 350); printf (os alunos sao %5d \n, 350); }
Algoritmos e Programao
Departamento de Informtica
3) main( ) // especificador de formato %f, float { printf (%f %f\n, 535.45, 73745.66); printf (%16f %16f\n, 535.45, 73745.66); }
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); }
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.
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.)
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
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.
Algoritmos e Programao
Departamento de Informtica
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..
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);
Algoritmos e Programao
Departamento de Informtica
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); }
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.
Algoritmos e Programao
Departamento de Informtica
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);
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.
Departamento de Informtica
printf ( digite um valor ponto flutuante e um inteiro); scanf( %*f %d, valor); printf ( \n Valor inteiro digitado %d, valor); }
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
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 = + * / %
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(); }
Algoritmos e Programao
Departamento de Informtica
Ateno! Em C, as instrues:
a = 2000; 2000 = a;
Exemplos:
1) main( ) { float nota1, nota2, media; printf ( digite a primeira nota: ); scanf ( %f , ¬a1); printf ( digite a segunda nota: ); scanf ( %f , ¬a2); media = (nota1+nota2)/2; printf ( sua media final %f, media); }
2) main( ) { float nota1, nota2; printf ( digite as notas: ); scanf ( %f %f, ¬a1, ¬a2); printf ( sua media final %f, (nota1+nota2)/2); }
3) main( ) { int nota, conceito; printf ( entre com a nota e o conceito); scanf ( %d %d, ¬a, &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 , ÷ndo, &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
Algoritmos e Programao
Departamento de Informtica
Exemplos:
int n; n n = = n + 1; -> n + 1; -> n = 1 n = 2
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
4) n = 6; x = n-- / 2;
n = 5
6) main( ) { int num = 0; printf ( %d, num); printf ( %d, num++); printf ( %d, num); }
Sada:
0 0 1
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.
Algoritmos e Programao
Departamento de Informtica
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++;
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
Departamento de Informtica
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;
Algoritmos e Programao
Departamento de Informtica
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
Algoritmos e Programao
1) (a > 10) || (a < 100)
3) (x 4) ! (x > 0) && y)
// verdadeiro se a>10 ou se a= = -1
8) O programa: main( ) { char ch; printf ( digite uma letra entre A e Z); ch = getche( ); if ((ch >= A) && (ch < = Z)) printf ( Voc acertou) }
Precedncia: (maior) (! - ++ --), (* / %), (+ -) aritmticos, (< > <= >= <>), (== !=) relacionais, (&&), (||) lgicos, (= += -= *= /= %=) atribuio (menor)
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); } */
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.
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
Exemplo:
if (a<b) { a=b; c=2; }
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); }
exemplo:
if (a<b) a=b;
outros exemplos:
1) if (i==j) printf( I e j sao iguais);
3) main( ) { char ch; ch = getche ( ); if (ch == p) printf (voc pressionou a tecla p); }
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
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.
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;
//
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);
Algoritmos e Programao
Departamento de Informtica
APLICAO: Elaborar um algoritmo para, dados trs nmeros, determinar o menor deles.
if((a<b)&&(a<c))
Comportamento: Se condio for verdadeira, ser executada a expresso 1. Caso contrrio, ser executada a expresso 2. Exemplo 1:
Max = (num1 > num2) ? num1 : num2;
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.
Sada: 1
3 ... 1000
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.
Algoritmos e Programao
Departamento de Informtica
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.
Algoritmos e Programao
Departamento de Informtica
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); }
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...);
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(); } } }
Departamento de Informtica
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:
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); }
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);
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); }
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); }
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.
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.
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
Algoritmos e Programao
Departamento de Informtica
Exemplos:
float nota[60]; int vetor[100];
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.
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
printf(entre com a 1a. nota); scanf(%f, ¬a0); printf(entre com a 2a. nota); scanf(%f, ¬a1); printf(entre com a 3a. nota); scanf(%f, ¬a2); 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
printf(entre com a 1a. nota); scanf(%f, ¬a0); printf(entre com a 2a. nota); scanf(%f, ¬a1); . . . . . . . . . printf(entre com a 300a. nota); scanf(%f, ¬a299); 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, ¬as[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++; } }
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, ¬as[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", ¬a1[i]); printf("nota 2: "); scanf("%f", ¬a2[i]); printf("nota 3: "); scanf("%f", ¬a3[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(); }
Isto equivaleria a:
int notas[5]; for (i=0; i<5; i++) notas[I] = 0;
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};
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}
Isto , esta estrutura de leitura do tamanho do vetor no permitir a leitura de um valor alm do limite (100, no caso).
Algoritmos e Programao
Departamento de Informtica
16.6.2 APLICAO
Onde existirem dados, sendo mais clara a sua relevncia em: - Listas telefnicas; - Cadastros; - Dicionrios.
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.
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.
Algoritmos e Programao
Departamento de Informtica
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]); } }
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
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"); } }
Algoritmos e Programao
Departamento de Informtica
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"); } }
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.
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.
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.
Algoritmos e Programao
Departamento de Informtica
#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(); }
Algoritmos e Programao
Departamento de Informtica
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.
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(); }
Algoritmos e Programao
Departamento de Informtica
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
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:
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"); } }
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
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(); }
Algoritmos e Programao
Departamento de Informtica
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.
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(); }
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(); }
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(); }
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(); }
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(); }
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(); }
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)
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?
Algoritmos e Programao
Departamento de Informtica
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(); }
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; }
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.
Algoritmos e Programao
Departamento de Informtica
19 PONTEIROS
Variveis ponteiro so as que podem armazenar endereos de memria.
-+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();
&
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.
-+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();
&
6: 6:
: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
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
&
main() int contador = 7; printf (""alor inicial = %d *n", contador); muda;4alor(contador); printf (""alor final = %d *n", contador); & %etch();
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
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
+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();
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.
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
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
Algoritmos e Programao
Departamento de Informtica
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(); &
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));
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(); &
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= .
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(); &
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;
&
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.
Algoritmos e Programao
Departamento de Informtica
&
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.
Departamento de Informtica
JFJ,JeJ,JnJ,JsJ,JaJ,J%J,JeJ,JmJ&;
&
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();
&
Departamento de Informtica
&
&
Jesoluo programa K:
#include <stdio.h> #include <conio.h> 4oid mostra;cadeia(char +pcadeia) Ehile (+p K= J*(J) putchar(+p); p<<; &
& main()
&
Jesoluo programa N:
#include <stdio.h> #include <conio.h> 4oid mostra;cadeia(char +pcadeia) Ehile (+pcadeia) putchar (+pcadeia<<);
&
&
?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.
Algoritmos e Programao
Departamento de Informtica
&
main() char destinoA!60B; copia;cadeia(",adeia a ser copiada", destino); puts(destino); & %etch();
Algoritmos e Programao
Departamento de Informtica
&
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
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.
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
&
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 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.
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@&;
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>
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.
Algoritmos e Programao
Departamento de Informtica
&
Algoritmos e Programao
Departamento de Informtica
&
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);
&
Departamento de Informtica
&
main() eDemplo 4arD; eDemplo +p4; p4 = &4arD; p4I>num = 6; p4I>ch = JSJ; imprime;struct(p4);
&
&
main() eDemplo 4arD; eDemplo +p4; p4 = &4arD; p4I>num = 6; p4I>ch = JXJ; incrementa;struct(p4); printf("%d", p4I>num); printf("%c", p4I>ch);
&
Algoritmos e Programao
Departamento de Informtica
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.
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();
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 )
&
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().
&
Algoritmos e Programao
Departamento de Informtica
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.
Algoritmos e Programao
Departamento de Informtica
,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 = !(;
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.
&;
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\]];
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 [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));
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.
&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();
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.
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();
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
&
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;
&
&
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(); &
Algoritmos e Programao
Departamento de Informtica
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
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".
'#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.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();
'#)
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); ;
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
'''
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 -;
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 {
''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 ;
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+
''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+
''*