• Nenhum resultado encontrado

PIT-AULA-15-FUNCOES-E-REVISAO

N/A
N/A
Protected

Academic year: 2021

Share "PIT-AULA-15-FUNCOES-E-REVISAO"

Copied!
90
0
0

Texto

(1)

Funções em C

e breve revisão

Aula 15

Prof. Fábio Miranda Site das aulas: https://sites.google.com/site/fabionmiranda Email/orkut: fabionmiranda@gmail.com

•Gestor, Consultor e Educador em TI há mais de 15 anos • Bacharel em Ciência da Computação •Pós-graduado em Gestão em Tecnologias da Informação

Pós-Graduado em Gestão Educacional

•Mestrando em Ciência da Computação pela UFMG •Professor aprovado PUC, COTEMIG, FAMINAS, PITÁGORAS, POLIMIG,

(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)
(14)
(15)

• Nos programas anteriores, os valores das

variáveis eram estabelecidos em operações de atribuição. Mas agora, qual é o valor de C?

(16)

• Uma outra forma de atribuir valores a variáveis é a

leitura de dados. Em C, usa-se a função scanf. • Assim como printf, a função scanf pode ter vários

parâmetros, sendo o primeiro uma string.

• No caso da função scanf, esta string deve conter apenas tags, separadas por espaços em branco. • Os demais parâmetros da função scanf devem ser

endereços de variáveis.

(17)

• O que acontece quando o computador executa uma instrução de leitura de dados? Exemplo:

• A execução do programa é interrompida. O

computador espera que o usuário digite algum valor e pressione a tecla Enter.

• Após pressionar Enter, o computador retoma a

execução do programa e armazena o(s) valor(es) digitado(s) no(s) endereço(s) fornecido(s) na

scanf(“%f”,&C);

(18)

• O que difere a leitura de dados da operação de atribuição?

– Na operação de atribuição, o valor a ser atribuído é definido antes da execução do programa, enquanto

numa operação de leitura de dados, o valor atribuído é definido durante a execução.

• Em programação, diz-se que coisas são estáticas

quando ocorrem antes do programa executar e

dinâmicas, quando ocorrem durante a execução.

C = 32;

scanf(“%f”,&C)

Valor de C é estabelecido estaticamente. Valor de C é estabelecido dinamicamente.

Leitura de dados

(19)

• Na leitura de dados, o valor digitado pelo usuário deve ser do mesmo tipo que a variável.

• Com a leitura de dados, a execução de um programa pode ser realizada para valores diferentes das variáveis.

• Porém, se o valor da variável é estabelecido de forma estática, para cada valor da variável, é necessário compilar o programa novamente.

(20)

• Dadas as idades (tipo int) e os pesos (tipo float) de duas pessoas, exibir quem é a pessoa mais velha e a sua idade e quem é a pessoa mais leve e o seu peso.

(21)
(22)

• Todo comando if requer uma condição que pode ser verdadeira ou falsa.

• Caso a condição seja verdadeira, o comando if

executa um conjunto de instruções, podendo

deixar de executar um outro conjunto alternativo. • Quando existe um conjunto de instruções a ser

executado, caso o valor da condição seja falso, utiliza-se o comando if-else.

(23)

• Exemplo:

• Um conjunto de instruções começa com o símbolo

{ e termina com o símbolo }. Caso, o conjunto contenha apenas uma instrução, as chaves são opcionais. if (delta >=0) { x1 = (-b + sqrt(delta))/(2*a); x2 = (-b – sqrt(delta))/(2*a); } else {

printf(“Sem raízes reais.”); }

(24)

• Qualquer instrução pode fazer parte de um

conjunto de instruções, inclusive um comando if

ou um comando if-else. if (delta >=0) { x1 = (-b + sqrt(delta))/(2*a); if (delta == 0) x2 = x1; else x2 = (-b – sqrt(delta))/(2*a); } else {

printf(“Sem raízes reais.”); }

Comando

if-else

Por que não foram usadas as chaves { } neste comando?

