<!--
 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 &lt; 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 &lt; 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>