introducao_funcoes.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <!--
  2. Introdução ao uso de funções em C e em Python
  3. http://saw.atp.usp.br/mod/page/view.php?id=
  4. -->
  5. <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
  6. <meta name='keywords' content='mac0122, material, professores, leonidas de oliveira brandao'>
  7. <link rel='stylesheet' type='text/css' href='css_img_js_conf/all.css'>
  8. <link rel='stylesheet' type='text/css' href='css_img_js_conf/line_introducao_programacao.css'>
  9. <script src="css_img_js_conf/defineLInE.js"></script> <!-- para referencias 'a documentos internos -->
  10. <div class="pagina">
  11. <p class="secao">O que é uma função em linguagens de programação</p>
  12. <p>
  13. A ideia básica de uma função, implementada em alguma linguagem de programação, é <i>encapsular</i> um código
  14. que poderá ser invocado/chamado por qualquer outro trecho do programa.
  15. Seu significado e uso é muito parecido com o de funções matemáticas, ou seja, existe um nome, uma definição
  16. e posterior invocação à função.
  17. </p>
  18. <p>
  19. Explicitando o paralelo com a matemática, tomemos como exemplo a função trigométrica <i>cosseno(x)</i>:
  20. deve-se definir a função (declará-la, seguindo a sintaxe correta: <tt>definir cosseno (parametro_real x): ...devolve valor;</tt>),
  21. depois pode-se <i>invocá-la</i> com parâmetros efetivos, valores específicos, como: <tt>cosseno(0)</tt> ou <tt>cosseno(0.5)</tt>.
  22. <br/>
  23. <b>Para quem deseja saber mais</b>: Esta é uma função que é impossível de ser implementada de <b>modo exato</b> em um
  24. computador digital, entretanto é viável obter boas aproximações utilizando o conceito de
  25. <a href="#" onclick="trocaPagina('introducao_eficiencia_algoritmos.html#taylor')"
  26. title="ver explicaco sobre serie de Taylor e funcao cosseno"><i>série de Taylor</i></a>.
  27. Do ponto de vista prático, a série que aproxima a função <i>cosseno</i>, para valores de <tt>x</tt> próximo à origem é:
  28. <i>(1) cos(x) = 1 - x<sup>2</sup> /2! + x<sup>4</sup> /4! - x<sup>6</sup> /6! + x<sup>8</sup> /8! + ...</i>
  29. </p>
  30. <p>
  31. Note que o <i>lado direito</i> da equação (1) é a definição da função e ela está escrita em termos
  32. do <b>parâmetro formal</b> <i>x</i>.
  33. Ao "chamarmos" a função com <b>parâmetros efetivos</b>, é sobre o valor desses parâmetros que computamos
  34. o lado direito da expressão, por exemplo, computar <i>cos(0.1)</i> ou de <i>cos(1.1)</i>.
  35. </p>
  36. <a name="porque">
  37. <p class="secao">Por que usar o conceito de função?</p>
  38. </a>
  39. <p>
  40. Assim, implementar códigos com objetivos específicos (como computar o <i>cosseno</i> de qualquer valor)
  41. apresentam três grandes vantagens:
  42. <ol>
  43. <li>
  44. Facilita o desenvolvimento (<i>desenvolvimento modular</i>): implementa-se uma <i>particular unidade</i>, um trecho menor,
  45. concentrando-se nele, até que ele esteja funcionando com alto grau de <i>confiabilidade</i>;
  46. </li>
  47. <li>
  48. Organização: o código fica melhor organizado e portanto mais fácil de manter;
  49. </li>
  50. <li>
  51. Reaproveitamento: sempre que precisar aplicar o código encapsulado em qualquer outro trecho de código
  52. (ou noutro código), pode-se utilizar aquele que já foi implementado e é <i>confiável</i>.
  53. </li>
  54. </ol>
  55. </p>
  56. <a name="aplicacao">
  57. <p class="subsubsecao">Um exemplo de aplicação do conceito de função: conseguir deduzir algitmos complexos</p>
  58. </a>
  59. <!--
  60. aplicando o princípio do <em>passo da indução finita</em>
  61. -->
  62. <p>
  63. Uma aplicação interessante das 3 vantagens acima citadas é possibilitar <b>quebrar</b> o problema, tentar perceber alguma estrutura
  64. do problema que permita quebrá-lo em tarefas menores (e mais simples!).
  65. Eesta abordagem é conhecida em Matemática como a técnica <b style="color:#0000aa;">dividir para conquistar</b>.
  66. <br/>
  67. Em atividades mais sofisticadas (geralmente aquelas envolvendo laços "duplos" ou mais - i.e., "laço dentro de laço")
  68. esta abordagem pode fazer a diferença entre conseguir deduzir um solução ou não conseguir.<br/>
  69. Um exemplo básico da abordagem: deduzir um <i style="color:#0000aa;">algoritmo para ordenar um vetor</i> com <em>N</em> valores.
  70. <ol type="A">
  71. <li value=””>Podemos imaginar um laço percorrendo as <em>N</em> posições do vetor <em>V[]</em>, sequencialmente desde
  72. <em>V[0]</em> até <em>V[N-2]</em>:
  73. <ol type="a">
  74. <li value=””>Para cada posição <em>i</em> supor existir uma função que encontra e devolve o índice <em>ind_min</em>
  75. do menor valor entre <em>V[i]</em> e <em>V[N-1]</em>;
  76. </li>
  77. <li value=””>Como isso foi feito sucessivamente desde a posição <em>i=0</em>, então (por indução), temos neste momento:
  78. <em>V[0]<u>&lt;</u>V[1]<u>&lt;</u> ... V[i-1]<u>&lt;</u> V[ind_min]<u>&lt;</u></em> e
  79. <em>V[ind_min]<u>&lt;</u>V[k]</em> para todo <em>k=i, i+1, ..., N-1</em> (supondo que a função acima funcionou).<br/>
  80. Portanto, basta trocar o elemento atual da posição <em>i</em> com aquele da posição <em>ind_min</em>
  81. (que tem o menor dentre <em>V[i]</em>, <em>V[i+1]</em>, ..., <em>V[N-1]</em>.<br/>
  82. Deste modo estendemos a ordenação: <em>V[0]<u>&lt;</u>V[1]<u>&lt;</u> ... V[i-1]<u>&lt;</u> V[i]<u>&lt;</u></em>.
  83. </li>
  84. </ol>
  85. </li>
  86. </ol>
  87. Uma vez que o problema foi <b>quebrado</b> e uma parte importante dele resolvida, deve-se tentar resolver a parte que falta, o parte "a".
  88. Então pode-se tentar resolver a parte "a", deduzindo um algoritmo que encontre o índice do menor valor
  89. (<em>V[i]</em> e <em>V[N-1]</em>).
  90. Uma vez resolvida também esta parte, este código pode ser incorporado adequadamente ao item "a" para
  91. finalmente <b>conquistarmos</b> a solução completa.
  92. </p>
  93. <p>
  94. Note que, em termos práticos, o algoritmo da parte "a" pode ser implementado como função, mas também pode-se
  95. implementá-lo diretamente no código (sem função, porém neste caso resultará em um código ficará "menos organizado").
  96. <br/>
  97. Experimente!
  98. </p>
  99. <p class="secao">Introdução ao uso de funções em <i>C</i> e em <i>Python</i></p>
  100. <p>
  101. Assim, agrupar trechos com objetivos específicos e implementá-los na forma de uma <i>função</i>
  102. que ajuda bastante o desenvolvimento e a organização dos códigos em programação.
  103. </p>
  104. <p>
  105. Do ponto de vista prático, a estrutura básica de uma função em uma linguagem de programação está representada abaixo,
  106. com a <i>declaração da função</i> e sua <i>lista de parâmetros formais</i>, seguido de sua invocação
  107. (quando providenciamos os <i>parâmetro efetivos</i>).
  108. <table>
  109. <tr valign="top"><td>Declaração:</td>
  110. <td>
  111. <tt>[enventual tipo de retorno] nome_da_funcao (lista_parametros_formais)<br/>
  112. comando1<br/>
  113. ...<br/>
  114. comandoN<br/>
  115. return EXP <cyan>//# devolve o valor em EXP para quem chamou a funcao</cyan></tt></td></tr>
  116. <tr valign="top"><td>Uso:</td><td>
  117. <tt>var = nome_da_funcao(lista_parametros_efetivos)</tt></td></tr>
  118. </table>
  119. </p>
  120. <p>
  121. Atenção ao <b><tt>return</tt></b>, este é um comando especial, se ele for alcançado (e.g., ele pode estar subordinado a um comando de seleção <tt>if</tt>)
  122. então a execução da função é <b>interrompida</b>, retornando-se ao ponto imediatamente após o ponto de chamada da função.
  123. No caso do comando ter uma expressão qualquer, como indicado no exemplo <tt>return EXP</tt>, o valor de <tt>EXP</tt> é devolvido ao ponto de chamada,
  124. neste caso a chamada deve estar dentro de uma expressão (lógica ou artimética de acordo com o tipo de <tt>EXP</tt>) ou ser o lado direito de
  125. uma <i>atribuição</i>. Este último é o caso ilustrado na figura 1.
  126. </p>
  127. <p>
  128. A <i>lista de parâmetros</i> pode conter vários nomes de variáveis, geralmente, separadas por vírgula.
  129. Por exemplo, se houver necessidade de uma função que realiza vários cálculos com três variáveis pode-se usar como
  130. declaração da função algo como:
  131. <tt>nome_da_funcao (var1, var2, var3)</tt>.
  132. </p>
  133. <p class="subsubsecao">Parâmetros formais e efetivos</p>
  134. <p>
  135. De modo geral, a diferença entre os <i> parâmetros formais</i> e <i>efetivos</i> é que o primeiro corresponde ao
  136. nome da variável utilizada dentro da função, enquanto o segundo é o nome da variável que será usado para iniciar o parâmetro
  137. formal ao iniciar a execução da função.
  138. </p>
  139. <p>
  140. Assim durante a execução, ao encontrar uma chamada à função <tt>nome_da_funcao</tt>, o fluxo de execução segue
  141. a partir do código da função.
  142. Mas antes de executar a primeira linha de código da função, os valores dos <i>parâmetros efetivos</i> servem para inicializar
  143. os parâmetros formais (que são também variáveis locais à função). Após esta inicialização, inicia-se a execução do código
  144. da função e geralmente ao final, encontra-se um comando do tipo "retorne devolvendo um valor" (<i>return</i>).
  145. </p>
  146. <p class="subsubsecao">Ilustrando a execução de um trecho de programa com 3 chamadas à mesma função</p>
  147. <p>
  148. Suponhamos que precisemos computar o valor da combinação de <i>N</i> tomado <i>k</i> a <i>k</i>, ou seja,
  149. C(N,k) = N! / ( k! (N-k)!).
  150. Para isso percebe-se que é necessário implementar o cômputo de fatorial que será utilizado 3 vezes.
  151. Para facilitar a compreensão, podemos escrever um código com 3 variáveis auxiliares para armazenar, respectivamente,
  152. <i>N!</i>, <i>k!</i> e <i>(N-k)!</i>.
  153. <p>
  154. <center>
  155. <p>
  156. <img src="img/exemplo_exec_funcao.jpg" title="exemplo de execucao da funcao"/>
  157. <br/>
  158. <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>
  159. </p>
  160. </center>
  161. <p>
  162. Na figura acima ilustra a execução do código para computar <i>C(N,k)</i>, com o retângulo à esquerda contendo
  163. o código que invoca a função <i>fat</i> e à direita a função <i>fat</i>.
  164. Para entender o fluxo de execução destaremos a execução da linha 2, <tt>b = fat(k);</tt>.
  165. Como <tt>b = fat(k);</tt> é uma atribuição, primeiro computa-se o valor do <i>lado direito</i> da atribuição
  166. e só depois atribui-se à variável do <i>lado esquerdo</i> da atribuição o seu valor, ou seja,<br/>
  167. &nbsp; 1. primeiro executa-se o cômputo de <tt>fat(k)</tt>, para isso<br/>
  168. &nbsp; 2. pega-se o valor do <i>parâmetro efetivo</i> <tt>k</tt> e usa-o para iniciar o <i>parâmetro formal</i> <tt>n</tt> da função<br/>
  169. &nbsp; 3. então inicia-se a execução da função <tt>fat</tt><br/>
  170. &nbsp; 4. ao final da função <tt>fat</tt>, pega-se o valor da variável local <tt>ft</tt> e <br/>
  171. &nbsp; 5. atribui-se este valor para a variável <tt>b</tt><br/>
  172. &nbsp; 6. então segue-se execução da próxima linha (3).<br/>
  173. Vale notar que a execução da atribuição <tt>c = fat(N-k);</tt> seguirá um fluxo análogo aos 6 passos acima.
  174. </p>
  175. <p>
  176. Uma vez entendido como é executado uma chamada á função, podemos novamente comparar com o conceito usual
  177. de função matemática. Existe a declaração da função, com seu parâmetro formal
  178. <pre>
  179. fat : IN -> IN (nome 'fat', com domínio e imagem nos naturais)
  180. fat(n) = { 1, se n=0, n x fat(n-1), se n>0 }</pre>
  181. E existe o uso da função, como em
  182. <pre>
  183. C(N,k) = fat(N) / (fat(k) x fat(N-k)</pre>
  184. </p>
  185. <p class="subsubsecao">Exemplo concreto em <i>C</i> e em <i>Python</i></p>
  186. <p>
  187. Para ilustrar o uso e sintaxe de funções em <i>C</i> e em <i>Python</i>, examinemos um exemplo em que implementamos uma
  188. função para cômputo do fatorial de um natural <i>n</i>, que será o nome de seu único parâmetro formal.
  189. </p>
  190. <center><table class="tableCd">
  191. <tr><td></td><td bgcolor="8aaada"><i>C</i> <td bgcolor="8aaada"><i>Python</i></td></tr>
  192. <tr><td><table class=""><tr class="trCd" valign="top"><td><pre> 1
  193. 2
  194. 3
  195. 4
  196. 5
  197. 6
  198. 7
  199. 8
  200. 9
  201. 10
  202. 11</pre></td></tr></table></td>
  203. <td><table class=""><tr class="trCd" valign="top"><td><pre><verm>int</verm> fat (<verm>int</verm> n) { <cyan>// define funcao com 1 parametro</cyan>
  204. <verm>int</verm> ft = 1; <verm>int</verm> i=1;
  205. <azul>while</azul> (i &lt; n) {
  206. i = i + 1;
  207. ft = ft * i;
  208. }
  209. return ft;
  210. } <cyan>// chave indica final da funcao 'fat(...)'</cyan>
  211. ...
  212. <cyan>// supondo existir neste contexto variaveis: N e k</cyan>
  213. <verd>printf</verd>("Combinacao = %f\n", fat(N) / (fat(k) * fat(N-k));</pre></td></tr></table></td>
  214. <td><table class=""><tr class="trCd" valign="top"><td><pre><verm>def</verm> fat (<verm>int</verm> n) : <cyan># define funcao com 1 parametro</cyan>
  215. ft = 1; <verm>int</verm> i=1
  216. <azul>while</azul> (i &lt; n) {
  217. i = i + 1;
  218. ft = ft * i;
  219. return ft;
  220. <cyan># Final da funcao 'fat(...)' - em Python,</cyan>
  221. <cyan># basta a indentacao da proxima linha ser recuada</cyan>
  222. ...
  223. <cyan># supondo existir neste contexto variaveis: N e k</cyan>
  224. <verd>print</verd>("Combinacao = ", fat(N) / (fat(k) * fat(N-k))
  225. </pre></td></tr></table></td></tr>
  226. </table></center>
  227. <p class="subsubsecao">Variáveis locais</p>
  228. <p>
  229. Note na linha 2 do código acima que são declaradas duas novas variáveis, <i>ft</i> e <i>i</i>, dentro da fução <i>fat</i>.
  230. Isso significa que as variáveis <i>ft</i> e <i>i</i> são <b>variáveis locais</b> à função, ou seja,
  231. pode-se utilizar variáveis com os mesmos nomes em outras funções sendo que elas não terão qualquer relação.
  232. Em particular, na 11 do código em <i>C</i> ou na 9 do código em <i>Python</i>, poderia-se usar uma variável com nome <i>n</i>,
  233. <i>ft</i> ou <i>i</i> e ainda assim, está variável não teria qualquer relação com as correspondentes da função <i>fat</i>.
  234. </p>
  235. <p class="subsubsecao">Para que serve função?</p>
  236. <p>
  237. A partir do exemplo acima, para cômputo de <i>C(n,k) = n! / (k! (n-k)!)</i>,
  238. imagine como seria o código para computar a combinção se a linguagem de programação NÂO dispusesse do conceito
  239. de funções: em resumo, precisariamos repetir as linhas 2 a 5 (ou 6), que computam fatorial, três vezes.
  240. Portanto, o uso de função simplifica o código.
  241. </p>
  242. <p>
  243. Mas existe uma outra razão para usar funções, que não tão óbvia, a maior facilidade para escrever um programa.
  244. E isso se deve à vários fatores, mas principalmente à quebra de um problema maior em vários menores.
  245. Isso facilita o desenvolvimento e reduz a incidência de erros de programação.
  246. </p>
  247. <p>
  248. Por exemplo, pode-se implementar a função separadamente, testando-a até que ela fique pronta e sem erros.
  249. Assim, o código fica mais fácil de ser entendido, pois ao usar a função pode-se abstrair, o trecho fica curto (apenas a chamada à função)
  250. e pode-se concentrar em saber se o restante do código está correto.
  251. </p>
  252. <p class="autoria">
  253. <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/>
  254. <a href="http://www.ime.usp.br/~leo" target="_blank" title="seguir para a página do LInE">http://line.ime.usp.br</a>
  255. </p>
  256. <p class="rodape">
  257. <b>Alterações</b>:<br/>
  258. 2020/08/15: novo formato, pequenas revisões<br/>
  259. 2020/08/09: Sábado, 09 de Agosto 2020, 14:00<br/>
  260. 2020/04/13: Segunda, 13 Abril 2020, 12:30
  261. </p>
  262. </div>