(25)

• Programas mais complexos são mais difíceis de ler e compreender.

• Uma forma de melhorar a legibilidade do programa é usar recuos.

• Os recuos devem ser usados sempre após o

símbolo {, sendo as instruções recuadas à direita. • O símbolo } deve estar alinhado ao abre-chaves

correspondente.

(26)

• Exemplo:

• De quem é o else acima?

– O compilador sempre associa um else ao “if anterior mais próximo que ainda não possui um else.”

• Como associar o else à instrução if (nota >= 9)?

if (nota >= 9)

if (nota_anterior < nota)

printf(“Você está melhorando.”); else

printf(“Sem estudo é difícil ser aprovado.”);

(27)

• Exemplo:

• Neste caso, as chaves, em vez de opcionais, serão obrigatórias, pois apenas os recuos não resolvem.

if (nota >= 9) {

if (nota_anterior < nota)

printf(“Você está melhorando.”); }

else

printf(“Sem estudo é difícil ser aprovado.”);

(28)

Funções?

• Funções também são chamados de:

– Subrotinas

– Subprogramas

– Leitura obrigatória: Capítulo 15 – Livro

“Algoritmos e Fundamentos e Praticas” do Everton Coimbra

– Fazer exercicios teóricos da pág. 375 – Trabalhem em equipe!!!!!

(29)

• Dadas as idades (tipo int) e os

pesos (tipo float) de duas pessoas, exibir quem é a pessoa mais

velha e a sua

idade e quem é a pessoa mais leve e o seu peso,

usando funções.

(30)

Problema 8

Lembrar que, quando se executa um programa, executa-se a função main.

(31)

• Observe como o programa principal tornou-se mais conciso e modularizado devido ao uso de

funções.

• Observe a função maiorValor:

int maiorValor(int idade1, int idade2) { if (idade1 > idade2) return idade1; else return idade2; }

Esta função funciona apenas para idades?

Esta função poderá ser usada sempre que for necessário

determinar o maior de dois valores inteiros.

Utilização de funções

(32)

• Assim, podemos reescrever a função maiorValor

como:

onde x e y representam valores inteiros genéricos.

• Atenção!

Os nomes dos parâmetros na definição da função não

precisam ser iguais aos nomes dos parâmetros durante o int maiorValor(int x, int y)

{ if (x > y) return x; else return y; }

Utilização de funções

(33)

• Como assim? Veja o exemplo abaixo:

• x e y: parâmetros de definição (ou formais)

• a

int a, b, maior;

maior = maiorValor(a,b);

int maiorValor(int x, int y) { if (x > y) return x; else return y; } 4 12 a b 4 12 x y No momento da chamada de maiorValor, cópias de a e b são feitas em x e y.

Utilização de funções

(34)

• Dado o valor da variável N, determine a soma dos números inteiros de 1 a N.

(35)

• Deseja-se calcular o valor de: 1 + 2 + 3 + ... + N.

• Observação: não sabemos, a priori, quantos termos serão somados, pois o valor de N é estabelecido dinamicamente.

• Para se calcular esta soma, o programa p09.c

utiliza o comando while.

– O comando while permite que um conjunto de

instruções seja executado tantas vezes quantas forem necessárias, enquanto uma condição for verdadeira.

(36)

• Quando um programa executa um conjunto de

instruções repetidas vezes, diz-se que o programa está realizando um processamento iterativo.

• Cada execução do conjunto de instruções

