123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <!--
- Introdução à Programação - 2017 - Prof. Leoônidas de Oliveira Brandão
- Introdução ao conceito de parâmetros para funções
- LInE (Laboratory of Informatics in Education) - http://www.usp.br/line
- IME - USP
- Material didático
- Pode usar livrevemente este material para fins não comerciais, devendo sempre fazer referência à autoria.
- Sugestões/apontamento são bem vindos: leo@ime.usp.br (favor indicar no assunto "material de introducao 'a programacao")
- Prof. Leônidas de Oliveira Brandão
- http://www.ime.usp.br/~leo
- http://line.ime.usp.br
- http://www.matemtica.br
- @versao: versão inicial: 2011/06/10
- -->
- <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
- <meta name='keywords' content='mac0122, material, professores, leonidas de oliveira brandao'>
- <link rel='stylesheet' type='text/css' href='css_img_js_conf/all.css'>
- <link rel='stylesheet' type='text/css' href='css_img_js_conf/line_introducao_programacao.css'>
- <script src="css_img_js_conf/defineLInE.js"></script> <!-- para referencias 'a documentos internos -->
- <div class="pagina">
- <p class="secao">Introdução ao conceito de parâmetros para funções</p>
- <p>
- Neste texto, explicamos os princípios a respeito de passagem de parâmetros para
- <a href="#" onclick="trocaPagina('introducao_funcoes.html')" title="examinar o texto introdutório sobre funções em C e Python">funções</a>,
- particularmente diferenciando as passagens por <i>referência</i> (ou <i>endereço</i>) e por <i>valor</i>.
- </p>
- <!--
- Leia com atenção estas observações a respeito de funções e passagem de parâmetros.
- Elas referem-se ao exemplo
- <a href="exemplo_referencia_valor.c" title="clique aqui para pegar o exemplos exemplo_referencia_valor.c">exemplo_referencia_valor.c</a>.
- -->
- <p class="subsecao">Por que parâmetros são necessários para funções?</p>
- <p>
- A <b style="color:#0000aa;">passagem de parâmetros</b> é essencial para ampliar o potencial de uso de uma função.
- Uma função sem parâmetro, é apenas um procedimento que executará sempre
- <i title="exceto se o programador estiver usando variáveis globais - mas esperamos que você jamais tente fazer dessa forma, pois
- um tal código seria muito mais difícil de ser depurado)">exatamente os mesmos passos</i>.
- Por exemplo, uma função para computar o fatorial de um número natural, deve ter um único parâmetro, digamos <i>n</i>, sendo
- que <i>n</i> deve conter o valor para o qual deseja-se saber o fatorial.
- Por um lado, na declaração da função deve-se indicar de alguma forma este parâmetro, que neste caso é denominado
- <b style="color:#0000aa;">parâmetro formal</b> (por ser um <i style="color:#0000aa;">formalismo</i> necessário para funcionar o conceito).
- <br/>
- Por outro lado, o ponto do código que "está interessado" no fatorial de algum valor é quem deve invocar a função passando-lhe esse valor como
- parâmetro, que neste caso recebe o nome de <b style="color:#0000aa;">parâmetro efetivo</b> (pois é <i style="color:#0000aa;">efetivamente</i>
- o valor sobre o qual dever ser "aplicada" a função).
- </p>
- <p>
- <center>
- <img src="img/exemplo_exec_funcao.jpg" title="exemplo de execucao da funcao"/>
- <br/>
- <i>Fig. 1. Ilustração do fluxo de execução ao <b>invocar</b> uma função para computar o <b>fatorial</b> de um natural.</i>
- </center>
- </p>
- <p>
- A figura 1 ilustra o exemplo da função fatorial, o código à esquerda está interessado em computar o fatorial de <i>N</i>, de <i>k</i>
- e de <i>N-k</i>, que são os <i>parâmtros efetivos</i> para a função <i>fat</i> do exemplo.
- Do lado direito está a código da função, sua declaração (usamos o nome <i>fat</i>) e seu único <i>parâmtro formal</i>,
- que recebeu o nome <i>n</i>.
- </p>
- <p class="subsubsecao">Introdução aos parâmetros formal e efetivo</p>
- <p>
- O conceito de funções apresenta 4 palavras-chave principais, que são:
- <ul>
- <li> <b>parâmetros formais</b>: usados na declaração da função (por isso denominados formais);
- <li> <b>parâmetros efetivos</b>: usados na chamada da função (quem invoca é quem deve providenciar os parâmetros <i>efetivamente</i> utilizados);
- <li> a passagem de parâmetros pode ser
- <ul>
- <li>por valor: como "a" e "b" em <tt>void funcao (<verm>int</verm> a, float b)</tt></li>
- <li>por referência: como "a" e "b" em <tt>void funcao (<verm>int</verm> *a, float b[])</tt></li>
- </ul>
- <li> em <i>C</i>, uma função devolve apenas tipos simples (como "int", "float" e "char"), nunca um vetor!!!</li>
- </ul>
- </p>
- <p>
- Assim, no caso de passagem de <b>parâmetro por referência</b> (ou <b>por endereço</b>), como o nome indica,
- será passada uma <b>referência</b> à uma variável <i>externa</i> à função (o parâmetro efetivo).
- Desse modo, dentro da função, ao alterar o valor do parâmetro formal, quem estará sendo alterado é efetivamente à variável <i>externa</i>.
- Em <i>C</i> existe uma sintaxe especial para declarar e alterar o parâmetro por referência (usando asterisco '<tt>*</tt>' - vide exemplo abaixo).
- </p>
- <p>
- Já o uso de <b>parâmetro por valor</b> é mais simples, o parâmetro formal funciona como uma <i>variável local</i> que é <i>inicializada</i>
- com o valor do parâmetro efetivo, assim que a função em questão é invocada.
- Qualquer alteração do parâmetro formal, tem influência nula sobre o parâmetro formal associado (ou seja, uma atribuição dentro da função com
- determinado parâmetro, não provoca alteração alguma no valor da variável que foi passada para a função - parâmetro efetivo).
- </p>
- <p>
- Nos exemplos abaixo ilustramos os 4 conceitos em exemplos para <i>C</i> e para <i>Python</i>.
- <center><table style="border: 1px solid black;font-size:0.8em;">
- <tr>
- <th style="background-color:#8aaada;align:center;">C</th><th style="background-color:#8aaada;align:center;">Python</th></tr>
- <tr><td><pre style="font-size:0.8em;"><verm>int</verm> soma (<verm>int</verm> a, <verm>int</verm> b) {
- <verm>int</verm> c = a+b; <cyan>// variavel local: sem relacao com 'main.c'!</cyan>
- return a+b; <cyan>// devolve a+b</cyan>
- }
- <verm>int</verm> soma_max (<verm>int</verm> a, <verm>int</verm> b, <verm>int</verm> *max) {
- if (a < b)
- *max = b; <cyan>// altera o valor da referencia (em quem invocou soma_max)</cyan>
- else
- *max = a; <cyan>// em caso de empate tanto faz...</cyan>
- return a+b; <cyan>// devolve a+b</cyan>
- }
- <verm>int</verm> main (void) {
- <verm>int</verm> a, b, c, maximo;
- <verd>scanf</verd>("%d %d", &a, &b); <cyan>// operador '&' pega o endereco da variavel na memoria</cyan>
- c = soma_max(a,b,&maximo);
- <verd>print</verd>("Soma de %d e %d = %d = %d.\n", a, b, soma(a,b), c);
- <verd>print</verd>("O maximo e': %d\n", maximo);
- return 1;
- }</pre> </td><td><pre style="font-size:0.8em;"><verm>def</verm> soma (a, b) :
- c = a+b; <cyan># variavel local: sem relacao com 'main.c'!</cyan>
- return a+b; <cyan># devolve a+b</cyan>
- <verm>def</verm> soma_max (a, b, max) :
- if (a < b) :
- max[0] = b; <cyan># altera o valor da referencia (em quem invocou soma_max)</cyan>
- else :
- max[0] = a; <cyan># em caso de empate tanto faz...</cyan>
- return a+b; <cyan># devolve a+b</cyan>
- <verm>def</verm> main () :
- a = int(<verd>input</verd>());
- b = int(<verd>input</verd>());
- maximo = []; maximo.append(-1); <cyan># truque: usar vetor para param. por ref.</cyan>
- c = soma_max(a, b, maximo);
- <verd>print</verd>("Soma de %d e %d = %d = %d." % (a, b, soma(a,b), c));
- <verd>print</verd>("O maximo e': %d" % (maximo[0]));
- main();</pre> </td></tr>
- </table></center>
- </p>
- <p class="subsubsecao">Explicações sobre as diferenças entre parâmetros por referência e por valor</p>
- <p>
- A diferença entre passagem de parâmetro por referência ou valor, no primeiro caso é passado o endereço (ou referência) da
- variável efetivamente usada (parâmetro efetivo) e no segundo o valor da variável efetivamente usada apenas serve como valor
- inicial para o parâmetro formal (uma <i>inicialização</i>).
- </p>
- <p>
- <i><b>C</b></i>:
- No código <i>C</i> acima, o que definiu tratar-se de referência foi o uso de '*' no parâmetro formal.
- Além disso, para fazer referência ao parâmetro efetivo (a variável <tt>maximo</tt>) também foi preciso usar o '*'.
- <br/>
- Por outro, na chamada da função foi preciso passar o endereço da variável <tt>maximo</tt> e isso foi possível
- usando o operador '&'.
- <br/>
- No exemplo não aparece, mas em <i>C</i>, ao passar um vetor como parâmetro, automaticamente ele é passador por referência.
- <br/>
- <a href="#" onclick="trocaPagina('introducao_funcoes_c.html')"
- title="Para examinar detalhes de funções C em clique aqui">Para examinar mais sobre funções em <i>C</i> clique aqui</a>.
- </p>
- <p>
- <i><b>Python</b></i>:
- No código <i>Python</i> acima, o que definiu tratar-se de referência foi usar como parâmetro formal um vetor (ou lista).
- Por isso foi preciso o "truque" de definir um vetor (de nome <tt>maximo</tt>, com um único elemento) e passá-lo
- como parâmetro efetivo para a função.
- <br/>
- Assim, em <i>Python</i>, sempre que passar um vetor como parâmetro, automaticamente ele é passador por referência.
- <br/>
- <a href="#" onclick="trocaPagina('introducao_funcoes_python.html')"
- title="Para examinar detalhes de funções em Python clique aqui">Para examinar mais sobre funções em <i>Python</i> clique aqui</a>.
- </p>
- <p>
- <a href="https://www.ime.usp.br/~leo" target="_blank" title="seguir para a pagina do prof. Leônidas">Leônidas de Oliveira Brandão</a><br/>
- <a href="http://www.ime.usp.br/~leo" target="_blank" title="seguir para a página do LInE">http://line.ime.usp.br</a>
- </p>
- <p class="rodape">
- <b>Alterações</b>:<br/>
- 2020/08/20: acertos no formato<br/>
- 2020/08/10: revisão de formato e nova introdução<br/>
- 2020/08/09: Sábado, 09 de Agosto 2020, 14:00<br/>
- 2018/04/24: Terça, 24 de Abril 2018, 12:30<br/>
- 2011/06/10: inicial
- </p>
- </div>
|