denomina-se uma iteração. Exemplo de uso do comando while: s = 0; i = 1; while (i <= 3) { s = s + i; i++; Instante s i (i <= 3) inicial 0 1 V 1ª Iteração 0 + 1 = 1 1 + 1 = 2 V 2ª Iteração 1 + 2 = 3 2 + 1 = 3 V

Comando

while

(37)

• A execução do programa p09.c sempre irá

terminar, pois i será maior do que N em algum momento.

• Porém, pode a execução de um programa com processamento iterativo não terminar? Observe:

s = 0; i = 0; while (i < 3) { i--; s = s + i; }

Este laço ou loop

nunca irá terminar!

(Erro de lógica) s = 0; i = 0; while (i > -3) { i--; s = s + i; } Maneira correta

Comando

while

(38)

• Atenção!

Em alguns casos, o loop infinito pode ser

desejável. Exemplo: um programa que monitora um reator nuclear deve estar sempre em

execução.

• Neste caso, pode-se escrever:

while (1) {

... }

(39)

• Outra forma de repetir um conjunto de instruções é com o comando do-while.

• Veja que no comando while, a condição é testada antes da execução das instruções, ao contrário do comando do-while. O que acontece para N=0?

s = 0; i = 1; do { s = s + i; i++; } while (i <= N); Comando do-while s = 0; i = 1; while (i <= N) { s = s + i; i++; } Comando while

Comando

do-while

(40)
(41)

• Suponha que soma (+) e subtração (-) são as únicas operações disponíveis em C. Dados dois números inteiros positivos A e B, determine o quociente e o resto da divisão de A por B.

Problema 10

(42)

A B

Algoritmos estruturados

• Para resolver o problema 10, precisamos de um

algoritmo:

Seqüência finita de instruções que, ao ser executada, chega a uma solução de um problema.

• Para escrever este algoritmo, podemos usar a seguinte idéia:

1. Representar os números A e B por retângulos de larguras proporcionais aos seus valores;

(43)

• Pode-se escrever este algoritmo como:

1. Sejam A e B os valores dados; 2. Atribuir o valor 0 ao quociente (q); 3. Enquanto B couber em A:

{

4. Somar 1 ao valor de q; 5. Subtrair B do valor de A; }

6. Atribuir o valor final de A ao resto (r).

(44)

• É conveniente representar algoritmos por meio de

fluxogramas (diagrama de blocos).

• Em um fluxograma, as operações possíveis são representadas por meio de figuras:

Figura Usada para representar

Início ou fim. Atribuição. Condição.

Leitura de dados.

Apresentação de resultados.

Conexão entre partes do algoritmo.

Fluxograma

(45)

• Exemplo: o algoritmo para o Problema 10 pode ser representado pelo seguinte fluxograma.

Atenção: observe que um algoritmo não inclui detalhes, tais como declaração de

variáveis, mensagens a serem exibidas, etc. Início A, B q = 0 B <= A r = A q, r q = q + 1 A = A - B Sim Não

Fluxograma

(46)

• Um algoritmo tem sempre um único bloco início e deve conter, pelo menos, um bloco fim. A

execução de um algoritmo deve ser feita seguindo-se as setas.

• Em geral, a construção de um algoritmo é uma tarefa mais difícil do que codificar o algoritmo em uma linguagem de programação.

• Porém, a construção de algoritmos pode se beneficiar de técnicas, como a Programação Estruturada.

(47)

• Na Programação Estruturada, os programas são construídos usando-se apenas três estruturas:

seqüência, seleção e repetição.

• Cada estrutura tem apenas um único ponto de entrada e um único ponto de saída (círculos).

...

Seqüência Seleção (duas formas)

V F

V F

Repetição (duas formas)

V F

F

V

Programação Estruturada

(48)

• Atenção!

– Nestas estruturas, os retângulos são utilizados para indicar qualquer ação, incluindo leitura de dados ou exibição de resultados.

• Construir programas estruturados corresponde a combinar estas estruturas de duas maneiras:

– Regra do empilhamento: o ponto de saída de uma estrutura pode ser conectado ao ponto de entrada de outra estrutura.

– Regra do aninhamento: um retângulo de uma estrutura pode ser substituído por uma outra estrutura qualquer.

(49)

• Estas regras podem ser aplicadas quantas vezes forem necessárias e em qualquer ordem.

• Na construção de fluxogramas, pode-se substituir o primeiro ponto de entrada e os últimos pontos de saída por ovais (início e fim).

• Os demais pontos de entrada e saída podem ser removidos.

(50)

• Exemplo: aplicação da regra de empilhamento.

• Exemplo: algoritmo do Problema 10.

Empilhamento Simplificação Fluxograma

Início Fim Aninhamento e Simplificação V F V F Início

Programação Estruturada

(51)

• Escreva um programa que permita ao usuário escolher dentre as seguintes opções:

– Exibir o conteúdo da pasta; – Modificar a hora do sistema; – Modificar a data do sistema;

– Terminar a execução do programa.

(52)
(53)

• O programa p12.c mostra diversas possibilidades de uso da função system:

Parâmetro Usado para

CLS Limpar a tela de execução.

DIR Exibir o conteúdo da pasta em uso.

TIME Exibir e permitir modificar a hora atual do sistema. DATE Exibir e permitir modificar a data atual do sistema. PAUSE Interromper a execução do programa.

(54)

• Os parâmetros possíveis para a função system

dependem do sistema operacional sob o qual os programas serão executados.

• Para o ambiente Dev-C++, os programas são executados sob o sistema operacional DOS. • Assim, os parâmetros “CLS”, “DIR”, “TIME”,

“DATE”, “PAUSE”, correspodem a comandos do

sistema DOS.

(55)

• O programa p12.c apresenta diversos comandos

if-else interrelacionados.

• Exemplo: imagine uma função que recebe como parâmetro um inteiro representando o número de um mês e retorna o número de dias deste mês (considere que fevereiro tem sempre 28 dias).

(56)
(57)

• Uma outra forma de escrever esta função, mas ainda com comandos if-else interrelacionados é:

(58)

• A demanda por comandos if-else interrelacionados

é muito comum em programação.

• Assim, a linguagem C disponibiliza um comando especial para tais situações: switch. A sintaxe

deste comando é a seguinte:

switch (expressão) { case constante-1: comandos-1; case constante-2: comandos-2; ... default: comandos-n;

Comando

switch

(59)

• Com o comando switch, a função dias_do_mes

pode ser reescrita como:

(60)

• Este comando permite que, de acordo com o valor de uma expressão, seja executado um ou mais

comandos dentre uma série de alternativas. • O caso cuja constante for igual ao valor da

expressão será selecionado para execução.

• Atenção!

– Os comandos associados a este caso e todos os

comandos seguintes serão executados em sequência até o final do comando switch.

– Para evitar a execução de todos os comandos seguintes, usa-se o comando break.

(61)

• Como assim?

Para mes = 2:

• Com o uso de break: dias = 28;

Comando

switch

Para mes = 2:

• Sem o uso de break: dias = 28;

dias = 30; dias = 0;

(62)

• Em alguns programas, durante um processamento iterativo, pode ser necessário:

– Encerrar o processamento iterativo independentemente do valor da condição do laço;

– Executar apenas parcialmente uma iteração, ou seja, executar somente algumas das instruções do laço da repetição.

• Para encerrar um processamento iterativo,

independentemente do valor da condição do laço, deve-se usar o comando break.

(63)

• Exemplo: dados os valores N (int) e A (float), determine a partir de qual termo o valor de:

é maior do que A. Suponha N = 10 e A = 2. N s ... 1 3 1 2 1 1     Instante Valor de s 10 termo 1.000000 20 termo 1.500000 30 termo 1.833333

40 termo 2.083333 A partir do quarto termo s > A.

(64)

• Um programa para resolver este problema pode ser escrito como:

• Neste caso, a condição do laço controla apenas o número de termos do somatório.

• O laço pode ser encerrado quando s > A, usando-se o comando break.

(65)

• Para executar somente algumas das instruções do

laço, mas sem encerrar a repetição: comando continue. • Exemplo: ler a idade e o peso de N pessoas e

determinar a soma dos pesos das pessoas com mais de 30 anos.

Comandos

break

e

continue

O comando continue faz com que a instrução

s = s + peso não seja executada quando idade <= 30.

Ou seja, ele volta a execução para o início do laço.

(66)

• Resultado da execução:

• Peso total = 35 + 40 + 48 + 60 + 85 = 193

(67)

• Um lojista atribui o preço de venda dos itens de sua loja com um número racional (uma fração de inteiros).

• Este comerciante precisa de uma calculadora capaz de realizar as operações de soma, subtração,

multiplicação e divisão de frações, a qual exibe o

resultado como uma fração na forma mais simplificada possível. Desenvolva um programa que implemente esta calculadora.

(68)

Análise do programa

Declaração de variáveis aqui?

(69)

• Nos programas anteriores, a função principal (main) aparecia sempre como a última função

declarada. Por quê?

• A Linguagem C exige que todos os identificadores

(nomes de variáveis e de funções) sejam

declarados antes de serem usados.

• Assim, sendo a última função declarada, a função

main pode chamar (ou usar) qualquer outra função do programa, pois as outras funções já teriam sido declaradas antes.

(70)

• Quando uma função é chamada, o compilador C verifica na declaração da função se o número e os tipos dos parâmetros estão sendo respeitados.

• Mas, e se a função principal (main) for declarada em primeiro lugar? Neste caso, o compilador C ainda

não “conhece” as declarações das demais funções. • Assim, como fazer para que main possa chamar

outras funções do programa? Como o compilador verificará a compatibilidade de tipos?

(71)

• A solução é usar protótipos de funções. Abaixo, são listados os protótipos das funções usadas pela

função main, no programa p20.c:

• O protótipo de uma função corresponde apenas ao

cabeçalho da função, seguido de ponto-e-vírgula.

...

(72)

• Observe que o programa p20.c inclui também a

função mdc e que não existe um protótipo para esta função. Por quê?

• Porque mdc é chamada apenas pela função

simplificar_fracao e a definição da função mdc

...

(73)

• Observe a declaração das variáveis a, b, c e d.

• Diferentemente do que vínhamos aprendendo, elas aparecem fora da definição de qualquer função

usada pelo programa. Qual é a repercussão disso?

...

(74)

• Na Linguagem C, as variáveis podem ser

declaradas em diversas partes de um programa. • A região dentro do programa onde o nome de uma

variável é visível (ou tem significado) é conhecida como escopo da variável.

• A Linguagem C define três categorias de escopo: – Bloco;

– Parâmetro de função; – Arquivo.

(75)

• Bloco é uma região do programa delimitada por chaves { e }.

• O exemplo comum de bloco é o corpo de uma função. Por exemplo:

Escopo de bloco

Normalmente, as variáveis são

declaradas no início do bloco.

(76)

• Uma variável com escopo de bloco é denominada

variável local ao bloco.

• Uma variável local tem visibilidade apenas dentro do bloco em que foi declarada.

• Mas, mesmo dentro do bloco, a variável local pode não ser visível, caso exista um bloco mais interno que declara uma outra variável de mesmo nome.

(77)

• Declarar variáveis no início do bloco não é

obrigatório, desde que a regra “definir antes e usar depois” seja atendida.

r pode ser usada dentro

r só pode ser usada dentro do while.

(78)

• Atenção! Para identificar uma variável, o compilador C leva em conta não apenas o nome da variável,

mas também seu escopo. Veja:

O que esta função irá exibir? O valor interno e 1 O valor externo e 100 Variáveis diferentes!

(79)

• O escopo de parâmetro de função existe na declaração de protótipos ou no cabeçalho de definição de funções.

• Variáveis declaradas em um protótipo de função têm significado apenas dentro do próprio protótipo. • Assim, no protótipo de uma função pode-se

declarar apenas os tipos dos parâmetros:

(80)

• Variáveis declaradas como parâmetros no cabeçalho de uma função são consideradas

variáveis locais à função.

Variáveis locais à função simplifica

(81)

• Variáveis declaradas fora de qualquer função do programa têm escopo de arquivo.

• Uma variável com escopo de arquivo tem

significado no restante do programa, a partir da linha em que foi declarada.

• Por isso, uma variável com escopo de arquivo é denominada variável global.

(82)

• Por exemplo, no programa p20.c, a declaração das variáveis a, b, c e d aparece no início do programa e, portanto, tais variáveis podem ser usadas em todas as funções.

...

(83)

• Atenção! A declaração de variáveis globais pode ser feita em qualquer parte do programa.

Não! A variável i só tem

(84)

• Para resolvermos este problema, basta declararmos a variável i antes da função func:

Em func: a[0] = 1

(85)

• Uma variável global também pode perder visibilidade em algumas funções, caso haja declaração de variável local de mesmo nome.

Variáveis distintas

Em func: a[2] = 3

(86)

• O uso de variáveis globais torna mais difícil a análise e compreensão do programa.

• Por quê?

Para se corrigir um erro de lógica relacionado com uma determinada variável global, é necessário

analisar todo o programa ou todo o escopo da variável global (que pode ser muito grande). • Conclusão: deve-se evitar o uso de variáveis

globais! As funções devem modificar apenas suas variáveis locais e as variáveis passadas como

parâmetros.

(87)

• Toda função define um processamento a ser realizado.

• Este processamento depende dos valores dos parâmetros da função.

• Assim, para usar uma função, um programa precisa fornecer a ela os parâmetros adequados. Exemplo:

– Para calcular o seno de 30º, escrevemos: sin(pi/6);

– Para calcular o valor absoluto de a-b, escrevemos: abs(a-b);

– Para calcular o mdc de 12 e 8, escrevemos: mdc(12,8);

(88)

• O mecanismo de informar os valores a serem

processados pela função chama-se passagem de parâmetros.

• A Linguagem C define duas categorias de passagem de parâmetros: passagem por valor e passagem por endereço (ou passagem por referência).

• Normalmente, a passagem de parâmetros a uma função é por valor.

• Mas, como os parâmetros de uma função são variáveis locais, alguns aspectos devem ser

(89)

• Considere o exemplo abaixo:

• O que este programa irá exibir?

Valores recebidos ... 1, 2 e 3 Valores alterados ... 2, 3 e 4 Valores finais ... 1, 2 e 3

Passagem por valor

(90)

• Observe que os valores das variáveis a, b e c não foram modificados na função alterar. Por quê?

• O tipo de passagem de parâmetros utilizado é por valor. Ou seja, são feitas apenas cópias dos valores das variáveis a, b, e c nas variáveis x, y e z.

1 2 a b

Escopo: função main

1 2 x

y z

Escopo: função alterar

2 3 4 x++ y++ z++ Apenas os conteúdos de x, y e z são alterados.

Referências

Documentos relacionados

A caixa de papelão pode ser descartada como lixo comum, uma vez que não existe contato direto com o produto. O Frasco plástico deve ser submetido à tríplice lavagem antes

O instrumento utilizado consistiu em três partes: (i) informação sobre o perfil do respondente, incluindo informações sobre gênero, idade e exercício de alguma

Lembre-se: você pode usar tudo o que foi visto em aula, em listas anteriores, ou mesmo qualquer questão do trabalho para responder outras questões (mesmo que você não tenha feito

3 - Todo exame andrológico apresentado à comissão de admissão será submetido à aprovação por técnico qualificado, contratado especificamente para este fim, sendo que a

Esse artigo propõe uma metodologia que, inclusa no modelo de avaliação de obras de arte especiais desenvolvido no Escritório Modelo de Engenharia Civil (EMEA) da Universidade

Para um controle efetivo dos Roedores recomenda-se antes da aplicação do produto a realização de uma inspeção minuciosa do local a ser tratado a fim de identificar

Para um controle efetivo dos Roedores recomenda-se antes da aplicação do produto a realização de uma inspeção minuciosa do local a ser tratado a fim de identificar

Para um controle efetivo dos Roedores recomenda-se antes da aplicação do produto a realização de uma inspeção minuciosa do local a ser tratado a fim de identificar