<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Aulas de C</title>
	<atom:link href="https://aulasdec.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://aulasdec.wordpress.com</link>
	<description>Aprendizado continuo. Linguagem antiga e moderna</description>
	<lastBuildDate>Fri, 16 Dec 2011 17:07:05 +0000</lastBuildDate>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='aulasdec.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>https://s-ssl.wordpress.com/i/buttonw-com.png</url>
		<title>Aulas de C</title>
		<link>https://aulasdec.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="https://aulasdec.wordpress.com/osd.xml" title="Aulas de C" />
	<atom:link rel='hub' href='https://aulasdec.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Tipos de Dados Personalizados em C &#8211; Estruturas</title>
		<link>https://aulasdec.wordpress.com/2011/11/07/tipos-de-dados-personalizados-em-c-estruturas-2/</link>
		<comments>https://aulasdec.wordpress.com/2011/11/07/tipos-de-dados-personalizados-em-c-estruturas-2/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 18:55:00 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://aulasdec.wordpress.com/?p=139</guid>
		<description><![CDATA[Ol&#225;, pessoal! J&#225; faz um certo tempo que n&#227;o posto nenhuma &#8220;aula&#8221; nova, e pe&#231;o desculpas, mas pretendo terminar o &#8220;b&#225;sico&#8221; de C para o dia-a-dia ainda em 2011, se minhas atividades de servi&#231;o assim permitir. Antes de tudo, espero que voc&#234;s tenham visto as &#8220;aulas&#8221; anteriores, onde falamos de Makefiles e compila&#231;&#227;o fracionada e [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=139&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ol&aacute;, pessoal!</p>
<p style="text-align:justify;">J&aacute; faz um certo tempo que n&atilde;o posto nenhuma &#8220;aula&#8221; nova, e pe&ccedil;o desculpas, mas pretendo terminar o &#8220;b&aacute;sico&#8221; de C para o dia-a-dia ainda em 2011, se minhas atividades de servi&ccedil;o assim permitir.</p>
<p style="text-align:justify;">Antes de tudo, espero que voc&ecirc;s tenham visto as &#8220;aulas&#8221; anteriores, onde falamos de Makefiles e compila&ccedil;&atilde;o fracionada e tenham entendido direitinho tudo o que foi dito, pois esse ser&aacute; um conceito fundamental a partir de agora.</p>
<p style="text-align:justify;">Outra coisa, estou publicando <a href="https://github.com/hufflepuffbr/aulasdec" target="_blank">todos os c&oacute;digos do Aulas de C</a> em <a href="http://www.github.com/hufflepuffbr" target="_blank">meu <em>github</em></a>. Basicamente, um github &eacute; um local onde podemos armazenar remotamente c&oacute;digos fontes como <em>backup</em>. Na realidade, o github &eacute; um servidor que oferece acesso aberto e gratuito a um <a href="http://pt.wikipedia.org/wiki/Controle_de_vers%C3%A3o" target="_blank">servidor de controle de vers&otilde;es</a> de c&oacute;digo fonte remoto baseado no software <a href="http://pt.wikipedia.org/wiki/Git" target="_blank">git</a>, criado por <a href="http://pt.wikipedia.org/wiki/Linus_Torvalds" target="_blank">Linus Torvalds</a>, o mesmo criador do Linux. &Eacute; um sistema r&aacute;pido e eficiente, com a vantagem de ser distribu&iacute;do, o que permite que cada desenvolvedor trabalhe no seu c&oacute;digo sem interferir de imediato nos c&oacute;digos dos demais desenvolvedores. N&atilde;o vamos nos aprofundar nesse assunto de imediato e para os interessados, a sugest&atilde;o &eacute; ir no site <a href="http://github.com" target="_blank">github.com</a> e dar uma olhada nas instru&ccedil;&otilde;es do site, que s&atilde;o bem claras.</p>
<p style="text-align:justify;">Al&eacute;m disso, estarei divulgando arquivos .zip com os c&oacute;digos fontes das aplica&ccedil;&otilde;es para que voc&ecirc;s possam dar uma olhada nas mesmas.</p>
<p style="text-align:justify;">Bem,&nbsp; sem mais delongas, vamos falar do nosso &#8220;assunto&#8221; dessa &#8220;aula&#8221;: estruturas de dados em C.</p>
<p style="text-align:justify;"><strong>1-) O que s&atilde;o estruturas de dados?</strong></p>
<p style="text-align:justify;">Bem, voc&ecirc;s devem ter reparado que trabalhamos com tipos de dados &#8220;discretos&#8221;, como n&uacute;meros inteiros e flutuantes, caracteres, matrizes e ponteiros. Isso parece ter ficado claro at&eacute; aqui. E em geral isso &eacute; bom quando estamos aprendendo&#8230;</p>
<p style="text-align:justify;">Por&eacute;m, no &#8220;mundo real&#8221;, n&atilde;o utilizamos apenas esses tipos, e sim utilizamos dados como &#8220;informa&ccedil;&otilde;es cadastrais&#8221;, &#8220;conta banc&aacute;ria&#8221;, &#8220;informa&ccedil;&otilde;es de <em>login</em> do usu&aacute;rio&#8221;, &#8220;ficha t&eacute;cnica do filme&#8221; e etc. &Eacute; poss&iacute;vel, obviamente, utilizar-se caracterers, matrizes, ponteiros e toda uma complexa combina&ccedil;&atilde;o de tipos de dados &#8220;discretos&#8221; para criarmos nosso sistema com essas informa&ccedil;&otilde;es, mas isso cedo ou tarde ficar&aacute; confuso e sujeito a <em>bugs</em>.</p>
<p style="text-align:justify;">Para facilitar nossa vida, o C (como a grande maioria das linguagens de programa&ccedil;&atilde;o modernas) oferece mecanismos para que o desenvolvedor crie e trabalhe com seus pr&oacute;prios tipos de dados. Existem duas formas b&aacute;sicas de se fazer isso, que s&atilde;o chamadas de <em>estruturas</em> (<span style="font-family:terminal,monaco;">struct</span>) e <em>uni&otilde;es</em> (<span style="font-family:terminal,monaco;">unions</span>). Uni&otilde;es s&atilde;o um t&oacute;pico avan&ccedil;ado sobre o qual n&atilde;o falaremos aqui. Vamos ent&atilde;o falar de estruturas.</p>
<p style="text-align:justify;">As estruturas s&atilde;o formas que o C oferecem de organizarmos nossos dados. Por exemplo, imagine um <em>software</em> para o c&aacute;lculo de n&uacute;meros complexos, que possuem uma parte real e uma imagin&aacute;ria. Voc&ecirc; pode, por exemplo, ter declara&ccedil;&otilde;es como a seguinte:</p>
<blockquote><p style="text-align:justify;"><span style="font-family:courier new,courier;">int real1, imaginario1, real2, imaginario2, real3, imaginario3&#8230;.</span></p>
</blockquote>
<p style="text-align:justify;">Parece algo muito tranquilo, mas isso causa uma s&eacute;rie de problemas:</p>
<ol>
<li style="text-align:justify;">O c&oacute;digo fica complexo e pouco flex&iacute;vel: para opera&ccedil;&otilde;es individuais pode at&eacute; parecer ok, mas conforme voc&ecirc; vai trabalhando com mais e mais informa&ccedil;&otilde;es, seu programa ficar&aacute; cada vez mais complexo, com c&oacute;digo redundante e repetitivo;</li>
<li style="text-align:justify;">Voc&ecirc; ficar&aacute; &#8220;engessado&#8221;: &eacute; bem complicado trabalhar com o melhor do sistema, com recursos como uso de aloca&ccedil;&atilde;o din&acirc;mica e ponteiros para melhor aproveitar os recursos do sistema e, com isso, alcan&ccedil;ar o melhor em termos de rendimento do sistema, al&eacute;m dos problemas que voc&ecirc; ter&aacute; quando voc&ecirc; precisa trabalhar com uma quantidade arbitr&aacute;ria (n&atilde;o previamente determinada) de dados;</li>
</ol>
<p style="text-align:justify;">Uma forma mais inteligente &eacute; criar uma esp&eacute;cie de tipo de dados novo. Em teoria isso &eacute; imposs&iacute;vel, pois voc&ecirc; teria que recriar compiladores e afins, pensando de uma maneira rudimentar. Mas o C j&aacute; prev&ecirc;, em seu padr&atilde;o, a possibilidade de &#8220;extender-se&#8221; os tipos padr&otilde;es do C e do sistema e com isso criar-se tipos personalizados de dados que representem os dados que estamos trabalhando, desse modo tornando o c&oacute;digo mais l&oacute;gico e aproveitando de todos os recursos do C. O mecanismo que nos permite isso s&atilde;o as estruturas de dados. No nosso caso, criamos uma estrutura. Toda estrutura &eacute; criada com a palavra-chave <span style="font-family:terminal,monaco;">struct</span> seguida do nome da estrutura e o que comp&otilde;e essa informa&ccedil;&atilde;o dentro de chaves (<span style="font-family:terminal,monaco;">{}</span>), como se estiv&eacute;ssemos declarando vari&aacute;veis normalmente. Formalmente a <span style="font-family:terminal,monaco;">struct</span> &eacute; representada como abaixo:</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">struct [nome_da_estrutura]</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">{</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp;&nbsp;&nbsp; tipoValor1 valor1;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp;&nbsp;&nbsp; tipoValor2 valor2;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp;&nbsp;&nbsp; &#8230;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp;&nbsp;&nbsp; tipoValorN valorN;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">}</span></p>
<p style="text-align:justify;">Imaginando os n&uacute;meros complexos que falamos anteriormente, um tipo de dados que representa n&uacute;meros complexos poderia ser representada assim:</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">struct tComplexo</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">{</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp;&nbsp;&nbsp; int real;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp;&nbsp;&nbsp; int imaginario;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">};</span></p>
<p style="text-align:justify;">Perceba que colocamos o nome da estrutura como <span style="font-family:terminal,monaco;">tComplexo</span>. &Eacute; uma boa pr&aacute;tica um nome como esse, pois o C oferece um comando que permite criar um &#8220;apelido&#8221; para um tipo de dados que tornaria a coisa mais f&aacute;cil. Por&eacute;m, se voc&ecirc; nomeasse ele como, por exemplo, complexo, esse nome n&atilde;o ficaria mais dispon&iacute;vel como &#8220;apelido&#8221;.</p>
<p style="text-align:justify;">OK&#8230; Criamos nosso tipo&#8230; Mas como o usamos?</p>
<p style="text-align:justify;">Bem, primeiro de tudo, temos que declarar nossas vari&aacute;veis com nosso tipo de dados desejado. A declara&ccedil;&atilde;o &eacute; feita exatamente da mesma forma que a declara&ccedil;&atilde;o de qualquer vari&aacute;vel, com uma pequena diferen&ccedil;a, que &eacute; a presen&ccedil;a do palavra-chave struct junto com o nome do tipo, como abaixo:</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp;&nbsp;&nbsp; struct tComplexo comp1, comp2;</span></p>
<p style="text-align:justify;">Esse comando faz o mesmo que faria com um <span style="font-family:terminal,monaco;">int</span>, <span style="font-family:terminal,monaco;">float</span>, etc&#8230;</p>
<p style="text-align:justify;">E o acesso aos dados? Ele se d&aacute; por meio do operador <span style="font-family:terminal,monaco;">.</span> (ponto). Ele permite que voc&ecirc; indique ao compilador qual informa&ccedil;&atilde;o espec&iacute;fica do seu tipo de dados voc&ecirc; deseja acessar. Por exemplo, vamos criar uma r&aacute;pida fun&ccedil;&atilde;o de c&aacute;lculo de n&uacute;meros complexos, baseado nesse c&oacute;digo que mostramos. O <a href="https://github.com/hufflepuffbr/aulasdec/blob/master/rudimentarStruct.c" target="_blank">c&oacute;digo completo do exemplo</a> pode ser encontrado no meu <em>github</em>:</p>
<blockquote><p style="text-align:justify;"><span style="font-family:'courier new', courier;">struct tComplexo somaComplexo (struct tComplexo a, struct tComplexo b)</span><br />
 <span style="font-family:'courier new', courier;"> {</span><br />
 <span style="font-family:'courier new', courier;"> &nbsp; struct tComplexo soma;</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; soma.real=a.real+b.real;</span><br />
 <span style="font-family:'courier new', courier;"> &nbsp; soma.imaginario=a.imaginario+b.imaginario;</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; return soma;</span><br />
 <span style="font-family:'courier new', courier;"> }</span></p>
</blockquote>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">Uma coisa importante &eacute; que, assim como no caso das </span><em>strings</em> (lembrando que <em>strings</em> s&atilde;o matrizes/ponteiros de caracteres), as estruturas n&atilde;o podem ser manipuladas diretamente. O que a estrutura ajuda &eacute; que podemos com elas organizarmos melhor nosso c&oacute;digo e, assim, tornarmos ele mais leg&iacute;vel e,. ao mesmo tempo, termos acesso &agrave; todas as demais benesses do C para qualquer tipo de dados, inclusive aloca&ccedil;&atilde;o din&acirc;mica de mem&oacute;ria e coisas do g&ecirc;nero.</p>
<p style="text-align:justify;">Voc&ecirc; deve estar se perguntando agora: <em>&#8220;se uma estrutura personalizadas passa a ser considerada um tipo de dados dentro do meu programa, ent&atilde;o posso colocar uma estrutura dentro de outra?&#8221;</em> A resposta &eacute; SIM, voc&ecirc; pode. Depende do compilador, mas em geral os que seguem o padr&atilde;o C permitem que voc&ecirc; &#8220;aninhe&#8221; estruturas em at&eacute; 8 n&iacute;veis de intera&ccedil;&atilde;o (estrutura dentro de estrutura dentro de estrutura dentro de estrutura dentro de estrutura dentro de estrutura dentro de estrutura dentro de estrutura &#8211; pior que Duna). Alguns compiladores permitem at&eacute; mais n&iacute;veis de &#8220;abstra&ccedil;&atilde;o&#8221;, mas v&aacute; por mim, isso vai bastar para 99,999999999999999999999999999999999999% das necessidades.</p>
<p style="text-align:justify;">E como eu fa&ccedil;o para &#8220;aninhar&#8221; uma estrutura dentro de outra. &Eacute; simples. Primeiro crie a estrutura a ser &#8220;aninhada&#8221; (pegamos o exemplo abaixo do <a href="http://www.ead.cpdee.ufmg.br/cursos/C/aulas/cb10.html#cB11" target="_blank">Curso de C da UFMG</a>):</p>
<blockquote><pre>struct tipo_endereco
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char rua [50];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int numero;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char bairro [20];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char cidade [30];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char sigla_estado [3];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long int CEP;
};</pre>
</blockquote>
<p style="text-align:justify;">E em seguida a adicionamos como um campo dentro da estrutura que ir&aacute; a receber:</p>
<blockquote><pre>struct ficha_pessoal
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char nome [50];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long int telefone;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct tipo_endereco endereco;
};</pre>
</blockquote>
<p style="text-align:justify;">Perceba que voc&ecirc; continua precisando adicionar o <span style="font-family:terminal,monaco;">struct [tipo]</span> l&aacute; dentro. O acesso &agrave;s informa&ccedil;&otilde;es continua a mesma. Imagina que voc&ecirc; tem uma vari&aacute;vel struct ficha_pessoal&nbsp; de nome eu e voc&ecirc; quer definir o estado onde mora. Para isso, voc&ecirc; usa algo como:</p>
<blockquote><p style="text-align:justify;"><span style="font-family:'courier new', courier;">strcpy (eu.endereco.estado,&#8221;SP&#8221;);</span></p>
</blockquote>
<p style="text-align:justify;">No caso de um tipo num&eacute;rico, usaria-se normalmente o operador de atribui&ccedil;&atilde;o (<span style="font-family:terminal,monaco;">=</span>), sem maiores mist&eacute;rios.</p>
<p style="text-align:justify;">Uma coisa que voc&ecirc; deve estar pensando agora: <em>&#8220;e se eu usar ponteiros nos tipos de dados, e como aponto mem&oacute;ria para nosso tipo de dados?</em>&#8220;</p>
<p style="text-align:justify;">OK&#8230; A gente vai ver um programinha de agenda que vai nos ajudar&#8230; O c&oacute;digo dele est&aacute; dispon&iacute;vel no <a href="https://github.com/hufflepuffbr/aulasdec/tree/master/agenda" target="_blank">meu github</a>. Ele est&aacute; dividido em 5 arquivos: um <a href="https://github.com/hufflepuffbr/aulasdec/blob/master/agenda/Makefile" target="_blank"><em>Makefile</em>&nbsp;gen&eacute;rico</a> similar ao que vimos anteriormente, <a href="http://aulasdec.wordpress.com/2011/07/28/utilitarios-make-makefiles-e-sua-importancia/" target="_blank">na nossa &uacute;ltima aula sobre <em>makefiles</em></a>. Voc&ecirc; pode copiar o que disponibilizei no github, ou ent&atilde;o utilizar um similar ao que colocamos no final do post sobre <em>Makefiles</em>. Nesse caso, troque as refer&ecirc;ncias a <span style="font-family:'courier new', courier;">roletrando </span>por <span style="font-family:'courier new', courier;">agenda</span>.</p>
<p style="text-align:justify;">O segundo arquivo &eacute; o arquivo de cabe&ccedil;alho do nosso projeto, <span style="font-family:'courier new', courier;"><a href="https://github.com/hufflepuffbr/aulasdec/blob/master/agenda/agenda.h" target="_blank">agenda.h</a></span>:</p>
<pre style="margin-top:0;margin-bottom:0;font:normal normal normal 12px/normal 'Bitstream Vera Sans Mono', Courier, monospace;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:1.4;text-align:0;background-color:#ffffff;padding:0;">
<div id="LC1" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span class="cp" style="color:#000000;margin:0;padding:0;">#include &lt;stdio.h&gt;</span></blockquote>
</div>
<div id="LC2" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span class="cp" style="color:#000000;margin:0;padding:0;">#include &lt;stdlib.h&gt;</span></blockquote>
</div>
<div id="LC3" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span class="cp" style="color:#000000;margin:0;padding:0;">#include &lt;string.h&gt;</span></blockquote>
</div>
<div id="LC5" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#ff0000;"><span class="k" style="margin:0;padding:0;">typedef</span> <span class="k" style="margin:0;padding:0;">struct</span> <span class="n" style="margin:0;padding:0;">_agendainfo</span></span></blockquote>
</div>
<div id="LC6" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span class="p" style="color:#ff0000;margin:0;padding:0;">{</span></blockquote>
</div>
<div id="LC7" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">char</span> <span class="n" style="margin:0;padding:0;">nome</span><span class="p" style="margin:0;padding:0;">[</span><span class="mi" style="margin:0;padding:0;">80</span><span class="p" style="margin:0;padding:0;">];</span></span></blockquote>
</div>
<div id="LC8" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">char</span> <span class="n" style="margin:0;padding:0;">rua</span><span class="p" style="margin:0;padding:0;">[</span><span class="mi" style="margin:0;padding:0;">80</span><span class="p" style="margin:0;padding:0;">];</span></span></blockquote>
</div>
<div id="LC9" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">char</span> <span class="n" style="margin:0;padding:0;">cidade</span><span class="p" style="margin:0;padding:0;">[</span><span class="mi" style="margin:0;padding:0;">40</span><span class="p" style="margin:0;padding:0;">];</span></span></blockquote>
</div>
<div id="LC10" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">char</span> <span class="n" style="margin:0;padding:0;">estado</span><span class="p" style="margin:0;padding:0;">[</span><span class="mi" style="margin:0;padding:0;">40</span><span class="p" style="margin:0;padding:0;">];</span></span></blockquote>
</div>
<div id="LC11" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">char</span> <span class="n" style="margin:0;padding:0;">cep</span><span class="p" style="margin:0;padding:0;">[</span><span class="mi" style="margin:0;padding:0;">11</span><span class="p" style="margin:0;padding:0;">];</span></span></blockquote>
</div>
<div id="LC12" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">char</span> <span class="n" style="margin:0;padding:0;">datanasc</span><span class="p" style="margin:0;padding:0;">[</span><span class="mi" style="margin:0;padding:0;">11</span><span class="p" style="margin:0;padding:0;">];</span></span></blockquote>
</div>
<div id="LC13" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">char</span> <span class="n" style="margin:0;padding:0;">email</span><span class="p" style="margin:0;padding:0;">[</span><span class="mi" style="margin:0;padding:0;">100</span><span class="p" style="margin:0;padding:0;">];</span></span></blockquote>
</div>
<div id="LC14" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="kt" style="margin:0;padding:0;">int</span> <span class="n" style="margin:0;padding:0;">sexo</span><span class="p" style="margin:0;padding:0;">;</span>                            <span class="c1" style="font-style:italic;margin:0;padding:0;">// utilizaremos 0 para feminino e 1 para masculino</span></span></blockquote>
</div>
<div id="LC15" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#ff0000;"><span class="p" style="margin:0;padding:0;">}</span>  <span class="n" style="margin:0;padding:0;">agenda_info</span><span class="p" style="margin:0;padding:0;">;</span></span>
</blockquote>
<blockquote>
<span style="color:#ff0000;"><span class="p" style="margin:0;padding:0;">
</span></span></blockquote>
</div>
<div id="LC17" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span class="k" style="margin:0;padding:0;">typedef</span> <span class="k" style="margin:0;padding:0;">struct</span> <span class="n" style="margin:0;padding:0;">_agenda</span></blockquote>
</div>
<div id="LC18" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span class="p" style="margin:0;padding:0;">{</span>
</blockquote>
</div>
<div id="LC19" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;">&nbsp;&nbsp;<span class="n" style="margin:0;padding:0;">agenda_info</span> <span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">entrada;</span></span>
</blockquote>
</div>
<div id="LC20" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#003300;">&nbsp;&nbsp;<span class="k" style="margin:0;padding:0;">struct</span> <span class="n" style="margin:0;padding:0;">_agenda</span> <span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">next</span><span class="p" style="margin:0;padding:0;">;</span></span></blockquote>
</div>
<div id="LC21" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#003300;"><span class="p" style="margin:0;padding:0;">}</span> <span class="n" style="margin:0;padding:0;">agenda</span><span class="p" style="margin:0;padding:0;">;</span></span>
</blockquote>
</div>
<div id="LC23" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;"><span class="kt" style="margin:0;padding:0;">void</span> <span class="n" style="margin:0;padding:0;">creditos</span> <span class="p" style="margin:0;padding:0;">(</span><span class="kt" style="margin:0;padding:0;">void</span><span class="p" style="margin:0;padding:0;">);</span></span>
</blockquote>
</div>
<div id="LC24" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;"><span class="kt" style="margin:0;padding:0;">void</span> <span class="n" style="margin:0;padding:0;">insereItem</span><span class="p" style="margin:0;padding:0;">(</span><span class="n" style="margin:0;padding:0;">agenda</span> <span class="o" style="margin:0;padding:0;">**</span><span class="n" style="margin:0;padding:0;">head</span><span class="p" style="margin:0;padding:0;">);</span></span></blockquote>
</div>
<div id="LC25" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;"><span class="kt" style="margin:0;padding:0;">void</span> <span class="n" style="margin:0;padding:0;">listaAgenda</span><span class="p" style="margin:0;padding:0;">(</span><span class="n" style="margin:0;padding:0;">agenda</span> <span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">head</span><span class="p" style="margin:0;padding:0;">);</span></span></blockquote>
</div>
</pre>
<p style="text-align:justify;">Perceba que a nossa primeira estrutura (<span class="k" style="margin:0;padding:0;">struct</span><span style="color:#ff0000;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:16px;white-space:pre;background-color:#ffffff;"> </span><span class="n" style="margin:0;padding:0;">_agendainfo</span>) &eacute; precedida de uma palavra-chave <span style="font-family:'courier new', courier;"><strong>typedef</strong></span>. Essa palavra chave &eacute; usada para dar um apelido ao nosso tipo de dados. No nosso caso, utilizamos typedef para criar um apelido ao nosso tipo&nbsp;<span style="font-family:'courier new', courier;"><span class="k" style="margin:0;padding:0;">typedef</span><span style="color:#ff0000;font-size:12px;line-height:16px;white-space:pre;background-color:#ffffff;"> </span><span class="k" style="margin:0;padding:0;">struct</span><span style="color:#ff0000;font-size:12px;line-height:16px;white-space:pre;background-color:#ffffff;"> </span><span class="n" style="margin:0;padding:0;">_agendainfo</span></span>&nbsp;chamado&nbsp;<span class="n" style="font-family:'courier new', courier;margin:0;padding:0;">agenda_info</span>. Isso facilita muito a coisa para a legibilidade do c&oacute;digo.</p>
<p style="text-align:justify;">Veja que temos uma outra estrutura <span style="font-family:'courier new', courier;">struct _agenda</span>, que tem um apelido definido via <span style="font-family:'courier new', courier;">typedef </span>chamado <span style="font-family:'courier new', courier;color:#003300;">agenda</span>. Essa estrutura tem duas coisas interessantes: primeiro, veja que temos um ponteiro usando o apelido <span style="font-family:'courier new', courier;">agenda_info</span> da nossa <span style="font-family:'courier new', courier;">struct _agendainfo</span>.</p>
<pre style="margin-top:0;margin-bottom:0;font:normal normal normal 12px/normal 'Bitstream Vera Sans Mono', Courier, monospace;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:1.4;text-align:0;background-color:#ffffff;padding:0;">
<div id="LC19" class="line" style="margin:0;padding:0 0 0 1em;"><span style="color:#000000;">&nbsp;&nbsp;<span class="n" style="margin:0;padding:0;">agenda_info</span> <span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">entrada</span><span class="p" style="margin:0;padding:0;">;</span></span></div>
</pre>
<p style="text-align:justify;">Essa declara&ccedil;&atilde;o &eacute; equivalente a:</p>
<pre style="margin-top:0;margin-bottom:0;font:normal normal normal 12px/normal 'Bitstream Vera Sans Mono', Courier, monospace;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:1.4;text-align:0;background-color:#ffffff;padding:0;">
<div id="LC19" class="line" style="margin:0;padding:0 0 0 1em;"><span style="color:#000000;">&nbsp;&nbsp;<span class="n" style="margin:0;padding:0;">struct _agendainfo</span> <span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">entrada</span><span class="p" style="margin:0;padding:0;">;</span></span></div>
</pre>
<p style="text-align:justify;">Mas percebe-se que &eacute; mais leg&iacute;vel que a entrada acima. Essa &eacute; a grande vantagem do uso de <span style="font-family:'courier new', courier;">typedef </span>e por isso usar <span style="font-family:'courier new', courier;">typedef </span>pode ser considerado (na maioria dos casos) uma boa pr&aacute;tica.</p>
<p style="text-align:justify;">Abaixo da declara&ccedil;&atilde;o de nossa entrada de agenda, perceba que temos uma segunda declara&ccedil;&atilde;o dentro dessa estrutura:</p>
<pre style="margin-top:0;margin-bottom:0;font:normal normal normal 12px/normal 'Bitstream Vera Sans Mono', Courier, monospace;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:1.4;text-align:0;background-color:#ffffff;padding:0;">
<div id="LC20" class="line" style="margin:0;padding:0 0 0 1em;"><span style="color:#003300;">&nbsp;&nbsp;<span class="k" style="margin:0;padding:0;">struct</span> <span class="n" style="margin:0;padding:0;">_agenda</span> <span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">next</span><span class="p" style="margin:0;padding:0;">;</span></span></div>
</pre>
<p style="text-align:justify;"><em>&#8220;Quer dizer que posso ter uma declara&ccedil;&atilde;o dentro de uma estrutura para uma estrutura igual?&#8221; </em>SIM, voc&ecirc; pode! A &uacute;nica regra &eacute; que normalmente voc&ecirc; n&atilde;o pode usar um apelido (<em>alias</em>) para essa estrutura, pois nesse momento ele n&atilde;o sabe que o apelido definido representa a estrutura em quest&atilde;o&#8230; Portanto &eacute; importante tomar-se cuidado ao fazer isso&#8230;</p>
<p style="text-align:justify;">OK&#8230; O que cada estrutura dessas faz&#8230;</p>
<p style="text-align:justify;">Nossa estrutura <span style="font-family:'courier new', courier;">agenda_info</span> (vamos usar os <em>alias</em>&nbsp;para facilitar a leitura) representa os dados a serem usados na agenda para cada entrada individual. J&aacute; a nossa estrutura <span style="font-family:'courier new', courier;">agenda </span>&eacute; quem vai&nbsp;<em>realmente </em>montar a agenda. Para isso, vamos usar uma estrutura de dados.</p>
<p style="text-align:justify;"><em>&#8220;Como assim?&#8221;. </em>No caso, vamos criar uma estrutura de <em>fila</em>, onde cada item ser&aacute; lido um ap&oacute;s o outro e ter&aacute; um ponteiro para o item seguinte (<span class="k" style="margin:0;padding:0;">struct</span><span style="color:#003300;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:16px;white-space:pre;background-color:#ffffff;"> </span><span class="n" style="margin:0;padding:0;">_agenda</span><span style="text-align:0;color:#003300;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:16px;white-space:pre;background-color:#ffffff;"> </span><span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">next</span><span class="p" style="margin:0;padding:0;">;</span>) Por conven&ccedil;&atilde;o, vamos usar <span style="font-family:'courier new', courier;">null </span>nesse ponteiro quando quisermos indicar o final da lista.</p>
<p style="text-align:justify;">E qual &eacute; a id&eacute;ia? Cada item agenda ir&aacute; apontar para dois itens: a entrada de dados (<span class="n" style="margin:0;padding:0;">agenda_info</span><span style="text-align:0;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:16px;white-space:pre;background-color:#ffffff;"> </span><span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">entrada</span><span class="p" style="margin:0;padding:0;">;</span>) e o j&aacute; citado ponteiro para o pr&oacute;ximo item. Veremos no <span style="font-family:'courier new', courier;">main </span>que o sistema ter&aacute; como saber onde fica o come&ccedil;o da lista.</p>
<p style="text-align:justify;">Al&eacute;m dessas declara&ccedil;&otilde;es de dados, declaramos tr&ecirc;s fun&ccedil;&otilde;es:</p>
<pre style="margin-top:0;margin-bottom:0;font:normal normal normal 12px/normal 'Bitstream Vera Sans Mono', Courier, monospace;font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:1.4;text-align:0;background-color:#ffffff;padding:0;">
<div id="LC23" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote style="font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:1.4;"><span style="color:#000000;"><span class="kt" style="margin:0;padding:0;">void</span> <span class="n" style="margin:0;padding:0;">creditos</span> <span class="p" style="margin:0;padding:0;">(</span><span class="kt" style="margin:0;padding:0;">void</span><span class="p" style="margin:0;padding:0;">);</span></span></blockquote>
<blockquote style="font-family:'Bitstream Vera Sans Mono', 'Courier New', monospace;font-size:12px;line-height:1.4;">
<span class="kt" style="margin:0;padding:0;">void</span> <span class="n" style="margin:0;padding:0;">insereItem</span><span class="p" style="margin:0;padding:0;">(</span><span class="n" style="margin:0;padding:0;">agenda</span> <span class="o" style="margin:0;padding:0;">**</span><span class="n" style="margin:0;padding:0;">head</span><span class="p" style="margin:0;padding:0;">);</span></blockquote>
</div>
<div id="LC25" class="line" style="margin:0;padding:0 0 0 1em;">
<blockquote><span style="color:#000000;"><span class="kt" style="margin:0;padding:0;">void</span> <span class="n" style="margin:0;padding:0;">listaAgenda</span><span class="p" style="margin:0;padding:0;">(</span><span class="n" style="margin:0;padding:0;">agenda</span> <span class="o" style="margin:0;padding:0;">*</span><span class="n" style="margin:0;padding:0;">head</span><span class="p" style="margin:0;padding:0;">);</span></span></blockquote>
</div>
</pre>
<p style="text-align:justify;">A primeira &eacute; meio clara: apenas ir&aacute; exibir cr&eacute;ditos. A segunda tem uma estrutura estranha: foi declarada uma fun&ccedil;&atilde;o&nbsp;<span style="font-family:'courier new', courier;">insereItem</span>,, com um par&acirc;metro<span style="font-family:'courier new', courier;">&nbsp;<span class="n" style="margin:0;padding:0;">agenda</span><span style="font-size:12px;line-height:16px;white-space:pre;background-color:#ffffff;"> </span><span class="o" style="margin:0;padding:0;">**</span><span class="n" style="margin:0;padding:0;">head</span></span>. O que queremos dizer a&iacute;?</p>
<p style="text-align:justify;"><strong>Ponteiros de Ponteiro:</strong></p>
<p style="text-align:justify;">Voc&ecirc; deve ter percebido que usamos dois <span style="font-family:'courier new', courier;">*</span>, ou seja, dois s&iacute;mbolos de indica&ccedil;&atilde;o de endere&ccedil;o. Aqui temos uma situa&ccedil;&atilde;o bastante comum em programa&ccedil;&atilde;o C. Se voc&ecirc; lembra anteriormente, que falamos que tem como modificar o endere&ccedil;o de uma vari&aacute;vel quando a passamos por refer&ecirc;ncia. Nesse caso, utilizamos exatamente isso, um <em>ponteiro</em>&nbsp;para um <em>ponteiro</em>. Ou seja, ao inv&eacute;s de alterarmos o endere&ccedil;o que leva ao conte&uacute;do, alteramos o endere&ccedil;o que leva ao endere&ccedil;o de mem&oacute;ria onde est&aacute; o conte&uacute;do em quest&atilde;o&#8230; &Eacute; um pouco complexo isso. Por enquanto basta saber que iremos alterar o local de mem&oacute;ria de uma determinada var&iacute;avel&#8230; Isso ir&aacute; garantir que consigamos acessar corretamente o sistema.</p>
<p style="text-align:justify;">Vamos ver o <span style="font-family:'courier new', courier;"><a href="https://github.com/hufflepuffbr/aulasdec/blob/master/agenda/main.c" target="_blank">main.c</a></span> desse nosso projeto:</p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">#include &#8220;agenda.h&#8221;</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">void limpaDados (agenda *minhaAgenda);</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">int main(void)</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">{</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;"><span style="color:#ff0000;">&nbsp; agenda *minhaAgenda=NULL</span>;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; int op;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; creditos();</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; do</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; {</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Escolha uma das op&ccedil;&otilde;es abaixo para a sua agenda\n\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;1 &#8211; Inserir um novo registro\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;2 &#8211; Listar os registros inseridos\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;3 &#8211; Sair\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;4 &#8211; Cr&eacute;ditos\n\n\nEscolha sua op&ccedil;&atilde;o:&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; scanf(&#8220;%d&#8221;,&amp;op);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; while(getchar()!=&#8217;\n&#8217;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; switch(op)</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; case 1:</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;color:#ff0000;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; insereItem(&amp;minhaAgenda);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; case 2:</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; listaAgenda(minhaAgenda);</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; case 3:</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; limpaDados(minhaAgenda);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return(0);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; case 4:</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; creditos();</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; default:</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&#8220;Op&ccedil;&atilde;o inv&aacute;lida!\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; } while (op!=3);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">}</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">void creditos(void)</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">{</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; printf(&#8220;Programa de agenda simples do curso de C livre do Aulas de C\n\n\n\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; printf(&#8220;Autor&#8230;: F&aacute;bio Emilio Costa &lt;fabiocosta0305@gmail.com&gt;\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; printf(&#8220;Licen&ccedil;a.: GPL 2\n\n&#8221;);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">}</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">void limpaDados (agenda *minhaAgenda)</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">{</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; agenda *next,*now;</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; next=minhaAgenda;</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; while(next!=NULL)</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; {</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; now=next;</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; next=next-&gt;next;</span></p>
<p style="text-align:justify;">&nbsp;</p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; free(now-&gt;entrada);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; free(now);</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; }</span></p>
<p style="text-align:justify;"><span style="font-family:'courier new', courier;">}</span></p>
<div style="text-align:justify;">Nenhum mist&eacute;rio nesse <span style="font-family:'courier new', courier;">main.c</span>: usamos nosso cabe&ccedil;alho personalizado <span style="font-family:'courier new', courier;">agenda.h</span> para importar todos os cabe&ccedil;alhos que precisamos e tamb&eacute;m trazer os tipos <span style="font-family:'courier new', courier;">agenda</span> e <span style="font-family:'courier new', courier;">agenda_info</span> que usaremos no nosso c&oacute;digo. Perceba que marcamos em vermelho a declara&ccedil;&atilde;o de nossa agenda (na vari&aacute;vel <span style="color:#ff0000;font-family:'courier new', courier;">minhaAgenda</span>) e em seguida, passamos o endere&ccedil;o aonde est&aacute; essa informa&ccedil;&atilde;o com o comando&nbsp;<span style="color:#ff0000;font-family:'courier new', courier;">insereItem(&amp;minhaAgend</span><span style="color:#ff0000;font-family:'courier new', courier;">a</span><span style="color:#ff0000;font-family:'courier new', courier;">)</span>. Perceba que utilizamos o operador de de-referenciamento (<span style="font-family:'courier new', courier;color:#ff0000;">&amp;</span>) para obtermos o <em>endere&ccedil;o</em>&nbsp;onde o C ir&aacute; guardar o endere&ccedil;o para o ponteiro da nossa estrutura da agenda. Isso permitir&aacute; que possamos alterar o conte&uacute;do desse ponteiro dentro da nossa fun&ccedil;&atilde;o. O resto do c&oacute;digo n&atilde;o tem muito mist&eacute;rio, e em geral n&atilde;o deve ser de maior complexidade se voc&ecirc; estudou corretamente nosso &#8220;curso&#8221; at&eacute; aqui e tamb&eacute;m fez com calma todos os exemplos que j&aacute; mostramos.</div>
<div>OK&#8230; E como &eacute; feita a inser&ccedil;&atilde;o dos dados? Para isso, utilizamos os c&oacute;digos de nosso arquivo <a href="https://github.com/hufflepuffbr/aulasdec/blob/master/agenda/insert.c" target="_blank">insert.c</a>:</div>
<div>
<blockquote>
<div><span style="font-family:'courier new', courier;">#include &#8220;agenda.h&#8221;</span></div>
<div><span style="font-family:'courier new', courier;">void limpandoDados(agenda_info *dados)</span></div>
<div><span style="font-family:'courier new', courier;">{</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; memset(dados-&gt;nome,&#8221;,sizeof(dados-&gt;nome));</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; memset(dados-&gt;rua,&#8221;,sizeof(dados-&gt;rua));</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; memset(dados-&gt;cidade,&#8221;,sizeof(dados-&gt;cidade));</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; memset(dados-&gt;estado,&#8221;,sizeof(dados-&gt;estado));</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; memset(dados-&gt;cep,&#8221;,sizeof(dados-&gt;cep));</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; memset(dados-&gt;datanasc,&#8221;,sizeof(dados-&gt;datanasc));</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; memset(dados-&gt;email,&#8221;,sizeof(dados-&gt;email));</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; dados-&gt;sexo=0;</span></div>
<div><span style="font-family:'courier new', courier;">}</span></div>
<div><span style="font-family:'courier new', courier;">void insereItem (agenda **head)</span></div>
<div><span style="font-family:'courier new', courier;">{</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; agenda_info *dados=(agenda_info*)malloc(sizeof(agenda_info));</span></div>
<div><span style="font-family:'courier new', courier;color:#ff0000;">&nbsp; agenda *entrada=(agenda*)malloc(sizeof(agenda)), *hook;</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; char sexo=&#8217;M';</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; if ((!entrada) || (!dados))</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; exit(1);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; limpandoDados(dados);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Digite o nome da pessoa, ou ent&atilde;o FIM se entrou por engano: \n&#8221;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; fgets(dados-&gt;nome,sizeof(dados-&gt;nome),stdin);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; if(strncmp(dados-&gt;nome,&#8221;FIM&#8221;,strlen(&#8220;FIM&#8221;))==0)</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; {</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; free(dados);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; return;</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; }</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Digite a rua onde essa pessoa mora: &#8220;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; fgets(dados-&gt;rua,sizeof(dados-&gt;rua),stdin);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Digite a cidade onde essa pessoa mora: &#8220;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; fgets(dados-&gt;cidade,sizeof(dados-&gt;cidade),stdin);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Digite o estado onde essa pessoa mora: &#8220;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; fgets(dados-&gt;estado,sizeof(dados-&gt;estado),stdin);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Digite o cep onde essa pessoa mora: &#8220;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; fgets(dados-&gt;cep,sizeof(dados-&gt;cep),stdin);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Digite o email dessa pessoa: &#8220;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; fgets(dados-&gt;email,sizeof(dados-&gt;email),stdin);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Digite a data de nascimento dessa pessoa: &#8220;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; fgets(dados-&gt;datanasc,sizeof(dados-&gt;datanasc),stdin);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; do</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; {</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Digite o sexo [M/F]: &#8220;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; scanf(&#8220;%c&#8221;,&amp;sexo);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; getchar();</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; sexo=((sexo&gt;=&#8217;a')&amp;&amp;(sexo&lt;=&#8217;z'))?sexo+&#8217;A'-&#8217;a':sexo;</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;%c\n&#8221;,sexo);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; if (sexo!=&#8217;M'&amp;&amp;sexo!=&#8217;F') printf (&#8220;sexo inv&aacute;lido\n&#8221;);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; } while (sexo!=&#8217;M'&amp;&amp;sexo!=&#8217;F');</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; dados-&gt;sexo=(sexo==&#8217;F')?0:1;</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; /**</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp;* &nbsp;Checa se j&aacute; existem itens dentro da agenda</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp;*/</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; if (!*head)</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; {</span></div>
<div><span style="color:#993366;"><span style="font-family:'courier new', courier;"><br />
 </span></span></div>
<div><span style="color:#993366;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; *head=entrada;</span></span></div>
<div><span style="color:#993366;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; (*head)-&gt;next=NULL;</span></span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; }</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; else</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; {</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; &nbsp; hook=*head;</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; &nbsp; while (hook-&gt;next!=NULL) hook=hook-&gt;next;</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; &nbsp; hook-&gt;next=entrada;</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; }</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; entrada-&gt;entrada=dados;</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; return;</span></div>
<div><span style="font-family:'courier new', courier;">}</span></div>
</blockquote>
</div>
<div>Perceba que aqui temos alguns segredos que ir&atilde;o nos ajudar a montar nossa lista de dados:</div>
<div style="text-align:justify;">Primeiro, perceba que alocamos mem&oacute;ria para uma entrada de dados de agenda, na vari&aacute;vel <span style="font-family:'courier new', courier;">dados</span>, e uma entrada para a agenda, chamada <span style="font-family:'courier new', courier;">entrada</span>, al&eacute;m de declararmos uma terceira vari&aacute;vel de agenda, chamada <span style="font-family:'courier new', courier;">hook</span> (<em>gancho</em>, em ingl&ecirc;s). Essa vari&aacute;vel ir&aacute; ser usada para fazer uma &#8220;corrida&#8221; para achar o final da agenda e colocar nela os dados necess&aacute;rios. O preenchimento de dados n&atilde;o possui grandes mist&eacute;riosd, exceto que utilizamos, ao inv&eacute;s do operador <span style="font-family:'courier new', courier;">.</span> (ponto), utilizamos o operador <span style="font-family:'courier new', courier;">-&gt;</span> (que chamaremos de operador <em>seta</em>, e &eacute; composto por um hifen e um sinal de maior). Tamb&eacute;m n&atilde;o precisamos usar o <span style="font-family:'courier new', courier;">*</span> para indicar que voc&ecirc; quer alterar a informa&ccedil;&atilde;o apontada, como em,&nbsp;<span style="font-family:'courier new', courier;">dados-&gt;rua</span>. Lemos essa entrada como &#8220;<em>o elemento <span style="font-family:'courier new', courier;">rua</span> da estrutura apontada por <span style="font-family:'courier new', courier;">dados</span></em>&#8220;. O resto &eacute; como j&aacute; vimos anteriormente. Usamos uma fun&ccedil;&atilde;o utilit&aacute;ria para inicializar corretamente a estrutura como se deve. Agora, vamos falar sobre o c&oacute;digo abaixo&#8230;&nbsp;</div>
<div>
<blockquote>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; if (!*head)</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; {</span></div>
<div><span style="color:#993366;"><span style="font-family:'courier new', courier;"><br />
 </span></span></div>
<div><span style="color:#993366;"><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; *head=entrada;</span></span></div>
<div><span style="color:#993366;font-family:'courier new', courier;">&nbsp; &nbsp; }</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; else</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; {</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; &nbsp; hook=*head;</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; &nbsp; while (hook-&gt;next!=NULL) hook=hook-&gt;next;</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; &nbsp; hook-&gt;next=entrada;</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; &nbsp; }</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">&nbsp; entrada-&gt;entrada=dados;</span></div>
<div><span style="font-family:'courier new', courier;color:#993366;">
<div style="color:#000000;font-family:Helvetica, Arial, sans-serif;"><span style="color:#993366;"><span style="font-family:'courier new', courier;">&nbsp; entrada-&gt;next=NULL;</span></span></div>
<div><span style="color:#993366;"><span style="font-family:'courier new', courier;"><br />
</span></span></div>
<p></span></div>
</blockquote>
</div>
<p style="text-align:justify;">&Eacute; esse c&oacute;digo que faz toda a parte da inser&ccedil;&atilde;o de dados. Perceba que testamos para ver se o valor apontado pelo endere&ccedil;o obtido no in&iacute;cio da fun&ccedil;&atilde;o e passado pelo <span style="font-family:'courier new', courier;">main()</span> &eacute; NULL (<span style="color:#993366;font-family:'courier new', courier;">if (!*head)</span>): isso ir&aacute; ocorrer apenas uma vez, logo no in&iacute;cio do programa. Quando isso acontecer, ele ir&aacute; pegar e substituir o endere&ccedil;o apontado por <span style="font-family:'courier new', courier;">*head</span>, pelo endere&ccedil;o entrada. Caso contr&aacute;rio, ele ir&aacute; utilizar o seguinte procedimento para &#8220;correr&#8221; a lista at&eacute; o fim:</p>
<ol>
<li>Usando a vari&aacute;vel <span style="font-family:'courier new', courier;">hook</span>, ir&aacute; armazenar a vari&aacute;vel o endere&ccedil;o apontado por <span style="font-family:'courier new', courier;">*head</span>;</li>
<li style="text-align:justify;">Em seguida, ir&aacute; associar o endere&ccedil;o do pr&oacute;ximo item apontado na vari&aacute;vel <span style="font-family:'courier new', courier;">hook</span> (o item em quest&atilde;o) &agrave; pr&oacute;pria vari&aacute;vel <span style="font-family:'courier new', courier;">hook</span>, at&eacute; alcan&ccedil;ar &uacute;ltimo item (aquele cujo next for NULL).&nbsp;Lembre-se desse procedimento: veremos ele novamente mais adiante;</li>
</ol>
<p style="text-align:justify;">Agora que sabemos onde a fila termina, adicionamos no novo item &agrave; fila, modificando o <span style="font-family:'courier new', courier;">next</span> do item apontado em <span style="font-family:'courier new', courier;">hook</span> pelo endere&ccedil;o de <span style="font-family:'courier new', courier;">entrada</span>, com isso &#8220;amarrando&#8221; essa entrada &agrave; lista.</p>
<p style="text-align:justify;">Ap&oacute;s ambos os caso, associamos os dados entrados ao valor de <span style="font-family:'courier new', courier;">entrada</span> o endere&ccedil;o de nossa estrutura, e definimos <span style="font-family:'courier new', courier;">next</span> como NULL, o que indicar&aacute; que esse &eacute; o &uacute;ltimo item (n&atilde;o faremos organiza&ccedil;&atilde;o das entradas para facilitar).</p>
<p style="text-align:justify;">E como funcionar&aacute; a visualiza&ccedil;&atilde;o desses itens?</p>
<p style="text-align:justify;">Bem, vamos ver o c&oacute;digo de exibi&ccedil;&atilde;o dos dados:</p>
<p style="text-align:justify;">
<p><span style="font-family:'courier new', courier;">#include &#8220;agenda.h&#8221;</span></p>
<p>&nbsp;</p>
<p><span style="font-family:'courier new', courier;">void listaAgenda(agenda *head)</span></p>
<p><span style="font-family:'courier new', courier;">{</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; agenda *item;</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; agenda_info *registro;</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; int counter=0;</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; item=head;</span></p>
<p>&nbsp;</p>
<p><span style="font-family:'courier new', courier;">&nbsp; while (item!=NULL)</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; {</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; registro=item-&gt;entrada;</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; counter++;</span></p>
<p>&nbsp;</p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Registro no. %d\n\n&#8221;,counter);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Nome&#8230;..: %s\n&#8221;,registro-&gt;nome);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Endereco.: %s\n&#8221;,registro-&gt;rua);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Cidade&#8230;: %s\n&#8221;,registro-&gt;cidade);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Estado&#8230;: %s\n&#8221;,registro-&gt;estado);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;CEP&#8230;&#8230;: %s\n&#8221;,registro-&gt;cep);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;DataNasc.: %s\n&#8221;,registro-&gt;datanasc);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Email&#8230;.: %s\n&#8221;,registro-&gt;email);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Sexo&#8230;..: %c\n&#8221;,(registro-&gt;sexo==0)?&#8217;F':&#8217;M');</span></p>
<p>&nbsp;</p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; printf(&#8220;Pressione qualquer tecla para continuar!\n&#8221;); while(!getchar());</span></p>
<p>&nbsp;</p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; item=item-&gt;next;</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; &nbsp; }&nbsp;</span></p>
<p>&nbsp;</p>
<p><span style="font-family:'courier new', courier;">&nbsp; printf(&#8220;Exibidos %d registros\n&#8221;, counter);</span></p>
<p><span style="font-family:'courier new', courier;">&nbsp; return;</span></p>
<p><span style="font-family:'courier new', courier;">}</span></p>
<div>&Eacute; bem simples&#8230; Lembra da &#8220;corrida&#8221; que fazemos na entrada de dados? Basicamente fazemos exatamente a mesma coisa: seguimos o seguinte procedimento at&eacute; acharmos o &uacute;ltimo item da nossa lista:</div>
<div>
<ol>
<li>Armazenamos em <span style="font-family:'courier new', courier;">registro</span> o ponteiro para os dados que iremos exibir;</li>
<li>Exibimos os dados utilizando <span style="font-family:'courier new', courier;">printf</span> (como de costume);</li>
<li>E associamos o ponteiro <span style="font-family:'courier new', courier;">next</span> e atribu&iacute;mos a ela o valor de <span style="font-family:'courier new', courier;">item</span>;</li>
</ol>
</div>
<div>Esse procedimento ir&aacute; se repetir at&eacute; que o valor de <span style="font-family:'courier new', courier;">item</span> seja NULL&#8230;</div>
<div>Antes de encerrarmos, vamos falar de uma rotina importante que &eacute; uma boa pr&aacute;tica no desenvolvimento de qualquer sistema com aloca&ccedil;&atilde;o din&acirc;mica de mem&oacute;ria, mas especialmente em programas como nosso, onde usamos intensivamente esse procedirmento. Esse procedimento ocorre no nosso programa apenas no encerramento do mesmo. Observe o seguinte c&oacute;digo em&nbsp;<span style="font-family:'courier new', courier;">main.c</span>:</div>
<div>
<blockquote>
<div><span style="font-family:'courier new', courier;">void limpaDados (agenda *minhaAgenda)</span></div>
<div><span style="font-family:'courier new', courier;">{</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; agenda *next,*now;</span></div>
<div></div>
<div><span style="font-family:'courier new', courier;">&nbsp; next=minhaAgenda;</span></div>
<div></div>
<div><span style="font-family:'courier new', courier;">&nbsp; while(next!=NULL)</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; {</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; now=next;</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; next=next-&gt;next;</span></div>
<div></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; free(now-&gt;entrada);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; &nbsp; free(now);</span></div>
<div><span style="font-family:'courier new', courier;">&nbsp; &nbsp; }</span></div>
<div><span style="font-family:'courier new', courier;">}</span></div>
</blockquote>
</div>
<div>Essa fun&ccedil;&atilde;o &eacute; chamada apenas no final do programa Note que ele segue a mesma id&eacute;ia de sempre quando falamos na fila, portanto guarde esse procedimento na mente:</div>
<div>
<ol>
<li>Ele atribui o valor de <span style="font-family:'courier new', courier;">next</span> para um ponteiro tempor&aacute;rio <span style="font-family:'courier new', courier;">now</span> (importante fazer isso para que n&atilde;o haja erros de l&oacute;gica onde o sistema &#8220;pire&#8221;).</li>
<li>Em seguida, como vamos usar apenas o ponteiro <span style="font-family:'courier new', courier;">now</span> na libera&ccedil;&atilde;o de mem&oacute;ria, podemos passar &nbsp;para <span style="font-family:'courier new', courier;">next</span> o valor do pr&oacute;ximo item (<span style="font-family:'courier new', courier;">next</span>);</li>
<li>Ap&oacute;s isso, liberamos primeiro os dados (com&nbsp;<span style="font-family:'courier new', courier;">free(now-&gt;entrada)</span>) e em seguida, liberamos a entrada (<span style="font-family:'courier new', courier;">free(now)</span>);</li>
<li>E ent&atilde;o repetimos o processo, enquanto o <span style="font-family:'courier new', courier;">next</span> n&atilde;o for NULL;</li>
</ol>
</div>
<div>&Eacute; uma boa pr&aacute;tica desalocar toda a mem&oacute;ria usada durante o uso do programa. A maioria dos sistemas operacionais modernos conseguem detectar a mem&oacute;ria usada pelo programa (incluse do <em>heap</em>, onde &eacute; armazenada toda a informa&ccedil;&atilde;o alocada dinamicamente) e elimin&aacute;-la, principalmente porque em geral cada programa recebe uma determinada quantidade de mem&oacute;ria no momento em que ele executar. Ainda assim, existe a possibilidade de mem&oacute;ria alocada n&atilde;o ser liberada no momento do encerramento do programa, formando o que se chama de <em>memory leakage</em>&nbsp;(vazamento de mem&oacute;ria), pois para o SO essa mem&oacute;ria ainda est&aacute; alocada, s&oacute; n&atilde;o sabendo-se por quem. Ao desalocar <em>explicitamente</em>&nbsp;a mem&oacute;ria, voc&ecirc; diminiu e muito a chance de um <em>memory leakage</em>. Lermbre-se sempre dessa m&aacute;xima em C:</div>
<div style="text-align:center;"><span style="font-size:large;"><strong><em>&#8220;Aloque ao entrar e desaloque ao sair&#8221;</em></strong></span></div>
<div>Com essa m&aacute;xima, terminamos nossa &#8220;aula&#8221;. Guarde esse c&oacute;digo, pois o usaremos em nossa pr&oacute;xima aula, onde falaremos de arquivos em disco.</div>
<div>Como brincadeiras, sugiro:</div>
<div>
<ol>
<li>Se voc&ecirc; reparar, n&atilde;o removemos o ENTER na entrada dos dados. Tente criar uma fun&ccedil;&atilde;o que remova os terminadores &#8216;<span style="font-family:'courier new', courier;">\ n</span>&#8216; das entradas de dados;</li>
<li>Quando falamos que n&atilde;o ir&iacute;amos organizar os dados, h&aacute; um jeito: lembre-se que voc&ecirc; pode apontar informa&ccedil;&otilde;es de ponteiros e estrururas dentro de outras estruturas. Tente criar um c&oacute;digo que permita que voc&ecirc; &#8220;ordene&#8221; os dados armazenados. Procure informa&ccedil;&otilde;es sobre a fun&ccedil;&atilde;o <span style="font-family:'courier new', courier;">strcomp</span> para algumas id&eacute;ias;</li>
</ol>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/139/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=139&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2011/11/07/tipos-de-dados-personalizados-em-c-estruturas-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
		<item>
		<title>Utilitários Make, Makefiles e sua importância</title>
		<link>https://aulasdec.wordpress.com/2011/07/28/utilitarios-make-makefiles-e-sua-importancia/</link>
		<comments>https://aulasdec.wordpress.com/2011/07/28/utilitarios-make-makefiles-e-sua-importancia/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 19:47:30 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Boas Práticas]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[GNU Compiler Chain]]></category>
		<category><![CDATA[Intermediário]]></category>
		<category><![CDATA[Introdução]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[Makefiles]]></category>
		<category><![CDATA[Projetos]]></category>
		<category><![CDATA[Técnicas]]></category>

		<guid isPermaLink="false">http://aulasdec.wordpress.com/2011/07/28/utilitarios-make-makefiles-e-sua-importancia/</guid>
		<description><![CDATA[OK&#8230;Então continuaremos sem programar C real. Essa é a má notícia da &#8220;aula&#8221; de hoje. A boa é que terminaremos o tópico que começamos na &#8220;aula&#8221; passada, quando falamos sobre o conceito de projeto, separação de códigos fonte e compilação individual.Como vimos, é possível dividir um programa em arquivos fontes individuais (que formam, em conjunto, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=135&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>OK&#8230;<br />Então continuaremos sem programar C real. Essa é a má notícia da &#8220;aula&#8221; de hoje.
<div align="justify">A boa é que terminaremos o <a target="_blank" href="http://aulasdec.wordpress.com/2011/07/09/sobre-arquivos-de-codigo-fonte-arquivos-de-cabecalhos-e-projetos/">tópico que começamos na &#8220;aula&#8221; passada,</a> quando falamos sobre o conceito de projeto, separação de códigos fonte e compilação individual.<br />Como vimos, é possível dividir um programa em arquivos fontes individuais (que formam, em conjunto, um <i>projeto</i>) e compilar os mesmos individualmente, de modo que no caso de uma modificação pontual não seja necessário recompilar totalmente os fontes para obter-se o executável. Isso deve-se ao fato de os compiladores modernos na verdade executarem duas funções simultaneamente: a <i>compilação</i> (transformação de códigos fontes em códigos objetos) e a <i>linkedição</i> ou <i>ligação</i> (a união de vários códigos objetos em binários que possam ser executados pela máquina).<br />Até aqui nenhuma novidade.<br />Mas lembremos novamente do que mostramos na aula passada. Programas &#8220;reais&#8221;, como pacotes Office e navegadores possuem milhões de linhas de código, que, por sua vez, podem estar espalhadas em milhares de arquivos de código fonte. Mesmo com essa divisão, a tarefa de gerar um novo código-objeto para cada fonte alterado e ligar todos os objetos em um executável seria MUITO enfadonha e propensa a erros.<br />Para resolver esse problema, antigamente usavam-se <i>scripts</i> específicos para cada plataforma de desenvolvimento e uso. Porém, isso ainda assim era ineficiente, pois a adição ou remoção de novos arquivos e a mudança na estrutura do projeto demandava a total modificação dos <i>scripts</i>, sendo que os próprios <i>scripts</i> tinham que ser mantidos, e eram enfadonhos de se manter.<br />Em 1977, porém, <a target="_blank" href="http://en.wikipedia.org/wiki/Stuart_Feldman">Stuart Feldman</a> criou o primeiro sistema de automação para a compilação de programas, o <a target="_blank" href="http://en.wikipedia.org/wiki/Make_%28software%29"><font face="monospace">make</font></a>. A função do <font face="monospace">make</font> é, construir todas as dependências descritas em um arquivo especial chamado <font face="monospace">Makefile</font>. Makefiles seguem um padrão razoavelmente simples de construção. Embora o formato Makefile original seja um &#8220;padrão <i>de facto</i>&#8220;, muitos compiladores trazem consigo o seu próprio make, e IDEs, como a Code::Blocks, o Eclipse e o Netbeans também possuem suas próprias regras e mecanismos, usando ou não e baseado ou não no make UNIX.<br />Para explicarmos o conceito geral e demonstrarmos o funcionamento, utilizaremos o GNU Make. GNU Make é parte dos utilitários incluídos no GCC (<i>GNU Compiler Chain</i>), que é incluído em quase todas as distribuições Linux e está disponível em várias plataformas, como Windows, MacOS/X, etc&#8230;<br />
<h3>Um Makefile simples:</h3>
<p>Sem muitas delongas, vamos mostrar como o Make trabalha e como criar um Makefile:<br />Basicamente, make funciona em um sistema de <i>alvos</i> e <i>dependências</i>. Ou seja, <font face="monospace">make</font> precisa saber quais são os arquivos que ele irá processar (dependências) para realizar alguma tarefa e obter alguma outra coisa (alvo). Por exemplo, vamos fazer um Makefile simples.<br />
<blockquote><b><font color="#990000" face="monospace">all:</font><br /><font color="#663366" face="monospace"> &nbsp;&nbsp;&nbsp; echo &#8220;Hello, Make!&#8221;</font></b></p></blockquote>
<p>Aqui dizemos que queremos obter &#8220;<i>all</i>&#8220;, ou seja, tudo (é o <i>default</i> do GNU Make. Se não encontrado, executa o primeiro alvo de cima para baixo dentro do Makefile). Depois dos dois-pontos (<font face="monospace">:</font>) indicaríamos qualquer dependência que precisássemos. Porém, como não temos nenhuma, deixamos em branco mesmo.<br />Em seguida, colocamos a tarefa a ser executada. Ela pode ser quaisquer seqüências de comandos válidos para o sistema operacional em questão. No nosso caso, utilizamos um comando <b><font color="#663366" face="monospace">echo &#8220;Hello, Make!&#8221;</font></b>, que é usado no Linux para emitir uma mensagem na tela (no Windows também funciona). Uma coisa importante: os comandos da tarefa devem ser espaçados do início da linha por uma tabulação (tecla TAB). Embora algumas ferramentas <font face="monospace">make</font> modernas consiga reconhecer espaços no lugar do TAB para efeito de indicação da tarefa, é melhor manter o padrão para não incorrer em problemas em outras plataformas.<br />Bem, digitado esse arquivo, salve-o com o nome de <font face="monospace">Makefile</font>. Esse nome é o nome <i>default</i> que o GNU <font face="monospace">make</font> (e a maioria dos demais) irá procurar. Em várias ferramentas make, é possível que você defina, por meio de uma opção de linha de comando, qual o Makefile a ser usado. Consulte o manual de sua ferramenta <font face="monospace">Make</font> para maiores informações.<br />Bem, voltando: uma vez salvo o mesmo (no momento não interessa onde você irá o jogar), digite o comando &#8220;<font face="monospace">make</font>&#8221; na linha de comandos de seu sistema operacional, no diretório onde você salvou o seu arquivo Makefile. A saída resultante será algo mais ou menos como a seguinte:<br />
<blockquote><font face="monospace">$ make</font><br /><font face="monospace">echo &#8220;Hello, Make!&#8221;</font><br /><font face="monospace">Hello, Make!</font></p></blockquote>
<p>Não muito útil, mas já mostra resultados. Uma vez que você disparou o comando, ele procurou um alvo-padrão (<font face="monospace">all</font>) e verificou se suas dependências estavam resolvidas (no momento nenhuma, então ok). Estando tudo OK, ele executou a tarefa determinada (no caso, o comando <b><font color="#663366" face="monospace">echo &#8220;Hello, Make!&#8221;</font></b>) e se encerrou.<br />Exemplo bobo&#8230;<br />
<h3>Um Makefile útil</h3>
<p>Bem, pelo menos sabemos como ele funciona. Agora vamos fazer algo realmente útil:<br />Vá ao diretório onde você guardou o seu projeto do Roletrando que mostramos na <a target="_blank" href="http://aulasdec.wordpress.com/2011/07/09/sobre-arquivos-de-codigo-fonte-arquivos-de-cabecalhos-e-projetos/">&#8220;aula&#8221; passada</a>. Vamos criar um Makefile um pouco mais interessante:<font face="monospace"><br /></font><br />
<blockquote><font color="#990000" face="monospace"><b>#</b></font><font color="#990000"><br /></font><font color="#990000" face="monospace"><b># Primeira tentativa de Makefile</b></font><font color="#990000"><br /></font><font color="#990000" face="monospace"><b>#</b></font></p>
<p><font color="#006600" face="monospace"><b>all: roletrando</b></font><br /><font face="monospace"><b>&nbsp;&nbsp;&nbsp; </b></font><br /><font color="#663366" face="monospace"><b>roletrando: main.o regras.o letras.o</b></font><font color="#663366"><br /></font><font color="#663366" face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o roletrando main.o regras.o letras.o</b></font></p>
<p><font face="monospace"><b>main.o: main.c roletrando.h</b></font><br /><font face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o main.o -c main.c </b></font></p>
<p><font face="monospace"><b>regras.o: regras.c roletrando.h</b></font><br /><font face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o regras.o -c regras.c </b></font></p>
<p><font face="monospace"><b>letras.o: letras.c roletrando.h</b></font><br /><font face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o letras.o -c letras.</b>c </font></p></blockquote>
</div>
<div align="justify">Agora temos um Makefile realmente útil. Primeira coisa que você deve ter notado é que, de certa forma, colocamos todos os comandos que usaríamos em uma compilação parcial normal, como vimos anteriormente:<br />
<blockquote><a href="http://aulasdec.wordpress.com/2011/07/09/sobre-arquivos-de-codigo-fonte-arquivos-de-cabecalhos-e-projetos/">Sobre arquivos de código-fonte, arquivos de cabeçalhos e projetos « Aulas de C</a><br />
<blockquote>No nosso caso, utilizaremos primeiro os comandos:<br /> <br />
<blockquote><font face="monospace">gcc -o letras.o -c letras.c</font><br /><font face="monospace">    gcc -o regras.o -c regras.c</font><br /><font face="monospace">    gcc -o main.o -c main.c</font></p></blockquote>
<p>Para gerarmos os arquivos .o (os códigos-objeto) de cada um dos código-fonte e, após isso, utilizaremos o comando:<br />
<blockquote><font face="monospace">    gcc -o roletrando letras.o regras.o main.o</font></p></blockquote>
<p>Para fazermos o link das funções e obtermos o executável. </p></blockquote>
</blockquote>
</div>
<p>Agora, precisamos entender o que estamos fazendo.<br />As primeiras linhas de nosso Makefile:<br />
<blockquote><font color="#990000" face="monospace"><b>#</b></font><font color="#990000"></font><br /><font color="#990000"></font><font color="#990000" face="monospace"><b># Primeira tentativa de Makefile</b></font><font color="#990000"></font><br /><font color="#990000"></font><font color="#990000" face="monospace"><b>#</b></font></p></blockquote>
<div align="justify">São apenas comentários. No caso do <font face="monospace">make</font>, os comentários utilizam o símbolo sustenido, ou <i>sharp</i>, ou qualquer outro nome que você já ouviu falar (vale até <i>lasanha</i>&#8230; <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ). Como no C e em qualquer outra linguagem ou ferramenta, os comentários são simplesmente ignorados.</div>
<p>A linha seguinte:<br />
<blockquote><font color="#006600" face="monospace"><b>all: roletrando</b></font></p></blockquote>
<p>Indica que, para o make atingir o alvo <font face="monospace">all</font>, ele tem como <i>dependência</i> que executar o alvo <font face="monospace">roletrando</font>. Importante notar que, no <font face="monospace">make</font>, uma dependência pode ser quaisquer arquivos E outros alvos. Isso é importante e veremos abaixo o por que.
<div align="justify">Outra coisa: repare que esse alvo não possui tarefas. O que fizemos aqui é criar uma espécie de alvo &#8220;nulo&#8221;, ou <i>phony</i>. Simplesmente fizemos isso para &#8220;chamar a atenção&#8221; do make para cá. Normalmente ele executa o primeiro alvo de cima para baixo dentro do Makefile por padrão se ele não encontrar um alvo <font face="monospace">all</font>. Em alguns casos, porém, você pode querer que o <font face="monospace">make</font> gere vários alvos ao mesmo tempo (por exemplo, se você desenvolver um sistema composto por vários programas). Nesse caso, basta listar outros alvos como dependências em <font face="monospace">all</font>.<br />Seguindo adiante, vemos uma entrada &#8220;completa&#8221; de um alvo (chamado também de <i>regra</i>):<br />
<blockquote><font color="#663366" face="monospace"><b>roletrando: main.o regras.o letras.o</b></font><font color="#663366"></font><br /><font color="#663366"></font><font color="#663366" face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o roletrando main.o regras.o letras.o</b></font></p></blockquote>
</div>
<div align="justify">Uma regra é composta pelo nome da regra (o alvo), uma ou mais dependências, e comandos que permita ao sistema obter essa dependência. O <font face="monospace">make</font> precisa dessa informação para fazer suas tarefas. No caso acima:
<ul>
<li>O nome da regra (alvo) é <font color="#663366" face="monospace"><b>roletrando</b></font>;</li>
<li>As dependências são <font color="#663366" face="monospace"><b>main.o regras.o letras.o</b></font>;</li>
<li>O comando a ser executado é <font color="#663366" face="monospace"><b>gcc -o roletrando main.o regras.o letras.o</b></font>;</li>
</ul>
<p>Perceba como a coisa está construída: quando usamos várias dependências, elas são separadas por espaço. Além disso, normalmente o nome da regra (ou alvo) é o nome do arquivo final a ser obtido por aquela regra (no nosso caso, o binário <font face="monospace">roletrando</font>). O comando (ou comandos) devem seguir após a linha com a descrição do alvo e das dependências. Uma regra é separada da outra por uma linha em branco.<br />OK&#8230; Aqui vemos que o <font face="monospace">make</font> sabe que, para obter o arquivo <font face="monospace">roletrando</font>, ele precisa ter as dependência (ou seja, os arquivos) <font face="monospace">main.o</font>, <font face="monospace">regras.o</font> e <font face="monospace">letras.o</font>. Além disso, ele sabe que, tendo esses arquivos, ele precisará executar o comando&nbsp;<font color="#663366" face="monospace"><b>gcc -o roletrando main.o regras.o letras.o</b></font> para obter o seu alvo e, portanto, cumprir a regra.<br />Mas até aqui, o Makefile não sabe como obter nenhuma das dependências em questão.<br />Para isso, incluímos as linhas seguintes:<br />
<blockquote><font face="monospace"><b>main.o: main.c roletrando.h</b></font><br /><font face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o main.o -c main.c </b></font></p>
<p><font face="monospace"><b>regras.o: regras.c roletrando.h</b></font><br /><font face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o regras.o -c regras.c </b></font></p>
<p><font face="monospace"><b>letras.o: letras.c roletrando.h</b></font><br /><font face="monospace"><b>&nbsp;&nbsp;&nbsp; gcc -o letras.o -c letras.</b>c </font></p></blockquote>
<p>Aqui, vemos que colocamos as diversas regras para gerar cada um dos arquivos <font face="monospace">.o</font> (objetos) necessários como dependência em <font face="monospace">roletrando</font>. Perceba que as dependências são os nomes dos arquivos de fonte <font face="monospace">.c</font> e (no nosso caso), o arquivo de cabeçalho <font face="monospace">roletrando.h</font>. Isso visa garantir que o arquivo de cabeçalho exista e, no caso de ele ser modificado (por exemplo devido a uma função modificada) o código seja reconstruído de maneira adequada. Claramente isso vai depender de como funciona seu código fonte: haverá situações onde adicionar muitos arquivos fonte ou cabeçalhos gerará inconvenientes (como compilações desnecessárias). Mas isso não vem ao caso agora.<br />O <font face="monospace">make</font> checará se (1) os arquivos indicados nas dependências existem ou se (2) eles são <i>alvos</i> resolvidos por outras regras. Se ambas as coisas não forem possíveis, ele irá dar uma mensagem de erro como a seguinte (No caso, renomeei o <font face="monospace">roletrando.h</font>, exigido por <font face="monospace">main.o</font>, para outro nome qualquer):<br />
<blockquote><font face="monospace">make: *** Sem regra para processar o alvo `roletrando.h&#8217;, necessário por `main.o&#8217;.&nbsp; Pare.</font></p></blockquote>
</div>
<div align="justify">Estando tudo OK, ao rodar-se o comando <font face="monospace">make</font> (por via das dúvidas, antes apague todos os arquivos <font face="monospace">.o</font> e o arquivo <font face="monospace">roletrando</font>), ele irá mostrar algo como abaixo:</div>
<blockquote><p><font face="monospace">$ make</font><br /><font face="monospace">gcc -o main.o -c main.c</font><br /><font face="monospace">gcc -o regras.o -c regras.c</font><br /><font face="monospace">gcc -o letras.o -c letras.c</font><br /><font face="monospace">gcc -o roletrando main.o regras.o letras.o</font></p></blockquote>
<p>Vamos descrever o que aconteceu:
<div align="justify">
<ol>
<li><font face="monospace">make</font> foi executado, procurou a regra <i>default</i> <font face="monospace">all</font> e a encontrou. Viu que ela demandava um alvo chamado <font face="monospace">roletrando</font>. Então foi para a regra <font face="monospace">roletrando</font>;</li>
<li>Em <font face="monospace">roletrando</font>, ele viu que precisava dos arquivos (ou <i>alvos</i>) <font face="monospace">main.o</font>, <font face="monospace">regras.o</font> e <font face="monospace">letras.o</font>. Antes de fazer qualquer coisa, ele irá verificar se ele tem uma regra que explique como obter esses arquivos.</li>
<li>O make percebe que existe uma regra para <font face="monospace">main.o</font>. Ela demanda os arquivos <font face="monospace">main.c </font>e <font face="monospace">roletrando.h</font>. Verificando que os dois existem, ele verifica se o arquivo indicado no alvo existe e é mais novo que os arquivos de dependência (o que indica que nenhum deles foi alterado). Caso contrário, ele irá executar as regras para obter-se uma nova versão do arquivo <font face="monospace">main.o</font> (ou obtê-lo, caso não exista).</li>
<li>Se houver alguma falha (por exemplo, um erro de sintaxe), o <font face="monospace">make</font> irá abortar sua execução, não gerando nenhum binário e não criando o <font face="monospace">roletrando</font>.</li>
<li>Em caso de sucesso no passo 3 para <font face="monospace">main.o</font>, o sistema repetirá o processo dos passos 3 e 4 para os demais arquivos de dependência <font face="monospace">regras.o</font> e <font face="monospace">letras.o</font>. Se algum deles exigisse um outro arquivo gerado por um outro alvo, os passos 3 e 4 seriam repetidos para tal arquivo e assim sucessivamente. <font face="monospace">make</font> realiza uma pesquisa recursiva para ver se cada alvo necessáriao como dependência de cada outro alvo (incluindo <font face="monospace">all</font>) foi obtido com sucesso.</li>
<li>O passo 5 tendo sido realizado com sucesso para TODOS os alvos e suas dependências (incluindo outros alvos), o <font face="monospace">make</font> irá executar os comandos indicados na regra roletrando para obter o arquivo <font face="monospace">roletrando</font>, resolvendo a dependência <font face="monospace">all</font>;</li>
<li>Resolvida todas as dependências de <font face="monospace">all</font> (<font face="monospace">roletrando</font> e suas dependências), <font face="monospace">make</font> irá se encerrar com sucesso;</li>
</ol>
</div>
<div align="justify">Agora, após rodar <font face="monospace">make</font>, você terá o arquivo <font face="monospace">roletrando</font>. Se tentar rodar make novamente, verá que ele não fará absolutamente NADA, pois ele sabe que nenhuma das dependências de <font face="monospace">roletrando</font> foi modificada (nehum dos <font face="monospace">.o</font>), pois todas existem e são mais atuais que qualquer modificação em quaisquer um dos arquivos <font face="monospace">.c</font>.<br />Vamos simular uma alteração em um dos arquivos <font face="monospace">.c</font> (no caso, o arquivo <font face="monospace">regras.c</font>). Para isso:
<ul>
<li>em Windows, abra o arquivo em um editor e o salve sem alterar nada;</li>
<li>no Linux, na linha de comando, dê o comando <font face="monospace">touch regras.c</font>;</li>
</ul>
<p>Execute então o comando <font face="monospace">make</font>. Sua saída deve ser como a seguinte:<br />
<blockquote><font face="monospace">$ make<br />gcc -o regras.o -c regras.c</font><br /><font face="monospace">gcc -o roletrando main.o regras.o letras.o</font></p></blockquote>
<p>Por que isso aconteceu?<br />Make analisa o <i>timestamp</i> do arquivo (o registro de quando o mesmo foi alterado pela última vez) de todas as dependências necessárias e, caso o timestamp de uma dependência seja maior que o do arquivo do alvo (ou seja, a dependência em questão foi alterada), ele executa novamente a regra para ele e para todas as regras que tenha o alvo como dependência e assim sucessivamente. Portanto:
<ol>
<li>O sistema identificou que a dependência <font face="monospace">regras.c</font> de <font face="monospace">regras.o</font> mudou e reconstruiu <font face="monospace">regras.o</font>;</li>
<li>Então o <font face="monospace">make</font> percebeu que a dependência <font face="monospace">regras.o</font> de <font face="monospace">roletrando</font> mudou e, portanto, reconstruiu <font face="monospace">roletrando</font>;</li>
</ol>
<p>Ou seja, você não precisa se preocupar com re-executar manualmente os comandos em questão. Estando tudo OK, o próprio <font face="monospace">make</font> irá executar e processar os arquivos adequados para gerar um binário.<br />
<h3>Varíaveis e Macros no Makefile</h3>
<p>Bem, agora temos um Makefile útil&#8230; <br />Mas agora pense em uma coisa&#8230;<br />Aqui colocamos regras, alvos e dependências para CADA arquivo fonte. Isso em sistemas pequenos é bem útil, mas conforme o sistema aumenta de tamanho e funcionalidades, obviamente aumenta o número de arquivos de código fonte. Ou seja, teríamos que fazer mais entradas de regras, mais dependências&#8230;<br />Além disso, imagine que você deixa de usar o <font face="monospace">gcc</font> como compilador. Você provavelmente teria que modificar todos os alvos e regras para usar os padrões do novo compilador, o que seria um pesadelo!<br />O <font face="monospace">make</font>, porém, salva a nossa vida, oferecendo variáveis e macros que nos ajudam a fazer com que o make realize tarefas &#8220;genéricas&#8221; (como gerar um objeto <font face="monospace">.o</font> a partir de um fonte <font face="monospace">.c</font>), além de embutir alguma inteligência para que ele descubra se existem novos arquivos <font face="monospace">.c</font> no local e coisas do gênero. No caso, digite o seguinte Makefile e o salve no diretório do roletrando com o nome <font face="monospace">Makefile-1</font>:<b><br /></b><br />
<blockquote><b><font face="monospace">#<br /># Segunda tentativa de Makefile<br />#</p>
<p><font color="#cc0000">C_COMP=gcc<br />FONTES=$(wildcard *.c)&nbsp;&nbsp;&nbsp; # equivale a dizer FONTES=main.c regras.c letras.c<br />HEADERS=$(wildcard *.h)</font></p>
<p>all: roletrando<br />&nbsp;&nbsp;&nbsp; <br /><font color="#333399">roletrando: $(FONTES:.c=.o)<br />&nbsp;&nbsp;&nbsp; $(C_COMP) -o $@ $^</font></p>
<p><font color="#006600">%.o: %.c $(HEADERS)<br />&nbsp;&nbsp;&nbsp; $(C_COMP) -c $&lt; -o $@</font></font></b></p></blockquote>
</div>
<p>Perceba que ele parece muito mais complexo do que o nosso Makefile anterior. Mas não se preocupe que iremos descrevê-lo aos poucos.<br />Primeiro vamos pegar as primeiras três linhas:<br />
<blockquote><b><font face="monospace"><font color="#cc0000">C_COMP=gcc</font></font></b><br /><b><font face="monospace"><font color="#cc0000"><br />FONTES=$(wildcard *.c)&nbsp;&nbsp;&nbsp; # &#8220;equivale&#8221; a dizer FONTES=main.c regras.c letras.c</font></font></b><br /><b><font face="monospace"><font color="#cc0000"><br />HEADERS=$(wildcard *.h)</font></font></b></p></blockquote>
<div align="justify">Aqui estamos criando três variáveis: C_COMP, FONTES e HEADERS. A primeira variável, C_COMP, indica o compilador que estamos usando. O nome poderia ser qualquer um (à exceção de alguns nomes que o <font face="monospace">make</font> reserva para uso próprio, que não detalharemos aqui), e abaixo veremos o porque. No nosso caso atual, definimos que <font face="monospace">C_COMP=gcc</font>, o que lembra uma atribuição em C. Estamos atribuindo à variável do Makefile C_COMP esse valor.<br />A variável seguinte, FONTES, é atribuída com <b><font face="monospace"><font color="#cc0000">$(wildcard *.c)</font></font></b>.<br />&#8220;<i>O que isso quer dizer, afinal de contas?</i>&#8220;.<br />Quando você usa o símbolo de $, quer dizer que você está usando uma <i>macro</i> do <font face="monospace">make</font>. As <i>macros</i> são certos recursos embutidos no <font face="monospace">make</font> que estão disponíveis para facilitar sua vida na criação de um Makefile. Quando usamos <font face="monospace">$()</font> cercando algo, estamos indicando uma <i>macro de expansão</i>, ou seja, vamos fazer com que o make entenda que o valor que está ali equivale ao de um comando ou variável previamente definido. No nosso caso, usamos o comando <font face="monospace">wildcard</font> para pedir que o make realize uma busca no diretório onde o Makefile se encontra e localize todos os arquivos que seguem o padrão indicado. No nosso caso, <b><font face="monospace"><font color="#cc0000">$(wildcard *.c)</font></font></b>, pode ser lido como &#8220;procure todos os arquivos .c no diretório onde você está e os dê como valor onde você está&#8221;. Colocamos em seguida um comentário:<br />
<blockquote><b><font face="monospace"><font color="#cc0000"># &#8220;equivale&#8221; a dizer FONTES=main.c regras.c letras.c</font></font></b></p></blockquote>
<p>para dizer o nosso resultante. No fim das contas, usar:<br />
<blockquote><b><font face="monospace"><font color="#cc0000"><br />FONTES=$(wildcard *.c) </font></font></b></p></blockquote>
<p>equivale a dizer, na situação atual<br />
<blockquote><b><font face="monospace"><font color="#cc0000">FONTES=main.c regras.c letras.c</font></font></b></p></blockquote>
<p>Em seguida, criamos uma varíavel HEADERS, com o mesmo tipo de conteúdo de FONTES.<br />Uma coisa importante de dizer aqui, que não foi dita, é que as variáveis podem conter um valor só (como em C_COMP), ou vários valores separados entre si por espaço (como no caso da &#8220;expansão&#8221; de FONTES). Isso é importante em alguns casos, como veremos adiante.<br />Após estipularmos o alvo all, com dependência roletrando (igual ao nosso primeiro Makefile), definimos nosso alvo roletrando.<br /><b><font face="monospace"><font color="#333399">roletrando: $(FONTES:.c=.o)<br />&nbsp;&nbsp;&nbsp; $(C_COMP) -o $@ $^</font><br /></font></b><i>&#8220;Que coisa maluca é essa pelamordeus?!&#8221;</i><br />Calma. Aqui estamos usando várias macros para resumir nosso serviço.<br />Primeiro, vamos olhar a parte das dependências: <b><font face="monospace"><font color="#333399"> $(FONTES:.c=.o)</font></font></b><br />O que isso quer dizer?<br />O <font face="monospace">make</font> possui alguma inteligência para saber que determinados arquivos geram outros determinados arquivos. Por isso, ele é capaz de &#8220;traduzir&#8221; nomes por substituição simples se corretamente indicado. No caso, estamos usando o <b><font face="monospace"><font color="#333399">:.c=.o</font></font></b> na frente de FONTES. Isso indica ao make para entender que, ao expandir FONTES ali, ele deve substituir todas as extensões <font face="monospace">.c</font> para <font face="monospace">.o</font>. Ou seja, ele será capaz de montar uma lista dos arquivos objetos necessários a partir da lista de arquivos fontes (que colocamos na variável FONTES, lembra).<br />Em seguida, temos a regra para obtermos os alvos: <b><font face="monospace"><font color="#333399">$(C_COMP) -o $@ $^</font></font></b><br />Temos a expansão de C_COMP, o que já deve ser claro, e um <font face="monospace">-o</font> que é parâmetro do <font face="monospace">gcc</font> (aqui fica uma sugestão: o ideal aqui é que outra variável contivesse todos os parâmetros da compilação, uma vez que eles podem mudar de compilador para compilador). Em seguida temos duas <i>macros</i> novas: <font face="monospace">$@</font> e <font face="monospace">$^. </font>No caso, <font face="monospace">$@</font> deve ser lido como &#8220;o alvo a ser alcançado&#8221; e $^ indica &#8220;a lista de dependências passadas&#8221;.<br />Como tudo isso então se comporta, no fim das contas?
<ol>
<li><font face="monospace">make</font> irá expandir a lista de dependências. Para isso, irá olhar o valor de FONTES, pegar qualquer valor listado em FONTES que termine com .c e modificará o valor dele nessa expansão para .o. Considerando que FONTES equivale, nesse momento a <b><font face="monospace"><font color="#cc0000">main.c regras.c letras.c</font></font></b>, ele expadirá FONTES como <b><font face="monospace"><font color="#cc0000">main.o regras.o letras.o</font></font></b> nas dependências de <font face="monospace">roletrando</font>;</li>
<li>Em seguida, ele irá montar a regra para atingir-se o alvo <font face="monospace">roletrando</font>. Primeiro irá expandir a variável C_COMP (valendo <font face="monospace">gcc</font>), colocará o <font face="monospace">-o</font> na frente do mesmo (que, como não é uma macro ou variável é deixado como está), após isso inserindo o nome do alvo (no caso, roletrando) e a lista de dependências do mesmo! O valor final para a regra expandida será <font face="monospace">gcc -o roletrando main.o regras.o letras.o</font> (ou valor similar: na realidade normalmente será <font face="monospace">gcc -o roletrando letras.o main.o regras.o</font>, pois a expansão com <font face="monospace">wildcard</font> em <font face="monospace">FONTES</font> gera um lista em ordem alfabética dos arquivos cujo nome casem com o padrão desejado);</li>
</ol>
<p>OK, então temos o comando para gerar o executável a partir dos objetos&#8230; Mas e quanto a geração dos objetos a partir dos fontes?<br />O <font face="monospace">make</font> tem outra boa inteligência que é permitir que um alvo seja estabelecido a partir de um padrão, ou melhor, que haja uma <i>regra padrão</i> para alvos de um determinado tipo. Um exemplo de alvo assim está no final do nosso novo Makefile:<br />
<blockquote><b><font face="monospace"><font color="#006600">%.o: %.c $(HEADERS)</font></font></b><br /><b><font face="monospace"><font color="#006600">&nbsp;&nbsp;&nbsp; $(C_COMP) -c $&lt; -o $@</font></font></b></p></blockquote>
</div>
<div align="justify">O símbolo de porcento (<font face="monospace">%</font>) serve para indicar um padrão genérico que pode ser usado na regra como um todo. Colocando no alvo, ele diz ao <font face="monospace">make</font> que ele sabe o que fazer para qualquer arquivo que obedeça o padrão em questão. No nosso caso, o alvo passa a ser &#8220;qualquer arquivo que termine em <font face="monospace">.o</font>&#8220;. O bom é que esse valor passa a ser &#8220;salvo&#8221; e pode ser usado na dependência, como fizemos aqui: nossa dependência é <b><font face="monospace"><font color="#006600">%.c $(HEADERS)</font></font></b>, ou seja, &#8220;qualquer arquivo que tenha o mesmo nome do alvo, mas termine em <font face="Courier New">.c</font>&#8221; e o valor da variável HEADERS (que é um wildcard de arquivos <font face="Courier New">.h</font>).<br />A linha de regra tem algumas similaridades com o que temos na linha de regra para <font face="Courier New">roletrando</font>: primeiro expandimos C_COMP para gcc e temos um <font face="Courier New">-c</font> que é mantido como está (lembrando que <font face="Courier New">-c </font>apenas compila o arquivo oferecido como entrada, sem fazer <i>link</i>, gerando um arquivo objeto). <br />Em seguida, temos a <i>macro</i> <font face="Courier New">$&lt;</font>. Essa macro pega <i>o primeiro valor listado</i> na lista de dependências e o usa como valor. Perceba que, se analisarmos a lista de dependências, teremos normalmente o arquivo <font face="Courier New">.c</font> e um ou mais <i>header files</i>. Por isso, usamos <i>apenas o primeiro</i> item da lista (é bom deixar o <i>header file</i> como dependência, para o caso de alteração, mas o que precisamos usar mesmo é o arquivo de fonte <font face="Courier New">.c</font>) como parâmetro aqui. Em seguida, temos a montagem do resto da regra, que é idêntica a como fizemos no alvo roletrando: <font face="Courier New">-o</font> como está e o <font face="Courier New">$@</font> sendo expandido para o nome do alvo.<br />Como então se dá a execução passo a passo do Makefile desde que mandamos o comando make, nesse caso?<br />Ele irá expandir a regra roletrando e ver se todos os arquivos .o existem. Caso algum deles não exista ou seja mais antigo que o seu&nbsp; <font face="Courier New">.c</font>, ele perceberá isso e, usando o alvo genérico <font face="Courier New">%.o</font>, irá gerar o <font face="Courier New">.o</font> necessário a partir do <font face="Courier New">.c</font>. Em seguida irá gerar o alvo <font face="Courier New">roletrando</font>.<br />Apague todos os arquivos <font face="Courier New">.o</font> e mande executar nosso Makefile com <font face="Courier New">make -f Makefile-1</font>. Sua saída provavelmente será algo como abaixo:<br />
<blockquote><font face="monospace">gcc -c letras.c -o letras.o</font><br /><font face="monospace">gcc -c main.c -o main.o</font><br /><font face="monospace">gcc -c regras.c -o regras.o</font><br /><font face="monospace">gcc -o roletrando letras.o main.o regras.o</font></p></blockquote>
<p>Ou seja, ele fará todo o serviço necessário sem você criar regras individuais e aumentar muito a complexidade do seu Makefile.<br />Um efeito colateral importante do uso de <font face="monospace">wildcards</font> é que qualquer arquivo pego pelo padrão é usado como valor de variável (e como dependência, em geral). Isso pode acarretar problemas. Por exemplo, mantendo nosso Makefile como está, crie um arquivo .c em branco no diretório do roletrando. Não interessa o nome, apenas crie (para usuários de Linux, use o comando <font face="monospace">touch o_nome_do_meu_arquivo_aleatório.c</font>), sem conteúdo nenhum. Após isso, execute o Makefile-1 como fizemos anteriormente. Você perceberá que ele irá achar o arquivo <font face="monospace">random.c</font> na lista de fontes e colocará o arquivo <font face="monospace">random.o</font> como parte das dependência de <font face="monospace">roletrando</font> (devido à expansão), compilando<font face="monospace"> random.c</font> com a regra genérica.<br />Isso parece bobagem, uma vez que random.c está vazio&#8230; Mas tente, por exemplo, copiar um arquivo que tenha uma função<font face="monospace"> main()</font> para dentro de <font face="monospace">roletrando</font>. Ao usar <font face="monospace">wildcards</font>, você pode incorrer no risco de, cedo ou tarde, provocar erros de compilação e ligação devido à inclusão inadvertidade de um arquivo <font face="monospace">.c</font> que contenha um código para uma função similar a uma que já exista em seu código. Tome muito cuidado quanto a isso.<br />Uma sugestão seria não utilizar as expansões com <font face="monospace">wildcards</font> e apenas incluir os nomes de arquivo fontes, separados por espaço, em FONTES. Ainda demandaria alguma edição no Makefile após a inclusão de um novo arquivo, mas isso permitiria uma melhor administração dos fontes a serem compilados. Além disso, o resto das regras e macros do Makegile continuariam com sua utilidade mantida.<br />No caso de a pessoa tentar isso, ela não poderia normalmente dar ENTER e em seguida colocar o nome de um arquivo (considera-se que o valor da variável termina de ser lido em um caracter nova-linha). Porém, é possível &#8220;enganar&#8221; o sistema para que ele ache que um ENTER não é o iniício de uma nova linha. Para isso, coloque &#8220;<font face="monospace">\</font>&#8221; antes de dar ENTER e siga em frente. O ENTER dado não será lido pelo <font face="monospace">make</font> (será &#8220;escapado&#8221;) e o valor na linha de baixo será acrescentado aos demais normalmente. Por exemplo,<br />
<blockquote><font face="monospace">FONTES=fonte1.c fonte2.c fonte3.c </font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fonte4.c</font></p></blockquote>
<p>Faria com que você recebesse a mensagem de erro &#8220;<font face="monospace">Makefile:2: *** faltando o separador.&nbsp; Pare.</font>&#8220;. Mas:<br />
<blockquote><font face="monospace">FONTES=fonte1.c fonte2.c fonte3.c \</font><font face="monospace"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fonte4.c</font></p></blockquote>
<p>Seria correto e retornaria a expansão para <font face="monospace">fonte1.c fonte2.c fonte3.c fonte4.c</font>.</div>
<p>Bem, estamos quase acabando esse assunto chato de Makefiles. Vamos apenas falar de um último tópico.<br />
<h3><i>Phony targets</i> (Alvos nulos)</h3>
<p>Lá no início, quando falamos do alvo <i>default</i> &#8220;<font face="monospace">all</font>&#8220;, mencionamos o fato de ele ser um <i>phony target</i>, um alvo nulo&#8230;
<div align="justify">Na verdade, <i>phony targets</i> são alvos que não vão gerar algum arquivo de saída. Um alvo assim tem como objetivo facilitar atividades que o desenvolvedor necessita fazer, como limpar os arquivos objeto antigos, empacotar um <i>tarball</i> (um arquivo compactado <font face="monospace">.tar.gz</font> ou <font face="monospace">.tar.bz2</font>), entre outros.<br />Uma coisa importante é que o mesmo não irá gerar arquivos, mas é bom por via das dúvidas indicar que esses alvos são <i>Phony Targets</i> para que o <font face="monospace">make</font> não exija um arquivo com o nome do <i>Phony Target </i>ou para evitar que a existência de um arquivo com o mesmo nome do alvo faça com que a regra pare de funcionar. Para isso, utilizamos o alvo especial <font face="monospace">.PHONY</font> para isolar todos os <i>Phony Targets</i> por meio dele. Caso contrário, podemos receber mensagens de erros como a seguinte, ao utilizar uma <i>Phony Target</i> <font face="monospace">clean</font>, por exemplo:<br />
<blockquote><font face="monospace">make: *** Sem regra para processar o alvo `clean&#8217;.&nbsp; Pare.</font></p></blockquote>
<p>Abra seu arquivo Makefile-1 e adicione as seguintes linhas ao final do mesmo:<br />
<blockquote><font face="monospace">clean:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; rm -f *.o roletrando *~</font></p>
<p><font face="monospace">tar:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; tar cvjf roletrando.tar.bz2 $(FONTES) $(HEADERS)</font></p></blockquote>
<p>Seu arquivo Makefile-1 deverá estar parecendo algo assim:</div>
<blockquote><p><font face="monospace">#</font><br /><font face="monospace"># Segunda tentativa de Makefile</font><br /><font face="monospace">#</font></p>
<p><font face="monospace">C_COMP=gcc</font><br /><font face="monospace">FONTES=$(wildcard *.c)&nbsp;&nbsp;&nbsp; # equivale a dizer FONTES=main.c regras.c letras.c</font><br /><font face="monospace">HEADERS=$(wildcard *.h)</font></p>
<p><font face="monospace">all: roletrando</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><br /><font face="monospace">roletrando: $(FONTES:.c=.o)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; $(C_COMP) -o $@ $^</font></p>
<p><font face="monospace">%.o: %.c $(HEADERS)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; $(C_COMP) -c $&lt; -o $@</font></p>
<p><font face="monospace">clean:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; rm -f *.o roletrando *~</font></p>
<p><font face="monospace">tar:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; tar cvjf roletrando.tar.bz2 $(FONTES) $(HEADERS)</font></p></blockquote>
<div align="justify">Perceba que ainda não definimos <font face="monospace">clean</font> e <font face="monospace">tar</font> como <i>Phony Thargets</i><font face="monospace"></font>. Agora, vamos definir nossas <i>Phony Thargets</i>. Antes de <font face="monospace">all</font>, inclua a seguinte regra:<br />
<blockquote><font face="monospace">.PHONY: all clean tar</font></p></blockquote>
<p>Perceba que agora definimos eles como <i>Phony Targets</i>, perceba que incluimos <font face="monospace">all</font>. Essa é uma boa prática, incluir <font face="monospace">all</font> como <i>Phony Target</i> para evitar problema maiores no caso da existência de uma arquivo <font face="monospace">all</font>. Teste as regras clean e tar, lembrando de usar <font face="monospace">-f Makefile-1</font> para indicar o arquivo de Makefile desejado (se você colocar essas regras no arquivo Makefile padrão, não precisará do <font face="monospace">-f</font>). Muitos softwares livres incluem em seus makefiles <i>Phony Targets </i>como <font face="monospace">clean</font>, <font face="monospace">install</font>, <font face="monospace">package</font>, etc&#8230; Tente criar vários <i>Phony Targets</i> para fazer operações de instalação, remoção, limpeza dos objetos antigos, compactação, e por aí afora.<br />O nosso Makefile &#8220;genérico&#8221; deve ficar como o abaixo. Esse é um ótimo Makefile padrão para ser adotado no dia a dia:<br />
<blockquote><font face="monospace"></font><font face="monospace">C_COMP=gcc</font><br /><font face="monospace">FONTES=$(wildcard *.c)&nbsp; </font><br /><font face="monospace">HEADERS=$(wildcard *.h)</font></p>
<p><font face="monospace">.PHONY: all clean tar</font></p>
<p><font face="monospace">all: roletrando</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><br /><font face="monospace">roletrando: $(FONTES:.c=.o)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; $(C_COMP) -o $@ $^</font></p>
<p><font face="monospace">%.o: %.c $(HEADERS)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; $(C_COMP) -c $&lt; -o $@</font></p>
<p><font face="monospace">clean:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; rm -f *.o roletrando *~</font></p>
<p><font face="monospace">tar:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; tar cvjf roletrando.tar.bz2 $(FONTES) $(HEADERS)</font></p></blockquote>
</div>
<div align="justify">
<h3>Para saber mais</h3>
<p>Não pretendo falar por um bom tempo mais sobre Makefiles. Essa introdução deve ser o suficiente para o dia a dia e para o que precisaremos por um LONGO TEMPO no nosso &#8220;curso&#8221;. Se você desejar maiores informações, abaixo alguns links úteis:
<ul>
<li>Artigo sobre make da Wikipedia: <a target="_blank" href="http://en.wikipedia.org/wiki/Make_%28software%29">http://en.wikipedia.org/wiki/Make_%28software%29</a>;</li>
<li>Manual do GNU Make: <a target="_blank" href="http://www.gnu.org/s/hello/manual/make/index.html#Top">http://www.gnu.org/s/hello/manual/make/index.html#Top</a>;</li>
<li>Especificação do make segundo o OpenGroup: <a target="_blank" href="http://pubs.opengroup.org/onlinepubs/009695399/utilities/make.html">http://pubs.opengroup.org/onlinepubs/009695399/utilities/make.html</a>;</li>
</ul>
<p>Além dos seguintes tutoriais, onde me baseei para escrever esse artigo:
<ul>
<li><a target="_blank" href="http://www.opussoftware.com/tutorial/TutMakefile.htm">http://www.opussoftware.com/tutorial/TutMakefile.htm</a></li>
<li><a target="_blank" href="http://ubuntuforum-pt.org/index.php/topic,21155.0.html">http://ubuntuforum-pt.org/index.php/topic,21155.0.html</a></li>
<li><a target="_blank" href="http://www.eng.hawaii.edu/Tutor/Make/">http://www.eng.hawaii.edu/Tutor/Make/</a></li>
<li><a target="_blank" href="http://www.cs.umd.edu/class/fall2002/cmsc214/Tutorial/makefile.html">http://www.cs.umd.edu/class/fall2002/cmsc214/Tutorial/makefile.html</a></li>
<li><a target="_blank" href="http://www.metalshell.com/view/tutorial/120/">http://www.metalshell.com/view/tutorial/120/</a></li>
<li><a target="_blank" href="http://developers.sun.com/solaris/articles/make_utility.html#5">http://developers.sun.com/solaris/articles/make_utility.html#5</a></li>
</ul>
<p>Bem, agora chega de falarmos de ferramentas. Prometo na próxima &#8220;aula&#8221; voltar à programação em C, com estruturas e tipos do usuário. Até lá!</div>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=4a94ff2e-c6e2-8e5b-bbd2-3c563cd7191e" /></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/135/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/135/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/135/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=135&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2011/07/28/utilitarios-make-makefiles-e-sua-importancia/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>

		<media:content url="http://img.zemanta.com/pixy.gif?x-id=4a94ff2e-c6e2-8e5b-bbd2-3c563cd7191e" medium="image" />
	</item>
		<item>
		<title>Sobre arquivos de código-fonte, arquivos de cabeçalhos e projetos</title>
		<link>https://aulasdec.wordpress.com/2011/07/09/sobre-arquivos-de-codigo-fonte-arquivos-de-cabecalhos-e-projetos/</link>
		<comments>https://aulasdec.wordpress.com/2011/07/09/sobre-arquivos-de-codigo-fonte-arquivos-de-cabecalhos-e-projetos/#comments</comments>
		<pubDate>Sat, 09 Jul 2011 16:18:14 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Boas Práticas]]></category>
		<category><![CDATA[Funções]]></category>
		<category><![CDATA[Projetos]]></category>
		<category><![CDATA[Técnicas]]></category>

		<guid isPermaLink="false">http://aulasdec.wordpress.com/2011/07/09/sobre-arquivos-de-codigo-fonte-arquivos-de-cabecalhos-e-projetos/</guid>
		<description><![CDATA[Olá!Hoje não iremos apresentar nenhum código.&#8220;Putzgrila!&#8221; você deve estar dizendo.Na realidade eu estou dizendo apenas &#8220;meia-verdade&#8221;, pois não apresentaremos nenhum código, digamos assim, novo.É que chegamos em um momento do nosso &#8220;curso&#8221; onde precisaremos de alguma teoria antes de seguir em frente.Até agora, temos visto programas que podemos compilar e editar em apenas um arquivo [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=131&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div align="justify">Olá!<br />Hoje não iremos apresentar nenhum código.<br />&#8220;<em>Putzgrila!</em>&#8221; você deve estar dizendo.<br />Na realidade eu estou dizendo apenas &#8220;meia-verdade&#8221;, pois não apresentaremos nenhum código, digamos assim, novo.<br />É que chegamos em um momento do nosso &#8220;curso&#8221; onde precisaremos de alguma teoria antes de seguir em frente.<br />Até agora, temos visto programas que podemos compilar e editar em apenas um arquivo de código-fonte e algumas dezenas de linhas. Talvez o <a href="http://aulasdec.wordpress.com/2011/04/18/matrizes-e-ponteiros-%e2%80%93-parte-3-%e2%80%93-ponteiros-e-funcoes/">&#8220;jogo de roletrando&#8221; que fizemos na última aula</a> tenha sido o maior código que escrevemos, com em torno de 170 linhas.<br />Isso pode parecer grande coisa, mas um programa assim&nbsp; é extremamente incomum.
<div align="justify">&#8220;<em>Como assim?</em>&#8220;, você deve estar pensando.<br />Se pararmos para pensar e compararmos com programas como os que usamos no dia a dia, o nosso &#8220;roletrando&#8221; é extremamente tosco e rudimentar. Não precisamos pegar leve, pois essa é a verdade. Programas comuns do dia a dia, como um navegador web, o próprio sistema operacional ou um compilador, são programas muito mais complexos e, portanto, com muito mais código. Por exemplo: o Windows XP, <a href="http://en.wikipedia.org/wiki/Source_lines_of_code#Example">segundo a Wikipedia, possui em torno de 45 milhões (sim, MI-LHÕ-ES) de linhas de código</a>. No mesmo artigo, mostra-se que o <em>kernel</em> (a parte mais fundamental do sistema operacional) do Linux 2.6.35 possui 13,5 milhões de linhas de código. Em Julho de 2011, quando esse artigo foi escrito, <a href="http://www.ohloh.net/p/libreoffice/analyses/latest">segundo o site Ohloh.net, o LibreOffice (uma suite de produtividade livre) possuia mais de 7,5 milhões de linhas de código</a>. Pelo mesmo site, e na mesma época, constava que o Mozilla Firefox (um popular navegador Web) possuia em torno de 5 milhões de linhas de código.<br />Usar tal estatística é problemático, uma vez que o número de linhas de código para descrever-se um programa pode mudar de linguagem de programaçÂão para linguagem de programaçÂão: as linguagens podem incorporar em sua infraestrutura uma maior ou menor quantidade de bibliotecas e funções utilitárias, permitindo que o programador desenvolva programas mais &#8220;enxutos&#8221; ao utilizar-se de funcionalidades já previstas na linguagem de programaçao. Porém, o caso aqui não é comparar a complexidade no desenvolvimento ou coisas do gênero. Isso não vêem ao caso, pois meu objetivo aqui não é tentar determinar a linguagem que permite produzir mais programa com menos código. Meu objetivo aqui é fazer você pensar: imagine ter que carregar em um editor todos os, por exemplo, 5 milhões de linhas de código do Mozilla Firefox para uma manutenção. Tériamos sérios problemas para localizar o que desejamos corrigir, editar e compilar esse código novo, além do tempo gasto para tais procedimentos.<br />Entretanto, esses programas existem. <em>&#8220;Como?&#8221;, </em>você deve se perguntar?<br />No caso, graças à possibilidade de compilação parcial.<br />Quando falamos, <a href="http://aulasdec.wordpress.com/2010/11/05/o-primeiro-programa-helloworld-c/">lá no início do curso</a>, que um compilador compila todo o código e gera o código binário, eu disse apenas <em>meia-verdade</em>. Realmente, o compilador gera UM código binário a partir do código fonte. Pòrém, quem realmente cria o binário esxecutável baseado no código binário gerado pelo compilador é um programa ou rotina do compilador chamado <a href="http://pt.wikipedia.org/wiki/Linker"><em>linkeditor</em> (ou <em>linker</em>)</a>.<br />Por que isso é necessário?<br />O tempo todo, desde o início do curso, temos citado funções. Temos visto funções o tempo todo, desde os <span style="font-family:courier new,courier;">printf()</span> até nossas funções personalizadas. Porém, no momento em que o sistema operaciona executa um programa, ele vai apenas lendo e lendo códigos até chegar ao fim do mesmo. Ele pode ter execuções condicionais, baseadas em <span style="font-family:courier new,courier;">if, while</span>, etc&#8230; (na verdade, tudo vai a um nível ainda mais baixo no fim das contas, mas não vamos entrar nesses detalhes), mas na verdade mesmo com esses saltos cedo ou tarde o programa volta para onde ele estava, até chegar ao fim dele.</div>
</div>
<p>Cada função, não importa qual, representa, digamos assim, um &#8220;salto&#8221;. Como <a href="http://aulasdec.wordpress.com/2010/12/01/funcoes-parte-1/">dissemos no passado</a>:<br />
<blockquote>
<p style="text-align:justify;">Quando uma função é chamada, o programa principal passa o controle da  execução para outro ponto completamente arbitrário dentro do espaço que o  programa ocupa na memória e executa os comandos informados na função.  Uma vez que termine, ele tem que devolver o controle para que o programa  principal volte a ser executado, o que em C indicamos com <span style="font-family:monospace;">return</span>, e assim sucessivamente até que o programa chegue ao fim do programa principal e seja encerrado.</p>
</blockquote>
<p style="text-align:justify;">A função do <em>linker</em> é justamente calcular as posições de cada função na memória (lembra que falamos que as funções ocupam memória, quando falamos dos <a href="http://aulasdec.wordpress.com/2011/04/18/matrizes-e-ponteiros-%e2%80%93-parte-3-%e2%80%93-ponteiros-e-funcoes/">ponteiros de função</a>?) e colocar no código binário as posições corretas, de modo que o sistema operacional consiga fazer todos os procedimentos de carga do código e execução de maneira adequada. Além disso, o <em>linker</em> também liga (em inglês, <em>to link</em> significa ligar) determinadas funções e códigos que não fazem parte do código binário que estamos usando para gerar o executável, sendo que esses últimos podem incluir tanto códigos binários de bibliotecas padrãao quanto códigos que estão em outros arquivos passados para o <em>linker</em>. </p>
<p style="text-align:justify;">Atualmente a separação entre compilador e <em>linker</em> está cada vez menor, pois muitos compiladores trazem o <em>linker</em> como uma rotina embutida em si, e não como um programa em separado, mas a função do <em>linker</em> e sua utilidade ainda existe.</p>
<p style="text-align:justify;">OK&#8230; Toda essa teoria para que?</p>
<p style="text-align:justify;">Se pensarmos agora, com o que sabemos, é muito mais interessante separarmos o código fonte em pequenos arquivos englobando uma pequena parte do código-fonte, pois:</p>
<ol>
<li style="text-align:justify;">O programador que for fazer manutenção em determinada parte do código terá uma chance muito menor de, inadvertivamente, mexer em código fonte indevido e provocar erros e <em>bugs</em>, pois cada parcela do código estará contido em um arquivo de código-fonte;</li>
<li style="text-align:justify;">A compilação será mais rápida &#8220;com o tempo&#8221;. É claro que muito provavelmente a compilação da primeira vez ainda será demorada, pois cada arquivo de código binário terá que ser gerado e, após todos os arquivos serem gerados, eles deverão ser alimentados ao <em>linker</em> (ou ao compilador atualmente), para que o mesmo seja transformado em código executável final. Porém, conforme as manutenções forem se fazendo necessárias, a compilação será mais rápida pois poderemos compilar apenas as parcelas de código (ou seja, os arquviso de código-fonte) <em>que foram alterados</em> e alimentar os códigos binários modificados junto com os demais ao <em>linker</em>. Desse modo, ao invés de compilar, por exemplo, alguns milhões de linhas de código, podemos restringir a compilação a algumas dezenas, ou até menos. De fato, muitos desses programas de grande porte, como o Firefox, utilizam ferramentas que permitem automatizar o processo de compilação de modo que elas detectam quando um ou mais arquivos foram modificados e geram novamente o código binário e o executável final;</li>
<li style="text-align:justify;">Podemos &#8220;fechar o código&#8221;. Essa expressão quer dizer que, ao oferecermos um código para alguém, podemos oferecê-lo na forma de um binárioo, ao invés de oferecê-lo na forma de código fonte. Isso pode ser interessante quando a pessoa ou empresa está desenvolvendo um código cujo funcionamento interno não deve ser divulgado por razões comerciais ou legais. Desse modo, pode-se oferecer o código binário ao usuário do mesmo que irá incorporá-lo ao seu código por meio do <em>linker</em>;</li>
<li style="text-align:justify;">Fica mais fácil aprender o que o programa faz &#8220;com o tempo&#8221;: ao invés de obrigar o desenvolvedor a ler todo o código de uma só vez e tentar entender o que ele faz, o desenvolvedor pode se restringir a ler apenas determinadas partes do código. Como a leitura de um código-fonte escritto por um outro desenvolvedor não é um procedimento exatamente simples, ao reduzir a necessidade do desenvolvedor em se &#8220;aprofundar&#8221; no estudo do código para resolver um problema (que podde ser imediato), ganha-se tempo no desenvolvimento de soluções;</li>
</ol>
<p>OK&#8230; E como &#8220;dividimos&#8221; um programa e o compilamos?
<p style="text-align:justify;">Primeiro, temos que criar em nossa mente a estrutura dos arquivos de código fonte. É claro que podemos ter arquivos individuais de código fonte para cada função que formos criar, mas isso não é uma boa ideia: se um arquivo único de código fonte é algo ruim, uma grande quantidade de arquivos de código fonte também é ruim, pois dificultaria a localização do arquivo que nos interessa em meio ao mar de arquivos gerado no processo. Em geral, todo bom <em>projeto de programação</em> (chama-se projeto todo o conjunto de arquivos cujo fim é resultar em um programa binário executável e/ou em bibliotecas de funções úteis ao desenvolvedor) tem seus arquivos fontes organizados por função.</p>
<p style="text-align:justify;">Para exemplificarmos esse processo, vamos pegar nosso programa do &#8220;jogo do Roletrando&#8221; e transformá-lo em um projeto. Organizaremos nosso &#8220;projeto Roletrando&#8221; em três arquivos:</p>
<ul>
<li style="text-align:justify;"><span style="font-family:courier new,courier;">main.c</span> &#8211; nele está a lógica principal do jogo. Existe o hábito entre desenvolvedores C de chamar-se o arquivo de código fonte principal do programa de <span style="font-family:courier new,courier;">main.c</span>, mas essa é uma decisão arbitrária, uma <em>boa prática</em> que não precisa necessariamente ser seguida (é uma boa prática, não uma obrigação). Estou seguindo essa boa prática como uma forma de facilitarr a vida de quemm for ler o código, mas isso não é obrigatório;</li>
<li style="text-align:justify;"><span style="font-family:courier new,courier;">regras.c</span> &#8211; nesse arquivo, colocaremos as duas funções que lidam com as regras do jogo: <span style="font-family:courier new,courier;">explicarRegras()</span>, que é mostrada no início do jogo para que o jogador conheça o funcionamento do jogo, e <span style="font-family:courier new,courier;">testaCerto()</span> que checa se o jogador conseguiu acertar a palavra em questão;</li>
<li style="text-align:justify;"><span style="font-family:courier new,courier;">letras.c</span> &#8211; colocaremos aqui as funções que validam o acerto ou erro na tentativa de acerto das letras: <span style="font-family:courier new,courier;">checaLetra()</span>, que indica se a letra existe ou não na palavra, e <span style="font-family:courier new,courier;">contaFaltantes()</span>, uma função utilizada para saber quantas letras ainda falta (pois a partir da metade de letras acertadas, o jogo passa a pedir que o jogador tente descobrir qual a palabra em questão);</li>
</ul>
<p style="text-align:justify;">Há um porém: como os códigos de cada arquivo farão referências a funções contidas nos demais arquivos, seria necessário adicionar os protótipos de função de TODAS as funções do programa em TODOS os arquivos. Isso tornaria o programa complexo e suscetível a erros: pense, por exemplo, que você modificou uma função, mas não seus protótipos. O <em>linker</em> não conseguiria ligar corretamente as funções, provocando o erro. O correto seria que o compilador provocasse um erro ou alerta indicando que os códigos antigos não foram adaptados para aquela função nova. Para que isso não aconteça, criaremos o nosso próprio arquivo de cabeçalhos. Quando falamos dos protótipos de função dissemos que:</p>
<blockquote><p style="text-align:justify;"><a href="http://aulasdec.wordpress.com/2010/12/16/funcoes-parte-2/">Funções ? Parte 2 « Aulas de C</a></p>
<p style="text-align:justify;">O que o compilador normalmente precisa é saber <em>como trabalhar</em> com uma função, ou seja, os valores que ele precisa passar para a mesma como <em>parâmetros</em> e o <em>tipo de retorno</em> da mesma. O código em si não precisa sequer ser descrito como parte do seu programa, podendo estar (o código em si) em qualquer outro lugar. (lembram das bibliotecas, como <span style="font-family:monospace;">stdio.h</span>, <span style="font-family:monospace;">string.h</span> e <span style="font-family:monospace;">stdlib.h</span>? Na realidade eles são úteis para o compilador saber como usar as funções que eles ?representam?. Os códigos estão armazenados em outras bibliotecas e arquivos dentro do sistema operacional ou do compilador).</p>
</blockquote>
<p style="text-align:justify;">Em C, chamamos esses arquivos que contêm os protótipos de função de &#8220;arquivos de cabeçalho&#8221; ou &#8220;<em>header files</em>&#8221; (por isso a extensão deles é tipicamente <span style="font-family:courier new,courier;">.h</span> &#8211; de <em>header</em>). Como esses arquivos são incluídos pelo compilador (por meio das diretivas <span style="font-family:courier new,courier;">#include</span>) ao código fonte no momento da compilação, esses arquivos são úteis para definir valores padrão e protótipos de funções que serão usadas em várias partes do código fonte, de modo a &#8220;isolar&#8221; funções desnecessárias ou com nomes similares e assim não provocar erros, além de ajudar na documentação e manutenção do código. No nosso caso, criariamos um arquivo roletrando.h com os cabeçalhos e definições necessárias. Uma outra grande vantagem dos arquivos de cabeçalhos é que o compilador consegue trazer arquivos de cabeçalho que estejam incluídos em arquivos de cabeçalho até um determinado nível, em geral suficiente para que um arquivo de cabeçalho do projeto nosso inclua os arquivos de cabeçalho padrão do C que precisamos.</p>
<p style="text-align:justify;">Sem muito papo, vamos ver como ficou disposto o código no nosso projeto e explicar pequenas alterações no mesmo. O arquivo <span style="font-family:courier new,courier;">main.c</span> ficará como abaixo:</p>
<blockquote><p style="text-align:justify;"><span style="font-family:courier new,courier;">/*</span><br /><span style="font-family:courier new,courier;">&nbsp;* main.c</span><br /><span style="font-family:courier new,courier;">&nbsp;*/</span></p>
<p><span style="color:rgb(255,0,0);"><strong><span style="font-family:courier new,courier;">#include &#8220;roletrando.h&#8221;</span></strong></span></p>
<p><span style="font-family:courier new,courier;">int main (void)</span><br /><span style="font-family:courier new,courier;">{</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; // Declarando variaveis</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; // Biblioteca de palavras</span><br /><span style="font-family:courier new,courier;">&nbsp; char palavras[][TAMANHO_PALAVRAS]={&#8220;rotina&#8221;, &#8220;retina&#8221;, &#8220;palhaco&#8221;, &#8220;lembranca&#8221;,</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;sistema&#8221;, &#8220;musica&#8221;,&#8221;curioso&#8221;, &#8220;fantasia&#8221;,</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;malabares&#8221;,&#8221;sonhador&#8221;,&#8221;atitude&#8221;,&#8221;pacoca&#8221;,</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;sonhador&#8221;};</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; // Ponteiros necessarios</span><br /><span style="font-family:courier new,courier;">&nbsp; char *palavraEscolhida, *letrasCertas;</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; // Algumas variaveis de apoio</span><br /><span style="font-family:courier new,courier;">&nbsp; int tentativasErradas=0,i;</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; explicarRegras();</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; srand(time(NULL)); // Serve para modificar a tabela de nÃºmeros pseudo-aleatÃ³rios</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; palavraEscolhida=palavras[rand()%((sizeof(palavras)/TAMANHO_PALAVRAS)-1)];</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; letrasCertas=malloc(strlen(palavraEscolhida)+1);</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; if (!letrasCertas)</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; {</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao consegui alocar memoria!\n&#8221;);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; memset(letrasCertas,&#8221;, strlen(palavraEscolhida)+1);</span><br /><span style="font-family:courier new,courier;">&nbsp; memset(letrasCertas,&#8217;-', strlen(palavraEscolhida));</span></p>
<p><span style="font-family:courier new,courier;">&nbsp; int tentativaAtual=0;</span><br /><span style="font-family:courier new,courier;">&nbsp; while(tentativasErradas&lt;NUM_TENTATIVAS)</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; {</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char minhaLetra;</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tentativaAtual++;</span></p>
<p><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;Okay, tentativa no %d (%d tentativas erradas):&#8221;, tentativaAtual, tentativasErradas);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf (&#8220;%c&#8221;, &amp;minhaLetra);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getchar();</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!checaLetra(palavraEscolhida,letrasCertas,minhaLetra))</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; {</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp; printf(&#8220;Que pena, essa letra nao aparece!\n&#8221;);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp; tentativasErradas++;</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp; continue;</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;A palavra ate agora e: %s\n&#8221;,letrasCertas);</span></p>
<p><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (contaFaltantes(letrasCertas)&lt;=(strlen(palavraEscolhida)/2))</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; {</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp; if((contaFaltantes(letrasCertas)==0)||testaCerto(palavraEscolhida,&amp;tentativasErradas))</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Muito bem! Voce acertou!\n&#8221;);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(palavraEscolhida);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(letrasCertas);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; }</span><br /><span style="font-family:courier new,courier;">&nbsp;&nbsp;&nbsp; }</span><br /><span style="font-family:courier new,courier;">}</span></p>
</blockquote>
<p style="text-align:justify;">Primeira coisa: se você comparar o código que estamos colocando aqui com o que colocamos originalmente, verá que, além de curto, ele não traz as funções como <font face="monospace">checaLetra</font> e afins. Isso é normal e é exatamente o que queremos: isolar o código &#8220;principal&#8221; em um arquivo e os demais em outros. </p>
<p style="text-align:justify;">Além disso, veja que, ao invés dos <font face="monospace">#include</font>s, <font face="monospace">#define</font>s e protótipos de função da versão &#8220;antiga&#8221;, colocamos apenas um <font face="monospace">#include</font>, que é levemente diferente do que os <font face="monospace">#include</font>s que vimos anteriormente:</p>
<div align="justify">
<blockquote>
<p style="text-align:justify;"><span style="color:rgb(255,0,0);"><strong><span style="font-family:courier new,courier;">#include &#8220;roletrando.h&#8221;</span></strong></span></p>
</blockquote>
<p>Esse #include por trazer o nome do arquivo de inclusão entre aspas duplas, ao invés de cercada por sinais de maior e menor (como em <b><font face="monospace">#include &lt;stdio.h&gt;</font></b>). &#8220;<i>Qual é a diferença?&#8221;</i>, você deve se perguntar.<br />A diferença está relacionada com a idéia de &#8220;biblioteca padrão&#8221;:<br />Toda linguagem de programação (e C não é exceção), tem sua biblioteca padrão de funções. Essa biblioteca representa conjuntos de funções que o programador pode esperar que um ambiente de desenvolvimento inclua, embora isso não seja obrigatório (em ambientes de pouca memória ou com usos específicos, pode-se implementar C sem várias das bibliotecas padrão). Somada à biblioteca padrão, toda linguagem de programação permite que o desenvolvedor a expanda, incluindo bibliotecas para as mais diversas finalidades. <br />Em C, quando um arquivo de cabeçalho no <font face="monospace">#include</font> vem cercado de sinais de maior e menor, o compilador procura o arquivo com o nome em questão não apenas nos diretórios do projeto em questão, mas em diretórios adicionais normalmente definidos em uma variável de ambiente chamada <font face="monospace">INCLUDE</font> (isso não é obrigatório, mas tem se tornado um &#8220;padrão de fato&#8221; devido ao intensivo uso desse procedimento). Esses diretórios contêm diversos arquivos de cabeçalho para diversas bibliotecas, tanto padrão do C quanto para as bibliotecas adicionadas pelo desenvolvedor. Além disso, o próprio compilador tem certa &#8220;inteligência&#8221; para localizar bibliotecas padrão. Por exemplo, no Linux e na grande maioria dos ambientes Unix padronizados, os arquivos de cabeçalho da biblioteca padrão estão em <font face="monospace">/usr/include</font>, e caminhos como <font face="monospace">/usr/local/include</font> são reservados para bibliotecas adicionais.<br />Quando, porém, no C, a diretiva de compilação <font face="monospace">#include</font> é cercada por aspas duplas, o C compreende que o cabeçalho em questão é parte específica desse projeto e não utiliza os caminhos em <font face="monospace">INCLUDE</font> para procurar por ele, procurando-o dentro do diretório no qual o projeto está sendo compilado.<br />Essa é a diferença básica nesses dois casos: existem mais detalhes, mas iremos nos restringir no momento a essa explicação básica.<br />Bem, dito isso, o resto do código não possui mistérios: continua sendo o <font face="monospace">main()</font> do <a href="http://aulasdec.wordpress.com/2011/04/18/matrizes-e-ponteiros-%e2%80%93-parte-3-%e2%80%93-ponteiros-e-funcoes/">&#8220;jogo de roletrando&#8221; que fizemos na última aula</a>,&nbsp; sem modificação alguma no código. Porém, se você tentar compilar ele &#8220;agora&#8221;, você receberá mensagens de erro como as a seguir (no caso, se você usar GCC):<font face="monospace"><br /></font><br />
<blockquote><font face="monospace">main.c:5:24: error: roletrando.h: Arquivo ou diretório não encontrado</font><br /><font face="monospace">main.c: In function &#8216;main&#8217;:</font><br /><font face="monospace">main.c:13: error: &#8216;TAMANHO_PALAVRAS&#8217; undeclared (first use in this function)</font><br /><font face="monospace">main.c:13: error: (Each undeclared identifier is reported only once</font><br /><font face="monospace">main.c:13: error: for each function it appears in.)</font><br /><font face="monospace">main.c:26: error: &#8216;NULL&#8217; undeclared (first use in this function)</font><br /><font face="monospace">main.c:30: warning: incompatible implicit declaration of built-in function &#8216;malloc&#8217;</font><br /><font face="monospace">main.c:30: warning: incompatible implicit declaration of built-in function &#8216;strlen&#8217;</font><br /><font face="monospace">main.c:34: warning: incompatible implicit declaration of built-in function &#8216;printf&#8217;</font><br /><font face="monospace">main.c:38: warning: incompatible implicit declaration of built-in function &#8216;memset&#8217;</font><br /><font face="monospace">main.c:42: error: &#8216;NUM_TENTATIVAS&#8217; undeclared (first use in this function)</font><br /><font face="monospace">main.c:47: warning: incompatible implicit declaration of built-in function &#8216;printf&#8217;</font><br /><font face="monospace">main.c:48: warning: incompatible implicit declaration of built-in function &#8216;scanf&#8217;</font></p></blockquote>
<div align="justify">A primeira linha já dá a pista do que fizemos de errado:<br />
<blockquote><font face="monospace">main.c:5:24: error: roletrando.h: Arquivo ou diretório não encontrado</font></p></blockquote>
<p>Sem o arquivo <font face="monospace">roletrando.h</font>, o compilador não sabe uma grande quantidade de coisas, como, por exemplo, qual o valor de <font face="monospace">TAMANHO_PALAVRAS</font>. Em alguns compiladores modernos, o compilador é de certa forma &#8220;inteligente&#8221; a ponto de conseguir evitar erros mais sérios, como em funções básicas como <font face="monospace">malloc</font> e <font face="monospace">printf</font>, mas ainda assim o sistema possui problemas para determinar tudo o que o programa precisa saber para compilar. Portanto, vamos criar o arquivo <font face="monospace">roletrando.h</font>:<br />
<blockquote><font face="monospace">/*</font><br /><font face="monospace">&nbsp;* roletrando.h</font><br /><font face="monospace">&nbsp;*/</font></p>
<p><font face="monospace">#include &lt;stdio.h&gt;</font><br /><font face="monospace">#include &lt;stdlib.h&gt;</font><br /><font face="monospace">#include &lt;time.h&gt;</font><br /><font face="monospace">#include &lt;string.h&gt;</font></p>
<p><font face="monospace">#define NUM_TENTATIVAS 6</font><br /><font face="monospace">#define TAMANHO_PALAVRAS 20</font></p>
<p><font face="monospace">int checaLetra (const char* palavraEscolhida, const char* letrasCertas, char letra);</font><br /><font face="monospace">void explicarRegras (void);</font><br /><font face="monospace">int contaFaltantes (const char* letrasCertas);</font><br /><font face="monospace">int testaCerto (const char* palavraEscolhida, int* tentativasErradas);</font></p></blockquote>
<p>Aqui, é interessante comparar o <i>header file</i> com o nosso &#8220;programa original&#8221;: perceba que é como se tivéssemo pego o código do início da nossa &#8220;versão original&#8221; e extraído apenas as primeiras linhas, até o início da função <font face="monospace">main()</font> e colocado ele no arquivo de cabeçalho. <br />&#8220;<i>Então eu posso colocar qualquer código C em um arquivo de cabeçalho?</i>&#8220;<br />Sim, você pode, mas NÃO, você não deveria.<br />Ao colocar código convencional no arquivo de cabeçalho, você está jogando fora todas as vantagens relacionadas à separação de código em arquivos individuais E adicionando problemas adicionais. Por exemplo: imagine que você tenha adicionado uma função real (não um protótipo) a um arquivo de cabeçalho que será usado em vários arquivos de código fonte. Ao compilar o código, o compilador irá &#8220;adicionar&#8221; ao código fonte original o arquivo de cabeçalho e o compilará. Aqui parece OK. Mas, quando o <i>linker</i> ou o compilador forem fazer as ligações do código, haverá VÁRIAS cópias da mesma função em forma de código binário para o <i>linker</i> usar. Como ele não saberá qual usar, ele provocará mensagens de erro.<br />Como boa prática, podemos considerar que um arquivo de cabeçalho deve restringir-se a:
<ol>
<li>Diretivas de pré-processador, como #include ou #define, que serão usadas por todos os arquivos que incluirem esse arquivo de cabeçalho, e;</li>
<li>Protótipos de função;</li>
</ol>
<p>Obviamente você pode incluir qualquer coisa válida em um programa C &#8220;normal&#8221;, mas isso aumentaria a complexidade do código, jogaria fora todas as vantagens do isolamento de código e colocaria potenciais erros e <i>bugs</i>.<br />OK, podemos agora compilar o nosso código fonte sem aquele monte de mensagens de erro. Porém, ao tentarmos compilar o código em <font face="monospace">main.c</font>, teremos a seguinte mensagem de erro:</div>
<blockquote><p><font face="monospace">/tmp/ccrd9zr4.o: In function `main&#8217;:</font><br /><font face="monospace">main.c:(.text+0x32c): undefined reference to `explicarRegras&#8217;</font><br /><font face="monospace">main.c:(.text+0x4c7): undefined reference to `checaLetra&#8217;</font><br /><font face="monospace">main.c:(.text+0&#215;509): undefined reference to `contaFaltantes&#8217;</font><br /><font face="monospace">main.c:(.text+0x53f): undefined reference to `contaFaltantes&#8217;</font><br /><font face="monospace">main.c:(.text+0&#215;558): undefined reference to `testaCerto&#8217;</font><br /><font face="monospace">collect2: ld returned 1 exit status</font></p></blockquote>
<p>Se você parar para pensar, vai notar que realmente não implementamos nenhuma das funções mostradas na mensagem de erro e, embora o compilador &#8220;saiba da existência&#8221; das mesmas (devido aos arquivos de cabeçalho), não sabe onde elas estão (elas não estão aí mesmo) e, portanto, não consegue gerar o código fonte em questão.<br />Portanto, vamos implementar as funções que faltam por meio dos dois arquivos que faltam, que são <font face="monospace">regras.c</font>:<br />
<blockquote><font face="monospace">/*<br />&nbsp;* regras.c<br />&nbsp;*/</p>
<p>#include &#8220;roletrando.h&#8221;</p>
<p>void explicarRegras (void)<br />{<br />&nbsp; // Explicando as regras do jogo para o jogador<br />&nbsp; printf (&#8220;Okay, vamos explicar as regras!\n&#8221;);<br />&nbsp; printf (&#8220;Eu conheco algumas palavras, e vou escolher aleatoriamente uma delas.\n&#8221;);<br />&nbsp; printf (&#8220;Voce vai me dizer qual letra voce acha que essa palavra tem!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce errar, vou considerar uma tentativa errada!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce acertar, vou te mostrar onde as letras estao!\n&#8221;);<br />&nbsp; printf (&#8220;Quando voce tiver acertado metade das palavras, vou te dar &#8220;);<br />&nbsp; printf (&#8220;a chance de dizer qual palavra e essa. \n&#8221;);<br />&nbsp; printf (&#8220;Se voce errar, vou considerar uma tentativa errada!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce acertar antes de acabar as tentativas, voce vence!\n\n\n&#8221;);<br />&nbsp; printf (&#8220;Algumas observacoes:\n&#8221;);<br />&nbsp; printf (&#8220;Voce tem %d tentativas que voce pode errar.\n&#8221;,NUM_TENTATIVAS);<br />&nbsp; printf (&#8220;Nenhuma palavra possui acentos, cedilha ou trema.\n&#8221;);<br />&nbsp; printf (&#8220;Nao estou diferenciando maisculas e minusculas. \n\n&#8221;);<br />}</p>
<p>int testaCerto (const char* palavraEscolhida, int *tentativasErradas)<br />{<br />&nbsp; char *minhaResposta;</p>
<p>&nbsp; minhaResposta=(char*)malloc(strlen(palavraEscolhida)+1);<br />&nbsp; memset(minhaResposta,&#8221;, strlen(palavraEscolhida)+1);</p>
<p>&nbsp; if (!minhaResposta)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao consegui alocar memoria!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; char *conversao=minhaResposta;<br />&nbsp; printf(&#8220;Qual palavra voce acha que e essa? &#8220;);<br />&nbsp; fgets(minhaResposta,strlen(palavraEscolhida)+1,stdin);</p>
<p>&nbsp; // Convertendo para minusculas e eliminando os caracteres de nova linha &#8211; \n<br />&nbsp; while (*conversao)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *conversao=((*conversao&gt;=&#8217;A')&amp;&amp;(*conversao&lt;=&#8217;Z'))?*conversao-&#8217;A'+&#8217;a':*conversao;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conversao++;<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; minhaResposta[strlen(minhaResposta)]=&#8221;;</p>
<p>&nbsp; if(strncmp(minhaResposta,palavraEscolhida,strlen(palavraEscolhida))==0)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(minhaResposta);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp; else<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Que pena, voce errou!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*tentativasErradas)++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(minhaResposta);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);<br />&nbsp;&nbsp;&nbsp; }<br />}</font></p></blockquote>
<p>E letras.c:<br />
<blockquote><font face="monospace">/*</font><br /><font face="monospace">&nbsp;* letras.c</font><br /><font face="monospace">&nbsp;*/</font></p>
<p><font face="monospace">#include &#8220;roletrando.h&#8221;</font></p>
<p><font face="monospace">int checaLetra (const char* palavra, const char* letrasCertas, char letra)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; // Acertos obtidos (0 indica que nao tem a letra em questao na palavra)</font><br /><font face="monospace">&nbsp; int acertos=0;</font></p>
<p><font face="monospace">&nbsp; // Ponteiros a serem inicializados</font><br /><font face="monospace">&nbsp; char *palavraAnalisada, *certas;</font></p>
<p><font face="monospace">&nbsp; // Inicialidando os ponteiros com os valores recebidos</font><br /><font face="monospace">&nbsp; palavraAnalisada=(char*)palavra;</font><br /><font face="monospace">&nbsp; certas=(char*)letrasCertas;</font></p>
<p><font face="monospace">&nbsp; char letraComparada=((letra&gt;=&#8217;A')&amp;&amp;(letra&lt;=&#8217;Z'))?letra-&#8217;A'+&#8217;a':letra;</font></p>
<p><font face="monospace">&nbsp; while (*palavraAnalisada)</font><br /><font face="monospace">&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; if (*palavraAnalisada==letraComparada)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; acertos++;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; *certas=letraComparada;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; palavraAnalisada++;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; certas++;</font><br /><font face="monospace">&nbsp; }</font></p>
<p><font face="monospace">&nbsp; return acertos;</font><br /><font face="monospace">}</font></p>
<p><font face="monospace">int contaFaltantes(const char* letrasCertas)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; char *letras=(char*)letrasCertas;</font><br /><font face="monospace">&nbsp; int faltantes=0;</font></p>
<p><font face="monospace">&nbsp; while (*letras) if (*(letras++)==&#8217;-') faltantes++;</font></p>
<p><font face="monospace">&nbsp; return faltantes;</font><br /><font face="monospace">}</font></p></blockquote>
<p>OK, você deve estar pensando&#8230;<br />E agora, como compilar esse programa?<br />Se você tentar compilar apenas um dos dois últimos códigos, você receberá uma mensagem de erro como a seguinte:<br />
<blockquote><font face="Courier New">/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o: In function `_start&#8217;:</font><br /><font face="Courier New">(.text+0&#215;18): undefined reference to `main&#8217;</font><br /><font face="Courier New">collect2: ld returned 1 exit status</font></p></blockquote>
<p>Isso quer dizer que o compilador compilou corretamente o código, mas o <i>linker</i> não encontrou nenhuma função <font face="Courier New">main()</font>. Portanto, o comando padrão de compilação que usamos desde o começo do curso, que vimos <a href="http://aulasdec.wordpress.com/2010/11/05/o-primeiro-programa-helloworld-c/">lá atrás</a>:<br /><a href="http://aulasdec.wordpress.com/2010/11/05/o-primeiro-programa-helloworld-c/">O primeiro programa: HelloWorld.c « Aulas de C</a><br />
<blockquote>Entre no mesmo diretório onde você gravou o seu <font face="monospace">HelloWorld.c </font>e digite o seguinte comando:<br /><font face="monospace">    gcc -o HelloWorld HelloWorld.c</font></p></blockquote>
<p>Já não serve mais.<br />Existem duas formas de compilar-se o código fonte com arquivos individuais e obter-se o binário. A primeira é utilizar-se o comando:<br />
<blockquote><font face="monospace">gcc -o roletrando main.c regras.c letras.c</font></p></blockquote>
</div>
<div align="justify">Perceba que a única diferença aqui entre isso e o que temos feito desde sempre é que adicionamos os arquivos <font face="monospace">.c </font>adicionais após o <font face="monospace">main()</font>. Entretanto esse método não oferece grandes vantagens: você ainda gastará muito tempo compilando código-fonte pois, embora o código esteja separado, o compilador precisará reuní-lo antes de compilar e ligar o código. Desse modo, ao menos um dos benefícios da separação dos códigos em arquivos individuais terá sido perdida (você ainda gastará muito tempo compilando todo o código, inclusive os trecho que não mudaram).<br />O método que nos permite os melhores benefícios é aquele em dois passos, onde (1) o compilador gera cada um dos arquivos binários de cada código fonte e (2) o <i>linker</i> gera o binário final a partir do código binário gerado pelo compilador previamente. Cada compilador tem sua metodologia para gerar esse processo, e você deve ler cuidadosamente a documentação do seu compilador.<br />No GCC, primeiro iremos gerar o código binário (que chamaremos de <i>código-objeto</i> para distingüir do binário final, ou <i>executável</i>), por meio do comando:<br />
<blockquote><font face="monospace">gcc -o nome_do_codigo_objeto.o -c meu_arquivo_fonte.c</font></p></blockquote>
<p>A opção -c do compilador GCC apenas faz a compilação do código, sem tentar fazer o <i>link</i>, conforme dito na documentação do mesmo:<br />
<blockquote><font face="monospace">-c&nbsp;</font> Compile or assemble the source files, but do not link.&nbsp; The linking stage simply is not done.&nbsp; The ultimate output is in the form of an object file for each source file.<br />By default, the object file name for a source file is made by replacing the suffix<font face="monospace"> .c, .i, .s</font>, etc., with <font face="monospace">.o</font>.<br />Unrecognized input files, not requiring compilation or assembly, are ignored.</p></blockquote>
<p>Ou seja, ele não gerará o o executável.</div>
<p>No nosso caso, utilizaremos primeiro os comandos:<br />
<blockquote><font face="monospace">gcc -o letras.o -c letras.c</font><br /><font face="monospace">gcc -o regras.o -c regras.c</font><br /><font face="monospace">gcc -o main.o -c main.c</font></p></blockquote>
<p>Para gerarmos os arquivos <font face="monospace">.o</font> (os códigos-objeto) de cada um dos código-fonte e, após isso, utilizaremos o comando:<br />
<blockquote><font face="monospace">gcc -o roletrando letras.o regras.o main.o</font></p></blockquote>
<p>Para fazermos o <i>link</i> das funções e obtermos o executável.
<div align="justify">É interessante notar que, no caso específico do GCC, ele possui alguma inteligência e é capaz de distinguir código-fonte de código-objeto. Portanto, a última linha do nosso primeiro passo:<br />
<blockquote><font face="monospace">gcc -o main.o -c main.c</font></p></blockquote>
<p>Poderia ser substituída por:<br />
<blockquote><font face="monospace">gcc -o roletrando letras.o regras.o main.c</font></p></blockquote>
<p>Sem problemas. Normalmente, porém, fazemos o passo da geração de arquivos objetos para cada arquivo-fonte.<br />&#8220;<i>E onde está o ganho? Até agora, gastei mais tempo lançando comandos!</i>&#8221; você deve estar se perguntando.<br />Imagine que você está traduzindo o jogo do roletrando para um outro idioma e tem que, portanto, mexer na função<font face="monospace"> explicarRegras()</font>, em <font face="monospace">regras.c</font>. Se você tiver com todos os códigos-objetos gerados, tudo o que você precisará fazer é gerar novamente o código-objeto de <font face="monospace">regras.c</font> (<font face="monospace">regras.o</font>) e refazer o executável com o comando para fazer o <i>link</i> das funções.<br />Existem muitas outras vantagens em usarmos esse método, mas não vem ao caso agora. Falaremos sobre outras vantagens no futuro.<br />Como &#8220;brincadeira&#8221;, tente visualizar os programas que criamos até agora e que usam funções, e tente recriá-los, separando as funções em arquivos fontes individuais e criando arquivos de cabeçalho para esses códigos. Esse processo é algo padrão no desenvolvimento de software e é algo muito comum.<br />Na nossa próxima &#8220;aula&#8221;, continuaremos esse assunto, aprofundando um pouco na automação da construção de binários a partir de arquivos de código fonte individuas e outras estratégias para organização de projetos.</div>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" alt="" src="http://img.zemanta.com/pixy.gif?x-id=b5dc835b-cf8d-8e5f-9e67-0dd405906d73" /></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/131/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/131/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/131/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=131&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2011/07/09/sobre-arquivos-de-codigo-fonte-arquivos-de-cabecalhos-e-projetos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>

		<media:content url="http://img.zemanta.com/pixy.gif?x-id=b5dc835b-cf8d-8e5f-9e67-0dd405906d73" medium="image" />
	</item>
		<item>
		<title>Matrizes e Ponteiros – Parte 3 – Ponteiros e Funções</title>
		<link>https://aulasdec.wordpress.com/2011/04/18/matrizes-e-ponteiros-%e2%80%93-parte-3-%e2%80%93-ponteiros-e-funcoes/</link>
		<comments>https://aulasdec.wordpress.com/2011/04/18/matrizes-e-ponteiros-%e2%80%93-parte-3-%e2%80%93-ponteiros-e-funcoes/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 18:52:02 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Funções]]></category>
		<category><![CDATA[Ponteiros]]></category>

		<guid isPermaLink="false">http://aulasdec.wordpress.com/?p=81</guid>
		<description><![CDATA[Olá! Esse tópico será um pouco diferenciado, portanto vou avisando que será BEM MAIS LONGO e complexo do que os anteriores. Isso porque iremos ver como as funções em C são afetadas pelos ponteiros. É um tópico bem avançado em teoria, mas é interessante mencioná-lo agora, enquanto os conceitos relacionados a ponteiros estão &#8220;frescos&#8221; na [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=81&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá!</p>
<div align="justify">Esse tópico será um pouco diferenciado, portanto vou avisando que será BEM MAIS LONGO e complexo do que os anteriores. Isso porque iremos ver como as funções em C são afetadas pelos ponteiros. É um tópico bem avançado em teoria, mas é interessante mencioná-lo agora, enquanto os conceitos relacionados a ponteiros estão &#8220;frescos&#8221; na memória. Na verdade, esse tópico será dividido em dois subtópicos:
<ul>
<li>Ponteiros de função, ou seja, usar um ponteiro para chamar diferentes funções decididas <i>em tempo de programação</i>. Isso é muito usado, por exemplo, em <i>plugins</i> de programas. Dizendo de maneira bem simplista, poderíamos carregar para a memória o conteúdo de um arquivo e fornecer o endereço onde esse conteúdo carregado se localiza para um ponteiro de função que o sistema executaria esse código dinamicamente (na verdade, existem mais complicadores, mas em termos gerais podemos dizer isso);</li>
<li>Passagem de ponteiros para funções: existem detalhes a serem mencionados quando passamos um ponteiro para uma função. Isso ocorre com muita freqüencia, uma vez que muitos &#8220;tipos&#8221; que um programador pode esperar de uma linguagem de programação (como <i>strings,</i> filas, listas, etc&#8230;) são resolvidas em C pelo uso de ponteiros;</li>
</ul>
<p>Bem, vamos começar com o primeiro de nossos subtópicos:<br />
<h3>Ponteiros de Função</h3>
<p>Como já cansamos de dizer nesse &#8220;curso&#8221;, ponteiros são variáveis que armazenam um endereço no qual está um determinado conteúdo. Se pensarmos dessa forma, podemos imaginar que isso possa se aplicar a trechos de código.<br /><i>&#8220;Por que?&#8221;</i>, você deve se perguntar. Porque, embora o código não fique no <i>heap</i> ou em outros pontos de memória como os dos dados, ele PRECISA ESTAR na memória para funcionar. Ou seja, se um código não estiver carregado na memória RAM (ao menos no momento da execução), ele não pode ser executado. De fato, quando chamamos um programa binário, a primeira coisa que o sistema operacional faz é chamar uma rotina chamada LOADER para copiar os conteúdos do arquivo onde o binário se encontra para um espaço de memória específico (programas podem eles próprio solicitarem ao SO para carregarem partes de si que ficaram de fora da memória em tempo de execução &#8211; isso se chama carga dinâmica e é um tópico mais avançado, que não iremos tratar em um futuro próximo). Em seguida, são feitos procedimentos para iniciar a execução do programa que mudam conforme a arquitetura do sistema operacional e do hardware, mas em geral envolve inicializar uma série de variáveis de baixo nível do sistema operacional e algumas informações no nível dos registradores de hardware (um registrador é um espaço de memória muito pequeno que é usado diretamente pela CPU para coordenar as operações de sistema. Fundamentalmente são eles que carregam as informações e códigos &#8220;para dentro&#8221; da CPU e &#8220;devolvem&#8221; o resultado). De qualquer modo, o programa é carregado em memória e em seguida inicializado sua execução.<br />Quando um programa encontra uma chamada a uma função, ele &#8220;salta&#8221; para o local de memória onde o código daquela função está e começa a executar o código da função (existem certos procedimentos internos para impedir que a execução da função afete de maneira indesejada o funcionamento do código que a chamou, mas não entraremos em detalhes aqui). Ao terminar essa execução, ele &#8220;volta&#8221; para o comando seguinte ao qual a função foi chamado. Para isso, obviamente o sistema armazena antes as informações sobre onde ele estava antes de a função ser chamada.<br />Se pensarmos bem, vamos ver que o tempo todo existe manipulação de endereços no momento da execução de código. E se há endereços, há ponteiros!<br />Chega de papo! Nosso programa exemplo da vez é uma &#8220;calculadora&#8221; simples. O código é o seguinte:<br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt;</font><br /><font face="monospace">#include &lt;stdlib.h&gt;  </font></p>
<p><b><font face="monospace" color="#006600">int soma (int, int);</font><font color="#006600"><br /></font><font face="monospace" color="#006600">int subtracao (int, int);</font><font color="#006600"><br /></font><font face="monospace" color="#006600">int multiplicacao (int, int);</font><font color="#006600"><br /></font><font face="monospace" color="#006600">int divisao (int, int);</font></b></p>
<p><font face="monospace">int main(void)</font><br /><font face="monospace">{</font><br /><b><font face="monospace" color="#cc0000">&nbsp; int (*funcPointer)(); // o meu ponteiro de funcao vem aqui</font></b></p>
<p><font face="monospace">&nbsp; int a=0,b=0,c=0,oper=0;</font></p>
<p><font face="monospace">&nbsp; printf (&#8220;Entre com dois numeros inteiros separados por espaco: &#8220;);</font><br /><font face="monospace">&nbsp; scanf (&#8220;%d %d&#8221;, &amp;a, &amp;b);</font></p>
<p><font face="monospace">&nbsp; do</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;Escolha uma operação a se realizar com esses numeros:\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;1-) Soma\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;2-) Subtracao\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;3-) Multiplicacao\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;4-) Divisao\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;, &amp;oper);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; } while (!((oper&gt;=1) &amp;&amp; (oper&lt;=4)));</font></p>
<p><font face="monospace">&nbsp; switch(oper)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; case 1:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font><br /><b><font face="monospace" color="#000099">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; funcPointer=soma;</font></b><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; case 2:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font><br /><b><font face="monospace" color="#000099">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; funcPointer=subtracao;</font></b><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; case 3:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font><br /><b><font face="monospace" color="#000099">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; funcPointer=multiplicacao;</font></b><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; case 4:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font><br /><b><font face="monospace" color="#000099">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; funcPointer=divisao;</font></b><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }</font></p>
<p><b><font face="monospace" color="#339999">&nbsp; c=(*funcPointer)(a,b);</font></b></p>
<p><font face="monospace">&nbsp; printf(&#8220;O resultado da operacao desejada com os valores %d e %d e %d\n&#8221;,a,b,c);</font></p>
<p><b><font face="monospace" color="#993399">&nbsp; printf(&#8220;A funcao usada para executar a operacao desejada localiza-se em %p\n&#8221;,funcPointer);</font></b></p>
<p><font face="monospace">&nbsp; return(0);</font></p>
<p><font face="monospace">}</font></p>
<p><b><font face="monospace" color="#006600">int soma (int a, int b)</font></b><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; return a+b;</font><br /><font face="monospace">}</font></p>
<p><b><font face="monospace" color="#006600">int subtracao (int a, int b)</font></b><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; return a-b;</font><br /><font face="monospace">}</font></p>
<p><b><font face="monospace" color="#006600">int multiplicacao (int a, int b)</font></b><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; return a*b;</font><br /><font face="monospace">}</font></p>
<p><b><font face="monospace" color="#006600">int divisao (int a, int b)</font></b><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; if (b==0)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao posso dividir nada por zero!\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp; return a/b;</font><br /><font face="monospace">}</font></p></blockquote>
</div>
<div align="justify">Bem, se observarmos bem, não existem grandes novidades aqui. Portanto, vamos nos restringir às explicações sobre os ponteiros de função. A primeira coisa importante a se notar está na declaração do ponteiro de função:<br />
<blockquote><b><font face="monospace" color="#cc0000">&nbsp; int (*funcPointer)(); // o meu ponteiro de funcao vem aqui</font></b></p></blockquote>
<p>Se você reparar, lembra <i>levemente</i> um protótipo de uma função. Porém, perceba que você tem o <b><font face="monospace" color="#cc0000">(*funcPointer)()</font></b>, que indica que é um ponteiro de função. Poderíamos ler esse código como &#8220;<font face="monospace"><i>funcPointer</i></font> é um ponteiro que aponta para o código de uma função que devolve <font face="monospace">int</font>&#8220;. Outra coisa a se notar é que aqui não tentamos resolver a parte da parametrização. Isso é importante de ser lembrado pois em teoria você pode usar <font face="monospace">funcPointer</font> para executar qualquer função que retorne <font face="monospace">int</font>. No momento em que usarmos o ponteiro de função, porém, é o momento no qual teremos que &#8220;resolver&#8221; a parte da parametrização. No momento, basta saber que aqui na realidade declaramos uma varíavel, ponteiro, que irá apontar para o código de uma função que irá retornar um valor <font face="monospace">int</font>.<br />Em seguida, temos um switch&#8230;case que se baseia em um valor que passamos para ele como um <font face="monospace">int</font> para decidir qual a operação a ser feita. Cada número possui um código similar ao abaixo:<br />
<blockquote><b><font face="monospace" color="#000099">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; funcPointer=multiplicacao;</font></b></p></blockquote>
<p>Se olharmos no início, veremos que declaramos funções que irão retornar valores int (ou seja, do tipo que é aceito por <font face="monospace">funcPointer</font>):<br />
<blockquote><b><font face="monospace" color="#006600">int soma (int, int);</font></b><b><font color="#006600"><br /></font><font face="monospace" color="#006600">int subtracao (int, int);</font></b><b><font color="#006600"><br /></font><font face="monospace" color="#006600">int multiplicacao (int, int);</font></b><b><font color="#006600"><br /></font><font face="monospace" color="#006600">int divisao (int, int);</font></b></p></blockquote>
</div>
<div align="justify">OK. Mas a sua pergunta deve ser <i>&#8220;como o C sabe tratar as coisas nesse caso?&#8221;</i>. Para o C, se você passa o nome de uma função <i>sem os seus parâmetros</i>, você está na realidade passando uma variável, ponteiro, para uma função cujo retorno será o tipo que a função retorna. Se pegarmos o nosso caso:<br />
<blockquote><b><font face="monospace" color="#000099">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; funcPointer=multiplicacao;</font></b></p></blockquote>
<p>Veremos que na nossa lista de funções declaradas existe uma função <b><font face="monospace" color="#006600">int multiplicacao (int, int);</font></b>. Desse modo, o C trata o <font face="monospace">multiplicacao</font> nesse caso não como um comando, mas como uma variável. Portanto, ele devolverá o endereço da posição de memória onde essa função começa. Isso é comprovado pelo comando:<br />
<blockquote><b><font face="monospace" color="#993399">&nbsp; printf(&#8220;A funcao usada para executar a operacao desejada localiza-se em %p\n&#8221;,funcPointer);</font></b></p></blockquote>
</div>
<p>que irá exibir o endereço de memória onde a função está armazenada.
<div align="justify">Voltando ao programa: já sabemos como declarar um ponteiro de função (algo como <font face="monospace">tipo (*nomeDoPonteiroDeFuncao)()</font>) e sabemos como passar o endereço para um ponteiro de função (como para qualquer outro). E para executarmos esse comando, como fazemos?<br />
<blockquote><b><font face="monospace" color="#339999">&nbsp; c=(*funcPointer)(a,b);</font></b></p></blockquote>
</div>
<p>É dessa forma. Usamos uma escrita similar à da declaração do ponteiro, <i>mas agora indicando os parâmetros desejados</i>. <b><br /></b>
<div align="center"><b><big><big>AQUI MORA DRAGÕES!!!</big></big></b>
<div align="justify">O C não faz checagem de cabeçalho de função e das tipagens envolvidas em um ponteiro de função. Isso passa a ser responsabilidade do programador, tomar os cuidados de passar os parâmetros da forma correta. Portanto, devemos ter muito cuidado quanto à parametrização das funções a serem passadas via poibteiros de função. Em geral, quando precisamos desse recurso, utilizamos algum tipo de padronização dos parâmetros. Mesmo assim, vale a ressalva de que se tome muito cuidado com isso.<br />Perceba uma coisa: o retorno da função executada pelo ponteiro é armazenado na variável <font face="monospace">int c.</font> Se o retorno para o ponteiro de função fosse <font face="monospace">void</font>, não teríamos necessidade de guardar retorno nenhum. Os retornos continuam sendo resolvidos normalmente e <i>warnings</i> e erros são retornados por devolver retornos errados. Mas temos que tomar cuidado também quanto a isso: imagine que você declare a função <font face="monospace">divisao</font> como retornando <font face="monospace">float</font>. Embora o compilador retorne um <i>warning</i> relacionado à passagem de tipo incompatível, ainda assim ele irá gerar o código binário (você consegue evitar isso usando as opções de <i>compilação pedântica</i> do seu compilador &#8211; consulte a documentação do mesmo para maiores informações).<br />De resto, o código não possui muitos mistérios: uma vez que o <i>switch</i> escolha a função a ser executada, baseada na entrada do usuário, o ponteiro <i>funcPointer</i> recebe o endereço da mesma. Em seguida, é feita a execução da mesma, como dissemos anteriormente, e o valor é retornando para a varável <font face="monospace">c</font>. Por fim, os comandos <font face="monospace">printf</font> ao final de <font face="monospace">main</font> exibira os resultados e o endereço onde a função alocada se encontra. Como &#8220;brincadeira&#8221;, para você entender melhor, mexa a seqüência nas quais as funções estão dispostas no código fonte. Essa seqüência meio que determina qual função ficará primeiro no código binário. Assim você poderá perceber que o código é manipulado não importa onde.<br />Bem, brinque um pouco com esse programa para entender ponteriros de função.<br />
<h3>Passagem de ponteiros (Passagem por referência e por valor):<br /></h3>
<p>Até agora, todas as nossas funções tem passado seus parâmetros <i>por valor</i>, ou seja, passamos uma cópia da informação armazenada na variável que passamos. Isso permite um certo isolamento entre a função chamada e a que chama, o que garante uma segurança quanto aos conteúdos da variável &#8220;local&#8221;.<br />Porém, em muitas situações em C, precisamos manipular diretamente a informação das variáveis em uma função. Um exemplo de função que faz isso é a função da biblioteca STDIO <font face="monospace">scanf</font>. Ela precisa saber onde está a variável cujo conteúdo será alterado para fazer a leitura da informação via teclado (utilizando-se do sistema operacional) e gravando o conteúdo no mesmo local apontado pela varíavel em questão. Isso é chamado tecnicamente de <i>Passagem de parâmetros por referência</i> e com isso o conteúdo no endereço apontado pela variável pode ser manipulado.<br />O C oferece, através dos ponteiros, formas de passarmos parâmetros por referência. Veremos isso no nosso próximo programa, que é uma brincadeira similar ao programa de TV Roda-a-Roda (antigo Roletrando):<br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;time.h&gt;<br />#include &lt;string.h&gt;</p>
<p>#define NUM_TENTATIVAS 6<br />#define TAMANHO_PALAVRAS 20</p>
<p><font color="#663366"><b>int checaLetra (const char* palavraEscolhida, const char* letrasCertas, char letra);<br />void explicarRegras (void);<br />int contaFaltantes (const char* letrasCertas);<br />int testaCerto (const char* palavraEscolhida, int* tentativasErradas);<br /></b></font><br />int main (void)<br />{</p>
<p>&nbsp; // Declarando variaveis</p>
<p>&nbsp; // Biblioteca de palavras<br /><font color="#660000"><b>&nbsp; char palavras[][TAMANHO_PALAVRAS]={&#8220;rotina&#8221;, &#8220;retina&#8221;, &#8220;palhaco&#8221;, &#8220;lembranca&#8221;, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;sistema&#8221;, &#8220;musica&#8221;,&#8221;curioso&#8221;, &#8220;fantasia&#8221;,<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &#8220;malabares&#8221;,&#8221;sonhador&#8221;,&#8221;atitude&#8221;,&#8221;pacoca&#8221;};</p>
<p>&nbsp; // Ponteiros necessarios<br />&nbsp; char *palavraEscolhida, *letrasCertas;</p>
<p>&nbsp; // Algumas variaveis de apoio<br />&nbsp; int tentativasErradas=0,i;</p>
<p></b></font>&nbsp; explicarRegras();</p>
<p>&nbsp; srand(time(NULL)); // Serve para modificar a tabela de nÃºmeros pseudo-aleatÃ³rios</p>
<p>&nbsp; palavraEscolhida=palavras[rand()%((sizeof(palavras)/TAMANHO_PALAVRAS)-1)];</p>
<p>&nbsp; letrasCertas=malloc(strlen(palavraEscolhida)+1);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />&nbsp; if (!letrasCertas)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao consegui alocar memoria!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; memset(letrasCertas,&#8221;, strlen(palavraEscolhida)+1);<br />&nbsp; memset(letrasCertas,&#8217;-', strlen(palavraEscolhida));</p>
<p>&nbsp; int tentativaAtual=0;<br />&nbsp; while(tentativasErradas<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char minhaLetra;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tentativaAtual++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;Okay, tentativa no %d (%d tentativas erradas):&#8221;, tentativaAtual, tentativasErradas);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf (&#8220;%c&#8221;, &amp;minhaLetra);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getchar();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!checaLetra(palavraEscolhida,letrasCertas,minhaLetra))<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp; printf(&#8220;Que pena, essa letra nao aparece!\n&#8221;);<br />&nbsp;&nbsp;&nbsp; &nbsp; tentativasErradas++;<br />&nbsp;&nbsp;&nbsp; &nbsp; continue;<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;A palavra ate agora e: %s\n&#8221;,letrasCertas);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (contaFaltantes(letrasCertas)&lt;=(strlen(palavraEscolhida)/2))<br />&nbsp;&nbsp;&nbsp; {<br /><font color="#006600"><b>&nbsp;&nbsp;&nbsp; &nbsp; if((contaFaltantes(letrasCertas)==0)||testaCerto(palavraEscolhida,&amp;tentativasErradas))</b></font><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Muito bem! VocÃª acertou!\n&#8221;);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p>void explicarRegras (void)<br />{<br />&nbsp; // Explicando as regras do jogo para o jogador<br />&nbsp; printf (&#8220;Okay, vamos explicar as regras!\n&#8221;);<br />&nbsp; printf (&#8220;Eu conheco algumas palavras, e vou escolher aleatoriamente uma delas.\n&#8221;);<br />&nbsp; printf (&#8220;Voce vai me dizer qual letra voce acha que essa palavra tem!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce errar, vou considerar uma tentativa errada!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce acertar, vou te mostrar onde as letras estao!\n&#8221;);<br />&nbsp; printf (&#8220;Quando voce tiver acertado metade das palavras, vou te dar &#8220;);<br />&nbsp; printf (&#8220;a chance de dizer qual palavra e essa. \n&#8221;);<br />&nbsp; printf (&#8220;Se voce errar, vou considerar uma tentativa errada!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce acertar antes de acabar as tentativas, voce vence!\n\n\n&#8221;);<br />&nbsp; printf (&#8220;Algumas observacoes:\n&#8221;);<br />&nbsp; printf (&#8220;Voce tem %d tentativas que voce pode errar.\n&#8221;,NUM_TENTATIVAS);<br />&nbsp; printf (&#8220;Nenhuma palavra possui acentos, cedilha ou trema.\n&#8221;);<br />&nbsp; printf (&#8220;Nao estou diferenciando maisculas e minusculas. \n\n&#8221;);<br />}</p>
<p><font color="#ff0000"><b>int checaLetra (const char* palavra, const char* letrasCertas, char letra)<br />{<br />&nbsp; // Acertos obtidos (0 indica que nao tem a letra em questao na palavra)<br />&nbsp; int acertos=0;</p>
<p>&nbsp; // Ponteiros a serem inicializados<br />&nbsp; char *palavraAnalisada, *certas;<br />&nbsp; <br />&nbsp; // Inicialidando os ponteiros com os valores recebidos<br />&nbsp; palavraAnalisada=palavra;<br />&nbsp; certas=letrasCertas;</p>
<p>&nbsp; char letraComparada=((letra&gt;=&#8217;A')&amp;&amp;(letra&lt;=&#8217;Z'))?letra-&#8217;A'+&#8217;a':letra;</p>
<p>&nbsp; while (*palavraAnalisada)<br />&nbsp; {<br />&nbsp;&nbsp;&nbsp; if (*palavraAnalisada==letraComparada)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; acertos++;<br />&nbsp;&nbsp;&nbsp; *certas=letraComparada;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; palavraAnalisada++;<br />&nbsp;&nbsp;&nbsp; certas++;<br />&nbsp; }</p>
<p>&nbsp; return acertos;<br />}<br /></b></font><br /><b><font color="#000099">int contaFaltantes(const char* letrasCertas)<br />{<br />&nbsp; char *letras=letrasCertas;<br />&nbsp; int faltantes=0;</p>
<p>&nbsp; while (*letras) if (*(letras++)==&#8217;-') faltantes++;</p>
<p>&nbsp; return faltantes;<br />}</font></b></p>
<p><font color="#cc6600"><b>int testaCerto (const char* palavraEscolhida, int *tentativasErradas)<br />{<br />&nbsp; char *minhaResposta;</p>
<p>&nbsp; minhaResposta=(char*)malloc(strlen(palavraEscolhida)+1);<br />&nbsp; memset(minhaResposta,&#8221;, strlen(palavraEscolhida)+1);<br />&nbsp;&nbsp;&nbsp; &nbsp; <br />&nbsp; if (!minhaResposta)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao consegui alocar memoria!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; char *conversao=minhaResposta;<br />&nbsp; printf(&#8220;Qual palavra voce acha que e essa? &#8220;);<br />&nbsp; fgets(minhaResposta,strlen(palavraEscolhida)+1,stdin);</p>
<p>&nbsp; // Convertendo para minusculas e eliminando os caracteres de nova linha &#8211; \n<br />&nbsp; while (*conversao)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *conversao=((*conversao&gt;=&#8217;A')&amp;&amp;(*conversao&lt;=&#8217;Z'))?*conversao-&#8217;A'+&#8217;a':*conversao;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conversao++;<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; minhaResposta[strlen(minhaResposta)]=&#8221;;<br />&nbsp; <br />&nbsp; if(strncmp(minhaResposta,palavraEscolhida,strlen(palavraEscolhida))==0)<br />&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp; else<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Que pena, voce errou!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*tentativasErradas)++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);<br />&nbsp;&nbsp;&nbsp; }<br />}</b></font></font></p></blockquote>
<p>Existe pouca coisa nova aqui, à exceção do uso que faremos de passagem de ponteiros a funções e suas idiossincrásias. Inicialmente fazemos algumas inclusões e criamos duas constantes: NUM_TENTATIVAS e TAMANHO_PALAVRAS. Ambas são usadas para evitarmos &#8220;números mágicos&#8221;. Em especial, nós estamos incluindo a biblioteca padrão <font face="monospace">string.h</font>, que define funções especiais para <i>strings</i>, além de ter a função <font face="monospace">malloc()</font>, que precisaremos para alocar dinamicamente algum espaço de memória. Também declaramos quatro funções por meio de seus protótipos:<br />
<blockquote><font color="#663366"><b><font face="monospace">int checaLetra (const char* palavraEscolhida, const char* letrasCertas, char letra);</font><br /><font face="monospace"> void explicarRegras (void);</font><br /><font face="monospace"> int contaFaltantes (const char* letrasCertas);</font><br /><font face="monospace"> int testaCerto (const char* palavraEscolhida, int* tentativasErradas);</font></b></font></p></blockquote>
<p><font face="monospace"> </font>As funções <font face="monospace">checaLetra</font>, <font face="monospace">contaFaltantes</font> e <font face="monospace">testaCerto</font> são as funções que nos interessam. <font face="monospace">explicarRegras</font> não faz nada, exceto exibir algum texto informativo explicando o funcionamento do nosso jogo. Não vou me ater a explicar o jogo, pois o jogo mesmo irá se explicar. <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> <br />No main, começamos declarando todas as variáveis úteis:<br />
<blockquote><font face="monospace"><font color="#660000"><b>&nbsp; char palavras[][TAMANHO_PALAVRAS]={&#8220;rotina&#8221;, &#8220;retina&#8221;, &#8220;palhaco&#8221;, &#8220;lembranca&#8221;, </b></font></font><br /><font face="monospace"><font color="#660000"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;sistema&#8221;, &#8220;musica&#8221;,&#8221;curioso&#8221;, &#8220;fantasia&#8221;,</b></font></font><br /><font face="monospace"><font color="#660000"><b> &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &#8220;malabares&#8221;,&#8221;sonhador&#8221;,&#8221;atitude&#8221;,&#8221;pacoca&#8221;};</b></font></font><br /><font face="monospace"><font color="#660000"><b> </b></font></font><br /><font face="monospace"><font color="#660000"><b> &nbsp; // Ponteiros necessarios</b></font></font><br /><font face="monospace"><font color="#660000"><b> &nbsp; char *palavraEscolhida, *letrasCertas;</b></font></font><br /><font face="monospace"><font color="#660000"><b> </b></font></font><br /><font face="monospace"><font color="#660000"><b> &nbsp; // Algumas variaveis de apoio</b></font></font><br /><font face="monospace"><font color="#660000"><b> &nbsp; int tentativasErradas=0,i;</b></font></font></p></blockquote>
<p>Declaramos uma matriz bidimencional de caracteres (ou, para ser mais exato, uma matriz de <i>strings</i>), onde uma das dimensões está em branco e a outra tem como tamanho <font face="monospace"><font color="#660000"><b>TAMANHO_PALAVRAS</b></font></font>. Isso é permitido para no máximo uma dimensão: se uma dimensão estiver em branco, o C irá alocar o espaço suficiente para conter os elementos nela, mas APENAS se a inicialização acontecer no momento da declaração, como no nosso código. Em seguida, declaramos dois ponteiros de caracteres, <font face="monospace"><font color="#660000"><b>palavraEscolhida </b></font></font>e <font face="monospace"><font color="#660000"><b>letrasCertas</b></font></font>, e algumas variáveis de apoio.<br />Em seguida, o sistema chama <font face="monospace">explicarRegras</font> para explicar como funciona nosso jogo. Em seguida, usamos a função <font face="monospace">srand(time(NULL))</font> para gerarmos uma nova raiz de números pseudo-aleatórios (já vimos isso anteriormente, lembra?) e, usando<br />
<blockquote><font face="monospace">palavraEscolhida=palavras[rand()%((sizeof(palavras)/TAMANHO_PALAVRAS)-1)];</font></p></blockquote>
<p>escolhemos uma das palavras. <br />Aqui tem uma pegadinha de programação: se você se lembra bem, mencionamos anteriormente que para o C, matrizes e ponteiros são estruturas similares. Isso porque em C uma matriz nada mais é que uma quantidade de memória alocada pelo sistema e declarada em ponteiro. Isso vale também para matrizes quaisquer dimensão. Podemos, desse modo, utilizar uma técnica para apontar diretamente a matriz de maneira &#8220;correta&#8221; (na realidade, existe um <i>pequeno</i> <i>bug</i> aqui, que vou deixar como uma &#8220;brincadeira&#8221; para você, leitor, identificar. A pista é: tem a ver com o tamanho. Você vai entender a seguir). No caso, o que fazemos é fazer com que o sistema escolha uma posição no começo de uma palavra. Para isso, existe alguma matemática com a função <font face="monospace">rand</font>, usando o tamanho da matriz <font face="monospace">palavras</font> e o <font face="monospace">TAMANHO_PALAVRAS</font> de modo que <font face="monospace">rand</font> retorne um valor entre 0 e o número de palavras-1, devolvendo o endereço do início dessa palavra para <font face="monospace">palavraEscolhida</font>. Você pode se perguntar &#8220;e porque não copiar a palavra escolhida&#8221;. Isso é possível, mas é mais complexo e consome memória e tempo de processamento. Novamente: não pense em programação apenas para PCs, com seus gigas de memória e processamento. Pense, por exemplo, em um celular com alguns KB de espaço útil e poucos megahertz de processamento. Aproveitar a palavra que JÁ ESTÁ NA MEMÓRIA é uma idéia melhor. Nós veremos como usar essa informação de maneira segura já já.<br />Em seguida usamos <font face="monospace">malloc</font> para alocar um espaço de tamanho igual ao tamanho da palavra escolhida. Fazemos uma checagem para ver se a alocação foi bem sucedida (NUNCA SE ESQUEÇA DISSO!) e usamos a função memset para preencher a memória alocada com terminadores nulos e, em seguida, com hifens. Essa segunda variável irá armazenar aonde você já acertou na escolha das palavras.<br />Entramos então no <i>loop</i> principal. Declaramos um caracter e adicionamos um a cada tentativa. O caracter é só declarado, sem ser inicializado. Aqui podemos &#8220;quebrar&#8221; a boa prática de C de inicializar uma variável assim que declará-la, pois aqui não iremos fazer mais nada que ler um caracter. Não há problema imediato nesse caso, pois é uma leitura rápida e o endereço usado será sempre o mesmo (não estamos alocando dinamicamente esse caracter). O jogador recebe uma informação sobre o número de tentativas que ele fez e quantas ele já errou (o laço compara o valor de <font face="monospace">tentativasErradas</font> com o de <font face="monospace">NUM_TENTATIVAS</font>). Foi colocado um <font face="monospace">getchar()</font> para &#8220;limpar&#8221; qualquer caracter espúrio que tenha sobrado (em especial o ENTER).<br />E agora entramos em nossa primeira checagem: o jogador escolheu uma letra certa?<br />Para isso, temos a função:<br />
<blockquote><font color="#663366"><b><font face="monospace">int checaLetra (const char* palavraEscolhida, const char* letrasCertas, char letra);</font></b></font></p></blockquote>
<p><font color="#663366"><b><font face="monospace"> </font></b></font></div>
</div>
<p>Que recebe dois ponteiros e a letra a ser comparada.<br />Aqui existe um detalhe: os dois ponteiros são declarados como <i>const</i>.<br />&#8220;<i>Por que? Não queremos manipular o conteúdo deles?&#8221;</i>, você deve estar se perguntando.
<div align="justify">Aqui é importante clarificar uma coisa: quando você manda um ponteiro para uma função, ela tem, digamos assim, <i>poder total</i> sobre ele. Isso inclui trocar o endereço de memória para o qual o ponteiro aponta. Se você lembrar de quando usamos ponteiros para executar a função de Fibonacci, utilizamos dois ponteiros apontando para o mesmo lugar, sendo que um deles é que &#8220;se deslocaria&#8221; através do local alocado para armazenarmos os valores.<br />Para garantirmos que um ponteiro que estamos passando não vai ter seu endereço alterado, usamos a palavra-chave <i>const</i> antes do <font face="monospace">char*</font>, para indicarmos ao sistema que esse ponteiro é <i>constante</i> (ou seja, irá apontar SEMPRE para o mesmo lugar enquanto em uso), o que oferecerá uma garantia de que, mesmo que o CONTEÚDO do endereço apontado seja alterado, o ENDEREÇO não o seja. Por segurança, a não ser que você precise manipular os endereços apontados, sempre coloque <i>const</i> quando usar ponteiros em parâmetros de função.<br />Indo para a função <font face="monospace">checaLetra</font>, encontramos o seguinte código:<font face="monospace"><br /></font><br />
<blockquote><font face="monospace"><font color="#ff0000"><b>int checaLetra (const char* palavra, const char* letrasCertas, char letra)</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> {</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; // Acertos obtidos (0 indica que nao tem a letra em questao na palavra)</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; int acertos=0;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> </b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; // Ponteiros a serem inicializados</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; char *palavraAnalisada, *certas;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; </b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; // Inicialidando os ponteiros com os valores recebidos</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; palavraAnalisada=palavra;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; certas=letrasCertas;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> </b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; char letraComparada=((letra&gt;=&#8217;A')&amp;&amp;(letra&lt;=&#8217;Z'))?letra-&#8217;A'+&#8217;a':letra;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> </b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; while (*palavraAnalisada)</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; {</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp;&nbsp;&nbsp; if (*palavraAnalisada==letraComparada)</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp;&nbsp;&nbsp; acertos++;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp;&nbsp;&nbsp; *certas=letraComparada;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp;&nbsp;&nbsp; palavraAnalisada++;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp;&nbsp;&nbsp; certas++;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; }</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> </b></font></font><br /><font face="monospace"><font color="#ff0000"><b> &nbsp; return acertos;</b></font></font><br /><font face="monospace"><font color="#ff0000"><b> }</b></font></font></p></blockquote>
<p>Vamos analisar essa função. Para começar, temos a declaração de três variáveis: um <font face="monospace">int</font> onde guardaremos a quantidade de vezes que a letra escolhida &#8220;casou&#8221; com alguma na palavra (0 se nenhuma), dois ponteiros de caracter (<font face="monospace">char*</font>) que serão quem realmente fará o trabalho sujo, e um <font face="monospace">char</font> que irá conter uma versão em minúscula do caracter digitado (isso deve-se ao fato de todas as palavras estarem em minúsculas, o que provocaria problemas na comparação entre os caracteres em caso de maiúsculas). A função não tem muito mistério: iremos correr os ponteiros de <font face="monospace">palavraAnalisada</font> (que recebe a palavra que o sistema escolheu) e <font face="monospace">certas</font> (onde serão gravados os acertos). Se o caracter que for apontado por <font face="monospace">palavraAnalisada</font> &#8220;casar&#8221; com a letra a ser comparadas, será somado um ao número de acertos e a letra será gravada na posição apontada em <font face="monospace">certas</font>. Como ambas se movem ao mesmo tempo (no fim do <i>loop</i> de comparação), a posição de <font face="monospace">certas</font> onde a letra será gravada corresponderá à posição em que a letra fica em <font face="monospace">palavraAnalisada</font>. Parece estranho no <font face="monospace">while</font> não haver nenhuma condição de saída aparente, mas lembre-se que para C, qualquer valor 0 ou equivalente é considerado falso e provoca a saída do <i>loop</i>. No caso de <i>strings</i>, o terminador nulo da <i>string</i> é considerado um valor equivalente a 0 e portanto falso. Por isso, não precisamos especificar uma condição de saída. Esse tipo de construção é comum em programas C de alto nível e faz parte do &#8220;modo C de pensar&#8221; não declarar uma condição de saída explícita aqui. Após o <i>loop</i>, a função retornará quantos acertos ocorreram.<br />Vejamos agora uma coisa: <i>é necessário criar os dois ponteiros de char</i>?<br />SIM!<br />Usando <i>const</i>, garantimos que os endereços armazenados nos ponteiros que passaram os mesmos para o sistema não terão seus valores alterados. Porém, pela própria lógica que usamos, precisaremos de ponteiros que &#8220;se movam&#8221; através das <i>strings</i>, comparando os caracteres um a um e obtendo os acertos. Não teríamos como fazer isso usando o ponteiro <i>const</i> que passamos, pois ele é constante e portanto não pode ser manipulado. Porém, ao declararmos dois ponteiros e copiarmos os endereços de memória apropriados para eles, podemos &#8220;deslocar&#8221; esses segundo ponteiros, sem interferir nos ponteiros originais (constantes). Lembre-se que <i>const</i> nesse caso apenas impede que o endereço do ponteiro seja trocado, não seu conteúdo. Por meio dos ponteiros que declaramos dentro da função, podemos modificar os conteúdos das <i>strings</i> apontadas pelos mesmos e deslocar-nos através dos locais apontados, operando por meio de aritmética de ponteiros.<br />OK, acho que devemos estar claros quanto a isso. Voltemos ao nosso programa.<br />Lembra que dissemos que a função <font face="monospace">checaLetra</font> retorna o número de acertos e 0 se nenhum? Isso tem um motivo:<br />
<blockquote><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!checaLetra(palavraEscolhida,letrasCertas,minhaLetra))</font></b></p></blockquote>
</div>
<div align="justify">Esse <font face="monospace">if</font> explica nossa escolha. Assim como no caso do <font face="monospace">while</font> em <font face="monospace">checaLetra</font>, o <font face="monospace">if</font> aqui é uma &#8220;boa prática&#8221; de C: ao invés de retornarmos um número arbitrário como falso, usamos o próprio mecanismo de &#8220;booleanos&#8221; em C (0 ou equivalente igual a falso, qualquer outro valor verdadeiro). Desse modo, o programa fica mais enxuto e rápido por dispensar comparações que seriam &#8220;desnecessárias&#8221;. Mas atenção: <i><b>BOAS PRÁTICAS NÃO SÃO OBRIGAÇÕES!</b></i> Se em algum código você precisar fazer comparações exijam o valor 0 como um valor verdadeiro, não se exime de usar o 0 como verdadeiro e comparar valores com operadores relacionais normalmente. O fato de você se ater a boas práticas ajuda na legibilidade e manutenção do código, mas não deve ser um grilhão para você.<br />Esse <font face="monospace">if</font> irá apenas exibir uma mensagem de que o jogador errou e adicionará um ao número de tentativas, e iniciará uma nova interação do <font face="monospace">while</font> pelo comando <font face="monospace">continue</font>. <br />Caso o jogador tenha acertado a letra, ele verá a palavra com as letras que ele já acertou e com traços nas posições onde ainda têm letras que o jogador ainda não acertou. Em seguida chamamos outra função que usa parâmetros por referência, que é a <font face="monospace">contaFaltantes</font>:<br />
<blockquote><b><font face="monospace" color="#000099">int contaFaltantes(const char* letrasCertas)<br />{<br />&nbsp; char *letras=letrasCertas;<br />&nbsp; int faltantes=0;</p>
<p>&nbsp; while (*letras) if (*(letras++)==&#8217;-') faltantes++;</p>
<p>&nbsp; return faltantes;<br />}</font></b></p></blockquote>
</div>
<div align="justify">Basicamente ela conta quantos traços ainda existem em <font face="monospace">letrasCertas</font> (ou seja, quantas letras ainda precisam ser descobertas). Novamente declaramos um <font face="monospace">int</font> para armazenar o total de faltantes (com 0 caso não haja nenhuma faltante) e um char* para ser usado para &#8220;nos deslocarmos&#8221; através da <i>string</i> e contarmos os caracteres faltantes. O <font face="monospace">while</font> dessa função é estranho:<br />
<blockquote><b><font face="monospace" color="#000099">&nbsp; while (*letras) if (*(letras++)==&#8217;-') faltantes++;</font></b></p></blockquote>
</div>
<div align="justify">O que queremos dizer aqui é que: enquanto <font face="monospace">*letras</font> não apontar um terminador nulo, <i>se o valor apontado por letras <b>no momento do <font face="monospace">if</font></b> for um traço</i>, adicione um aos faltantes. Após a comparação, mova uma posição adiante o ponteiro letras (perceba a pós-fixação do ponteiro). Esse é outro tipo de construção característica que o C permite e muitas vezes ela é vista em programas profissionais C.<br />Depois de contadas as faltantes, comparamos esse total com a metade das letras da palavra escolhida. Se isso for verdade, uma nova contagem é feita para ver se todas as letras foram acertadas<font face="monospace">:<br /></font><br />
<blockquote><font face="monospace" color="#006600"><b>&nbsp;&nbsp;&nbsp; &nbsp; if((contaFaltantes(letrasCertas)==0)||testaCerto(palavraEscolhida,&amp;tentativasErradas))</b></font></p></blockquote>
</div>
<div align="justify">Caso contrário, será chamada a função testaCerto. No caso, o C garante que, caso <font face="monospace">contaFaltantes</font> retorne 0, <font face="monospace">testaCerto</font> não será chamada (é a <i>short-fuse logic</i> &#8211; lógica de curto-circuito, que faz com que, uma vez uma comparação lógica seja irrefutavelmente verdadeira ou falsa, o resultado seja considerado sem necessidade de realizar os demais processamentos, poupando tempo). Perceba que aqui usamos a comparação <font face="monospace" color="#006600"><b>contaFaltantes(letrasCertas)==0</b></font>. Embora aqui pudessemos usar <font face="monospace" color="#006600"><b>!contaFaltantes(letrasCertas)</b></font>, aqui a boa prática não contribuiria, e sim atrapalharia a legibilidade. É importante ter isso em mente ao escrever seus códigos.<br />Vejamos agora a função <font face="monospace">testaCerto</font>, que é chamada no caso de ainda haver letras a serem descobertas em uma palavra com mais de metade de seus caracteres descobertos:<br />
<blockquote><font face="monospace"><font color="#cc6600"><b>int testaCerto (const char* palavraEscolhida, int *tentativasErradas)</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> {</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; char *minhaResposta;</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> </b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; minhaResposta=(char*)malloc(strlen(palavraEscolhida)+1);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; memset(minhaResposta,&#8221;, strlen(palavraEscolhida)+1);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; &nbsp; </b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; if (!minhaResposta)</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; {</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao consegui alocar memoria!\n&#8221;);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; }</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> </b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; char *conversao=minhaResposta;</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; printf(&#8220;Qual palavra voce acha que e essa? &#8220;);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; fgets(minhaResposta,strlen(palavraEscolhida)+1,stdin);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> </b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; // Convertendo para minusculas e eliminando os caracteres de nova linha &#8211; \n</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; while (*conversao)</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; {</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *conversao=((*conversao&gt;=&#8217;A')&amp;&amp;(*conversao&lt;=&#8217;Z'))?*conversao-&#8217;A'+&#8217;a':*conversao;</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conversao++;</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; }</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> </b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; minhaResposta[strlen(minhaResposta)]=&#8221;;</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; </b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; if(strncmp(minhaResposta,palavraEscolhida,strlen(palavraEscolhida))==0)</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; return(1);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp; else</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; {</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Que pena, voce errou!\n&#8221;);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*tentativasErradas)++;</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> &nbsp;&nbsp;&nbsp; }</b></font></font><br /><font face="monospace"><font color="#cc6600"><b> }</b></font></font></p></blockquote>
<p>Quando chamamos <font face="monospace">testaCerto</font>, passamos a palavra em um ponteiro <font face="monospace">const char*</font> e um <font face="monospace">int*</font>.<br />&#8220;<i>Por que esse <font face="monospace">int</font> não é <font face="monospace">const</font>?</i>&#8220;.<br />O <font face="monospace">int</font> aqui não é <font face="monospace">const</font> pois, vamos dizer assim, o original não era um ponteiro. A validade do que dissemos sobre a alteração potencial do endereço só vale para quando passamos ponteiro-para-ponteiro. Quando derreferenciamos uma variável comum e passamos sua referência, mesmo que haja uma alteração no endereço dentro do código da função, não haverá outros impactos na variável de retorno (além de possíveis <i>crashes</i> de sistema e, na melhor das hipóteses, erros de lógica). Colocar um <font face="monospace">const</font> como precaução a mais é errado? Não. Mas como o código aqui não vai alterar essa posição (apenas o conteúdo do endereço), não há tanta necessidade assim de colocar <font face="monospace">const</font> nesse momento.<br />É imporante aqui dizer que o retorno é 1 para o caso de você acertar a palavra e 0 se errar. A passagem por referência de <font face="monospace">tentativasErradas</font> é importante pois precisaremos, no caso de erro aqui, adicionar 1 ao número de tentativas erradas (não haveria como fazer uma segunda chamada, uma vez que a entrada do usuário é feita nessa função, e armazenar o valor de retorno dessa função antes da comparação no<font face="monospace"> if </font>que a chama no programa principal, ainda que possível, é complexo e propenso a erros). Inicialmente alocamos o mesmo tanto de memória que usamos na <font face="monospace">palavraEscolhida</font> para o usuário entrar sua tentativa usando <font face="monospace">malloc</font> e colocamos um segundo ponteiro chamado <font face="monospace">conversao</font> para esse endereço. Usamos <font face="monospace">fgets</font> para aceitar a resposta dada pelo usuário e colocamos o terminador nulo ao fim da entrada do usuário. Usando o ponteiro <font face="monospace">conversao</font>, convertemos a palavra para minúscula (uma conversão que fazemos usando o fato de que variáveis <font face="monospace">char</font> podem ser entendidas como <font face="monospace">int</font> e podemos subtrair um <font face="monospace">char</font> de outro &#8211; mais exatamente, o valor ASCII de um do valor ASCII de outro &#8211; e somá-los com um terceiro <font face="monospace">char</font>). <br />Em seguida, usamos a função <font face="monospace">strncmp</font> da biblioteca <font face="monospace">string.h</font>, para comparar a resposta dada com a <font face="monospace">palavraEscolhida</font>. Essa função compara um determinado trecho de uma <i>string</i> com o trecho de mesmo tamanho da outra <i>string</i>. Para evitar que o jogador use um <i>cheat</i> e digite apenas a parte que ele sabe da palavra, determinamos que o tamanho a ser usado é o de <font face="monospace">palavraEscolhida</font>, não da tentativa do jogador. Isso porque <font face="monospace">strncmp</font> devolve 0 se os dois pedaços forem exatamente iguais, -1 se o primeiro for alfabeticamente anterior ao segundo e 1 se o primeiro for alfabeticamente posterior ao segundo (e aqui você deve ter entendido porque disse que o jogador poderia <i>cheatar</i> aqui). Se o resultado for 0, ou seja, as duas palavras forem iguais, a função retorna 1, o que vai fazer o <font face="monospace">if</font> no código principal ser verdadeiro. Caso contrário, retornará 0, tornando o <font face="monospace">if </font>falso (lembrando que pelo <i>short-fuse logic</i>, a primeira função deve ser falsa &#8211; senão essa nem seria executadas). Antes de devolver o 0 no caso de erro, porém, ele mostra uma mensagem de erro e soma um ao número de <font face="monospace">tentativasErradas</font> (atente que o <font face="monospace">++</font> fora do parênteses em <font face="monospace"><font color="#cc6600"><b>(*tentativasErradas)++</b></font></font> indica que o valor a ser alterado é o que está armazenado no endereço apontado por <font face="monospace"><font color="#cc6600"><b>*tentativasErradas</b></font></font>, não o próprio <font face="monospace"><font color="#cc6600"><b>*tentativasErradas</b></font></font>.).<br />Se você notar, caso o <font face="monospace">if</font> seja falso, ele acaba no final do <i>loop</i>. Uma nova iteração será aberta obviamente, se o número de <font face="monospace">tentativasErradas</font> ainda for menor que o <font face="monospace">NUM_TENTATIVAS</font>. Caso contrário, o programa sairá do <i>loop</i> e se encerrará.<br />Algumas &#8220;brincadeiras&#8221;:
<ol>
<li>Descubra o <i>bug</i> na instrução que escolhe as palavras;</li>
<li>Aumente o número de palavras e veja se isso altera alguma coisa no funcionamento do código e se ele não chega a escolher alguma das palavras novas ou antigas. Coloque palavras grandes e veja o que acontece. Modifique o código para corrigir tal circunstância;</li>
<li>Uma coisa que não foi considerada propositalmente nesse código: no jogo normal, você não pode pedir uma letra já pedida. Além disso, a qualquer momento você pode pedir uma lista das letras já usadas. Crie uma lógica que trate dessas condições;</li>
<li>Em algumas versões desse jogo, uma tentativa errada de informar a palavra completa acaba com o jogo de uma vez. Tente criar uma lógica assim;</li>
<li>Em algumas versões, existe uma regra que, caso um determinado número de tentativas erradas consecutivas seja alcançada, o jogo acaba. Tente adaptar o jogo para essa regra;</li>
</ol>
<p>Bem, com esse tópico, encerramos (ao menos por agora) o tópico Matrizes e Ponteiros. Ainda existe um tema dentro dela que falta, que é o de <i>ponteiros de ponteiros</i>, mas veremos ele no futuro, quando tratarmos de estruturas de dados complexas em C. Por agora é só e tenho só que agradecer por vocês terem aguentado tanto. <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> <br /><span id="more-81"></span><b>[Atualização - Dia 13/06/2011]</b> O leitor <a href="http://topologia-geral.ourproject.org/" rel="external nofollow" class="url">André Caldas</a> fez uma série de correções que realmente foram muito esclarecedoras. Ao invés de interferir no texto, prefiro que leiam os comentários do mesmo, pois são conceitos que eu mesmo tinha alguma confusão.. Com isso, algumas correções são necessárias nos códiogs dos dois programas que publicamos aqui. Em especial, devo me corrigir quanto à declaração do ponteiro de função: é possível sim fazer uma declaração de um ponteiro de função indicando os parâmetros. Não só é possível, como é o correto, uma vez que o sistema irá então fazer a checagem correta da função, no quesito de parâmetros e retorno. Ou seja, o código é mais bem escrito uma vez que utilize-se tipos. No caso do nosso primeiro código, ao invés de:<br />
<blockquote><font face="monospace">&nbsp; int (*funcPointer)(); // o meu ponteiro de funcao vem aqui</font></p></blockquote>
<p>o correto é:<br />
<blockquote><font face="monospace">&nbsp; int (*funcPointer)(int,int); // o meu ponteiro de funcao vem aqui</font></p></blockquote>
</div>
<div align="justify">Além disso, uma outra correção, essa um erro crasso meu, é o fato de que, no nosso jogo no segundo código, na função testaCerto, existe um sérissimo vazamento de memória (<i>memory leakage</i>) que deixei para trás. Se você leitor não percebeu, eu não faço uma desalocação de memória antes das saídas do código, tanto no caso do acerto quanto de erro. Isso pode parecer pouco, mas esses pequenos erros são os que geram maus hábitos de programação e que acabam redundando em programas mau-feitos e com falhas sérias que podem, inclusive, comprometer todo um ambiente computacional.<br />No caso, o problema era no código abaixo:<br />
<blockquote><font face="monospace">&nbsp; if(strncmp(minhaResposta,palavraEscolhida,strlen(palavraEscolhida))==0)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; return(1);</font><br /><font face="monospace">&nbsp; else</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Que pena, voce errou!\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*tentativasErradas)++;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }</font></p></blockquote>
<p>Se você reparar bem, irá notar que tanto no acerto quanto no erro, saio da função sem executar a devida limpeza da memória alocada em <font face="monospace">minhaResposta</font>. No caso, o código correto é:<br />
<blockquote><font face="monospace">&nbsp; if(strncmp(minhaResposta,palavraEscolhida,strlen(palavraEscolhida))==0)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font color="#ff0000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(minhaResposta);</font></b></font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp; else</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Que pena, voce errou!\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*tentativasErradas)++;</font><br /><font color="#ff0000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(minhaResposta);</font></b></font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }</font></p></blockquote>
<p>Repare nos <font face="monospace">free</font> colocados aqui, que têm como objetivo liberar a memória utilizada. Além disso, não estava desalocando a memória antes de encerrar o programa para os ponteiros <font face="monospace">palavraEscolhida</font> e <font face="monospace">letrasCertas</font>. Embora possa-se dizer que essa é uma falha que não compromete, uma vez que esses dois espaços são desalocados pelo próprio SO ao final da execução do programa, novamente fica a questão do mau-hábito de programação. O ideal é que, <i>mesmo ao final do programa</i>, você libere todos os recursos usados pelo mesmo.<br />Dito isso, segue abaixo as novas versões de ambos os programas, caso você ainda tenha alguma dúvida sobre as correções feitas&nbsp; (que serão marcadas em cores para que você analise e aprenda com o meu erro. <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )<br /><b>Calculadora (ponteiro de função):</b><br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;</p>
<p>int soma (int, int);<br />int subtracao (int, int);<br />int multiplicacao (int, int, int);<br />int divisao (int, int);</p>
<p>int main(void)<br />{<br /><font color="#663366"><b>&nbsp; int (*funcPointer)(int,int); // o meu ponteiro de funcao vem aqui</b></font></p>
<p>&nbsp; int a=0,b=0,c=0,oper=0;</p>
<p>&nbsp; printf (&#8220;Entre com dois numeros inteiros separados por espaco: &#8220;);<br />&nbsp; scanf (&#8220;%d %d&#8221;, &amp;a, &amp;b);</p>
<p>&nbsp; do<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;Escolha uma operaÃ§Ã£o a se realizar com esses numeros:\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;1-) Soma\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;2-) Subtracao\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;3-) Multiplicacao\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;4-) Divisao\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;, &amp;oper);<br />&nbsp;&nbsp;&nbsp; } while (!((oper&gt;=1) &amp;&amp; (oper&lt;=4)));</p>
<p>&nbsp; switch(oper)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; case 1:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; funcPointer=soma;<br />&nbsp;&nbsp;&nbsp; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; case 2:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; funcPointer=subtracao;<br />&nbsp;&nbsp;&nbsp; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; case 3:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; funcPointer=multiplicacao;<br />&nbsp;&nbsp;&nbsp; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; case 4:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; funcPointer=divisao;<br />&nbsp;&nbsp;&nbsp; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; c=(*funcPointer)(a,b);<br />&nbsp; printf(&#8220;O resultado da operacao desejada com os valores %d e %d e %d\n&#8221;,a,b,c);<br />&nbsp; printf(&#8220;A funcao usada para executar a operacao desejada localiza-se em %p\n&#8221;,funcPointer);<br />&nbsp; return(0);<br />}</p>
<p>int soma (int a, int b)<br />{<br />&nbsp; return a+b;<br />}</p>
<p>int subtracao (int a, int b)<br />{<br />&nbsp; return a-b;<br />}</p>
<p>int multiplicacao (int a, int b, int c)<br />{<br />&nbsp; return a*b;<br />}</p>
<p>int divisao (int a, int b)<br />{<br />&nbsp; if (b==0)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao posso dividir nada por zero!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp; return a/b;<br />}</font></p></blockquote>
<p><b>Roda-a-Roda (parâmetro por referência):</b><br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;time.h&gt;<br />#include &lt;string.h&gt;</p>
<p>#define NUM_TENTATIVAS 6<br />#define TAMANHO_PALAVRAS 20</p>
<p>int checaLetra (const char* palavraEscolhida, const char* letrasCertas, char letra);<br />void explicarRegras (void);<br />int contaFaltantes (const char* letrasCertas);<br />int testaCerto (const char* palavraEscolhida, int* tentativasErradas);</p>
<p>int main (void)<br />{</p>
<p>&nbsp; // Declarando variaveis</p>
<p>&nbsp; // Biblioteca de palavras<br />&nbsp; char palavras[][TAMANHO_PALAVRAS]={&#8220;rotina&#8221;, &#8220;retina&#8221;, &#8220;palhaco&#8221;, &#8220;lembranca&#8221;, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;sistema&#8221;, &#8220;musica&#8221;,&#8221;curioso&#8221;, &#8220;fantasia&#8221;,<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; &#8220;malabares&#8221;,&#8221;sonhador&#8221;,&#8221;atitude&#8221;,&#8221;pacoca&#8221;};</p>
<p>&nbsp; // Ponteiros necessarios<br />&nbsp; char *palavraEscolhida, *letrasCertas;</p>
<p>&nbsp; // Algumas variaveis de apoio<br />&nbsp; int tentativasErradas=0,i;</p>
<p>&nbsp; explicarRegras();</p>
<p>&nbsp; srand(time(NULL)); // Serve para modificar a tabela de nÃºmeros pseudo-aleatÃ³rios</p>
<p>&nbsp; palavraEscolhida=palavras[rand()%((sizeof(palavras)/TAMANHO_PALAVRAS)-1)];</p>
<p>&nbsp; letrasCertas=malloc(strlen(palavraEscolhida)+1);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br />&nbsp; if (!letrasCertas)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao consegui alocar memoria!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; memset(letrasCertas,&#8221;, strlen(palavraEscolhida)+1);<br />&nbsp; memset(letrasCertas,&#8217;-', strlen(palavraEscolhida));</p>
<p>&nbsp; int tentativaAtual=0;<br />&nbsp; while(tentativasErradas<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char minhaLetra;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tentativaAtual++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf (&#8220;Okay, tentativa no %d (%d tentativas erradas):&#8221;, tentativaAtual, tentativasErradas);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf (&#8220;%c&#8221;, &amp;minhaLetra);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getchar();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!checaLetra(palavraEscolhida,letrasCertas,minhaLetra))<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp; printf(&#8220;Que pena, essa letra nao aparece!\n&#8221;);<br />&nbsp;&nbsp;&nbsp; &nbsp; tentativasErradas++;<br />&nbsp;&nbsp;&nbsp; &nbsp; continue;<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;A palavra ate agora e: %s\n&#8221;,letrasCertas);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (contaFaltantes(letrasCertas)&lt;=(strlen(palavraEscolhida)/2))<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp; if((contaFaltantes(letrasCertas)==0)||testaCerto(palavraEscolhida,&amp;tentativasErradas))<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Muito bem! Voce acertou!\n&#8221;);<br /><font color="#663366"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(palavraEscolhida);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(letrasCertas);</b></font><br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);<br />&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }<br />}</p>
<p>void explicarRegras (void)<br />{<br />&nbsp; // Explicando as regras do jogo para o jogador<br />&nbsp; printf (&#8220;Okay, vamos explicar as regras!\n&#8221;);<br />&nbsp; printf (&#8220;Eu conheco algumas palavras, e vou escolher aleatoriamente uma delas.\n&#8221;);<br />&nbsp; printf (&#8220;Voce vai me dizer qual letra voce acha que essa palavra tem!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce errar, vou considerar uma tentativa errada!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce acertar, vou te mostrar onde as letras estao!\n&#8221;);<br />&nbsp; printf (&#8220;Quando voce tiver acertado metade das palavras, vou te dar &#8220;);<br />&nbsp; printf (&#8220;a chance de dizer qual palavra e essa. \n&#8221;);<br />&nbsp; printf (&#8220;Se voce errar, vou considerar uma tentativa errada!\n&#8221;);<br />&nbsp; printf (&#8220;Se voce acertar antes de acabar as tentativas, voce vence!\n\n\n&#8221;);<br />&nbsp; printf (&#8220;Algumas observacoes:\n&#8221;);<br />&nbsp; printf (&#8220;Voce tem %d tentativas que voce pode errar.\n&#8221;,NUM_TENTATIVAS);<br />&nbsp; printf (&#8220;Nenhuma palavra possui acentos, cedilha ou trema.\n&#8221;);<br />&nbsp; printf (&#8220;Nao estou diferenciando maisculas e minusculas. \n\n&#8221;);<br />}</p>
<p>int checaLetra (const char* palavra, const char* letrasCertas, char letra)<br />{<br />&nbsp; // Acertos obtidos (0 indica que nao tem a letra em questao na palavra)<br />&nbsp; int acertos=0;</p>
<p>&nbsp; // Ponteiros a serem inicializados<br />&nbsp; char *palavraAnalisada, *certas;<br />&nbsp; <br />&nbsp; // Inicialidando os ponteiros com os valores recebidos<br />&nbsp; palavraAnalisada=(char*)palavra;<br />&nbsp; certas=(char*)letrasCertas;</p>
<p>&nbsp; char letraComparada=((letra&gt;=&#8217;A')&amp;&amp;(letra&lt;=&#8217;Z'))?letra-&#8217;A'+&#8217;a':letra;</p>
<p>&nbsp; while (*palavraAnalisada)<br />&nbsp; {<br />&nbsp;&nbsp;&nbsp; if (*palavraAnalisada==letraComparada)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; acertos++;<br />&nbsp;&nbsp;&nbsp; *certas=letraComparada;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; palavraAnalisada++;<br />&nbsp;&nbsp;&nbsp; certas++;<br />&nbsp; }</p>
<p>&nbsp; return acertos;<br />}</p>
<p>int contaFaltantes(const char* letrasCertas)<br />{<br />&nbsp; char *letras=(char*)letrasCertas;<br />&nbsp; int faltantes=0;</p>
<p>&nbsp; while (*letras) if (*(letras++)==&#8217;-') faltantes++;</p>
<p>&nbsp; return faltantes;<br />}</p>
<p>int testaCerto (const char* palavraEscolhida, int *tentativasErradas)<br />{<br />&nbsp; char *minhaResposta;</p>
<p>&nbsp; minhaResposta=(char*)malloc(strlen(palavraEscolhida)+1);<br />&nbsp; memset(minhaResposta,&#8221;, strlen(palavraEscolhida)+1);<br />&nbsp;&nbsp;&nbsp; &nbsp; <br />&nbsp; if (!minhaResposta)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Nao consegui alocar memoria!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; char *conversao=minhaResposta;<br />&nbsp; printf(&#8220;Qual palavra voce acha que e essa? &#8220;);<br />&nbsp; fgets(minhaResposta,strlen(palavraEscolhida)+1,stdin);</p>
<p>&nbsp; // Convertendo para minusculas e eliminando os caracteres de nova linha &#8211; \n<br />&nbsp; while (*conversao)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *conversao=((*conversao&gt;=&#8217;A')&amp;&amp;(*conversao&lt;=&#8217;Z'))?*conversao-&#8217;A'+&#8217;a':*conversao;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conversao++;<br />&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp; minhaResposta[strlen(minhaResposta)]=&#8221;;<br />&nbsp; <br />&nbsp; if(strncmp(minhaResposta,palavraEscolhida,strlen(palavraEscolhida))==0)<br />&nbsp;&nbsp;&nbsp; {<br /><font color="#663366"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(minhaResposta);</b></font><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp; else<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Que pena, vocÃª errou!\n&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (*tentativasErradas)++;<br /><b><font color="#663366">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free(minhaResposta);</font></b><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);<br />&nbsp;&nbsp;&nbsp; }<br />}</font></p></blockquote>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=81&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2011/04/18/matrizes-e-ponteiros-%e2%80%93-parte-3-%e2%80%93-ponteiros-e-funcoes/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
		<item>
		<title>Matrizes e Ponteiros &#8211; Parte 2 &#8211; Alocação dinâmica de memória</title>
		<link>https://aulasdec.wordpress.com/2011/03/09/matrizes-e-ponteiros-parte-2-alocacao-dinamica-de-memoria-2/</link>
		<comments>https://aulasdec.wordpress.com/2011/03/09/matrizes-e-ponteiros-parte-2-alocacao-dinamica-de-memoria-2/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 18:14:22 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Ponteiros]]></category>

		<guid isPermaLink="false">http://aulasdec.wordpress.com/2011/03/09/matrizes-e-ponteiros-parte-2-alocacao-dinamica-de-memoria-2/</guid>
		<description><![CDATA[Olá todos e desculpem a demora! Espero que todos tenham pulado o Carnaval no &#8220;Unidos da Programação em C&#8221;! Bem, vamos continuar de onde paramos, então vamos dar prosseguimento ao &#8220;curso&#8221;. Quando, na primeira parte do assunto matrizes e ponteiros, falamos sobre os ponteiros, nós dissemos que &#8220;existem situações onde precisamos utilizar uma posição de [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=69&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá todos e desculpem a demora! Espero que todos tenham pulado o Carnaval no &#8220;Unidos da Programação em C&#8221;! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> <br />Bem, vamos continuar de onde paramos, então vamos dar prosseguimento ao &#8220;curso&#8221;.
<div align="justify">Quando, na <a target="_blank" href="http://aulasdec.wordpress.com/2011/02/07/matrizes-e-ponteiros-parte-1-2/">primeira parte do assunto matrizes e ponteiros</a>, falamos sobre os ponteiros, nós dissemos que &#8220;<i>existem situações onde precisamos utilizar uma posição de memória que não conhecemos previamente. Na realidade, isso é mais comum do que se imagina: não fosse assim, todo programa deveria ser artificialmente limitado em suas capacidades baseado em números arbitrários de</i><i> informação a ser processada. Por exemplo: um programa teria que criar</i><i> previamente 500 variáveis de notas para processar o boletim escolar de uma classe de 20 alunos, sendo inútil para uma classe de 501 alunos. Isso também aumentaria o custo de desenvolvimento e manutenção de um programa de computador, além de utilizar os recursos de um computador de maneira pouco eficiente.</i>&#8221; Isso acontece porque pelas regras do padrão <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29#ANSI_C_and_ISO_C">ANSI C Original</a> (seguida pela maior parte dos compiladores), o compilador não pode gerar código que utilize-se de <a target="_blank" href="http://en.wikipedia.org/wiki/Variable-length_array"><i>matrizes de tamanho varíavel</i></a> (em uma versão atualizada do padrão, <a target="_blank" href="http://en.wikipedia.org/wiki/C99">C-99</a>, os compiladores já passaram a dar suporte a esse recurso, porém nos focaremos ao <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29#ANSI_C_and_ISO_C">C padrão ANSI</a>.). Por exemplo, em <a target="_blank" href="http://en.wikipedia.org/wiki/C_%28programming_language%29#ANSI_C_and_ISO_C">C padrão ANSI</a>, o código abaixo:<br />
<blockquote><font face="monospace">printf (&#8220;Quantos elementos precisamos?&#8221;);</font><br /><font face="monospace">scanf (&#8220;%d&#8221;,&amp;nElementos);</font><br /><font face="monospace">int elementos[nElementos];</font></p></blockquote>
<p>É considerado errado e gera um erro similar (PS: se você colocar esse tipo de código em um compilador com suporte ao C-99, em geral ele irá compilar, mas irá dar alertas. Será necessário fazer o compilador enxergar o código como C-99, não ANSI C Original. verifique o manual do compilador para maiores informações).<br />Para &#8220;escaparmos&#8221; a esse tipo de problema, a solução é fugir das matrizes e recorrermos aos ponteiros. Mas como?<br />O C Original prevê funções de alocação de memória dinâmica. Com o uso dessas funções, podemos obter, <i>em tempo de execução</i>, qualquer quantidade de memória que precisarmos (claro, imaginando que ela esteja disponível), normalmente de um espaço conhecido como <i>heap</i> e gerenciado pelo sistema operacional. Com isso, não precisamos artificalmente definirmos o uso de memória em um programa C (PS: várias outras linguagens, como Pascal, possuem também mecanismos de <a target="_blank" href="http://en.wikipedia.org/wiki/Variable-length_array">alocação dinâmica de memória</a>), podendo aproveitar os recursos do sistema com maior eficiência.<br />Bem, chega de papo! Vamos ao que interessa.<br />
<h3>O código</h3>
<p>Vamos refazer um programa similar a algo que fizemos anteriormente, que é o programa da seqüência de Fibonacci (fãs de <i>Código Da Vinci</i>, regozijem-se). Porque disse similar? Pois a seqüência de Fibonacci é calculada de maneira muitíssimo parecida com a do Fatorial, que vimos quando falamos de <a target="_blank" href="http://aulasdec.wordpress.com/2010/12/16/funcoes-parte-2/"><i>recursividade</i></a>. Para não recorrermos à recursão e mostrarmos a seqüência de Fibonacci resultante, utilizaremos alocação dinâmica de memória para reservamos o espaço adequado e aritmética de ponteiros para realizar os cálculos. Abaixo está o código<font face="monospace">:<br /></font><br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt; <br /><font color="#cc9933"><b>#include &lt;sdtlib.h&gt;</b></font><br /></font><br /><font face="monospace">int main(void)</font><br /><font face="monospace">{</font><br /><font color="#cc0000"><b><font face="monospace">&nbsp; unsigned long int i=0,numeroFib=0,*sequenciaFib,*operFib;</font></b></font></p>
<p><font face="monospace">&nbsp; do</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Indique o tamanho da sequencia Fibonacci (a partir do 3): &#8220;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;numeroFib);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }while (numeroFib&lt;3);</font></p>
<p><font color="#000066"><b><font face="monospace">&nbsp; sequenciaFib=(unsigned long int *)malloc(sizeof(unsigned long int)*numeroFib);</font></b></font><br /><b><font color="#339999" face="monospace">&nbsp; if(!sequenciaFib)</font><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp; {</font><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Sem memoria!\n&#8221;);</font><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);</font><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp; }</font></b><font color="#339999"><b><br /></b><br /></font><font color="#003300"><b><font face="monospace">&nbsp; operFib=sequenciaFib;</font></p>
<p><font face="monospace">&nbsp; *operFib=1;</font><br /><font face="monospace">&nbsp; ++operFib;</font><br /><font face="monospace">&nbsp; *operFib=1;</font><br /><font face="monospace">&nbsp; ++operFib;</font></b></font></p>
<p><b><font color="#663366" face="monospace">&nbsp; for (i=0;i&lt;&lt;numeroFib-2;i++)</font><font color="#663366"><br /></font><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp; {</font><font color="#663366"><br /></font><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *operFib=*(operFib-1)+*(operFib-2);</font><font color="#663366"><br /></font><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operFib++;</font><font color="#663366"><br /></font><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp; }</font></b></p>
<p><b><font face="monospace">&nbsp; operFib=sequenciaFib;</font></p>
<p><font face="monospace">&nbsp; for (i=0;&lt;numeroFib;i++)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;%do. numero Fibonacci e %u e esta armazenado no endereco %p\n&#8221;,i+1,*operFib,operFib);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++operFib;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }</font><br /></b><br /><font color="#000099"><b><font face="monospace">&nbsp; free(sequenciaFib);</font></b></font></p>
<p><font face="monospace">&nbsp; return(0);</font><br /><font face="monospace">}</font></p></blockquote>
<p>Bem, não precisamos comentar o início, à exceção que precisamos incluir a <font face="monospace">stdlib.h</font> (<i>STanDard LIBrary</i>, se você não se lembra bem), pois ela é quem fornece a função <font face="monospace">malloc</font> (<i>Memory ALLOCation</i>) que precisaremos. Logo falaremos sobre ela. Em seguida declaramos quatro variáveis <font face="monospace">unsigned long int</font>&#8230; Na realidade, duas <font face="monospace">unsigned long int</font> e dois ponteiros <font face="monospace">unsigned long int</font> (<font face="monospace">unsigned long int *</font>). Fizemos a opção de usar o <font face="monospace">unsigned long int </font>pois podemos com isso executar um número muito alto de interações e, ao mesmo tempo, não precisamos nos preocupar com valores negativos de Fibonacci (que não existem). Para não termos problemas, fazemos com que o sistema só aceite um valor mínimo de 3 (ou seja, para mostrar até o terceiro número de Fibonacci).<br />
<h3>Alocação dinâmica de memória &#8211; os comandos <font face="monospace">malloc</font> e <font face="monospace">free</font>:<br /></h3>
<p>Continuando o programa, encontramos o comando:<br />
<blockquote><font color="#000066"><b><font face="monospace">&nbsp; sequenciaFib=(unsigned long int *)malloc(sizeof(unsigned long int)*numeroFib);</font></b></font></p></blockquote>
<p>Essa linha é que faz todo o truque de alocação dinâmica de memória com o uso do comando <font face="monospace">malloc</font> (<i>Memory ALLOCation</i>). <font face="monospace">malloc</font> aloca uma determinada quantidade de bytes para um ponteiro do tipo <font face="monospace">void</font> (<font face="monospace">void *</font>). É importante lembrar disso pois podemos provocar sérios erros senão lembrarmos constantemente disso. Para que possamos usar corretamente <font face="monospace">malloc</font>, devemos obter o número de bytes necessários para armazenarmos as informações necessárias. Nesse caso, utilizamos o operador <font face="monospace">sizeof</font> para obter o tamanho de bytes de um <font face="monospace">unsigned long int</font> (lembrando que esse valor pode mudar conforme a plataforma) e multiplicamos pelo número de elementos que precisaremos (no caso, o tamanho da seqüência de Fibonacci que desejamos desenvolver). Depois disso, devemos dar um <i>typecast</i> para indicar ao sistema que vamos transformar o ponteiro <font face="monospace">void</font> retornado por <font face="monospace">malloc</font> em um ponteiro <font face="monospace">unsigned long int</font> (<font face="monospace">unsigned long int *</font>). Desse modo, temos como saída um ponteiro do tipo <font face="monospace">unsigned long int </font>pronto para nosso uso.<br />Antes de usarmos o ponteiro, é interessante de, por via das dúvidas, ver se realmente temos a memória alocada. Isso pode não parecer válido agora, mas qualquer pequena falha ao lidar com alocação dinâmica de memória pode comprometer o uso do sistema. O comando <font face="monospace">malloc</font> nos oferece um bom mecanismo para isso: ele retorna <font face="monospace">null</font> quando a alocação de memória falhou. Portanto, podemos testar isso com o seguinte código:<br />
<blockquote><b><font color="#339999" face="monospace">&nbsp; if(!sequenciaFib)</font></b><b><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp; {</font></b><b><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Sem memoria!\n&#8221;);</font></b><b><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(1);</font></b><b><font color="#339999"><br /></font><font color="#339999" face="monospace">&nbsp;&nbsp;&nbsp; }</font></b></p></blockquote>
</div>
<div align="justify">Provocando uma saída do sistema caso a memória que precisemos não seja alocada. Isso nos garante que não vamos operar sobrescrevendo memória apontada por um &#8220;ponteiro desgarrado&#8221; (ponteiro não-inicializado corretamente).<br />Agora, e essa é uma regra importante: sempre que você alocar memória, desaloquea-a assim que não for mais necessária. Isso vai garantir que não só seu programa, mas qualquer programa no computador onde o seu estiver executando, irá encontrar memória sempre que precisar. Caso não desaloque memória, você pode entrar em uma situação conhecida como &#8220;<i>memory leakage&#8221;</i> (Vazamento de memória), onde o sistema irá dar falha após várias alocações de memória seguirem-se sem a devida desalocação (o C não possui os sistemas de coletor de lixo &#8211; <i>Garbage Collector</i> &#8211; existente em outras linguagens devido à sua filosofia de trabalhar com o mínimo possível de complexidade). Para desalocar-se memória é usado o comando <font face="monospace">free.</font> No nosso caso, o último comando do programa é:<br />
<blockquote><font color="#000099"><b><font face="monospace">&nbsp; free(sequenciaFib);</font></b></font></p></blockquote>
<p>Que avisa ao sistema operacional que desejamos desalocar o espaço de memória que alocamos para <font face="monospace">sequenciaFib</font>, devolvendo esses recursos ao sistema operacional.<br />
<h3>Aritmética de ponteiros:<br /></h3>
<p>Bem, agora vamos continuar analisando o código, vendo um tópico que causa muiita confusão e portanto deve ser clareado totalmente, que é a <i>aritmética de ponteiros</i>.<br />Nós já vimos na <a target="_blank" href="http://aulasdec.wordpress.com/2011/02/07/matrizes-e-ponteiros-parte-1-2/">aula anterior</a> que existem formas de fazer um ponteiro &#8220;correr&#8221; pela memória vendo seus conteúdos, somando e subtraindo elementos do ponteiro em questão. Para isso, usa-se a <i>aritmética de ponteiros</i>, que nada mais é que usarmos os operandos matemáticos mais simples (<font face="monospace">+</font>, <font face="monospace">-</font>, <font face="monospace">++</font> e <font face="monospace">&#8211;</font>) para que eles alterem a informação de que endereço deve ser apontado por um ponteiro. <br />Vamos analisar então como o programa irá usar a aritmética de ponteiros:<br />
<blockquote><font color="#003300"><b><font face="monospace">&nbsp; operFib=sequenciaFib;</font></b></font></p>
<p><font color="#003300"><b><font face="monospace">&nbsp; *operFib=1;</font></b></font><br /><font color="#003300"><b><font face="monospace">&nbsp; ++operFib;</font></b></font><br /><font color="#003300"><b><font face="monospace">&nbsp; *operFib=1;</font></b></font><br /><font color="#003300"><b><font face="monospace">&nbsp; ++operFib;</font></b></font></p>
<p><b><font color="#663366" face="monospace">&nbsp; for (i=0;i&lt;&lt;numeroFib-2;i++)</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp; {</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *operFib=*(operFib-1)+*(operFib-2);</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operFib++;</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp; }</font></b></p></blockquote>
</div>
<div align="justify">O primeiro comando é simples: salvamos em <font face="monospace">operFib</font> o endereço apontado por <font face="monospace">sequeciaFib</font>. Perceba que ambos estão sem o operador de derreferenciamento (sim, o nome é confuso) <font face="monospace">*</font>. Nesse caso, é o que queremos: aqui estamos atribundo o <i>endereço</i> apontado por <font face="monospace">sequenciaFib</font> como o endereço a ser apontador <font face="monospace">operFib</font>.<br />A pergunta que você deve estar se fazendo é: &#8220;<i>por que usar dois ponteiros?</i>&#8220;<br />Na realidade aqui é importante fazer uma consideração MUITO SÉRIA: o C NÃO POSSUI &#8220;LEMBRANÇA&#8221; do endereço apontado por um ponteiro. Ele trabalha sempre no &#8220;instante&#8221;, por assim dizer. Se você modificar o endereço de <font face="monospace">sequenciaFib</font>, ele será usado em tudo o mais por esse novo valor, INCLUSIVE NA DESALOCAÇÃO. Isso pode gerar problemas sérios, pois o sistema operacional, no momento de alocar memória, também armazena a informação de quanta memória foi alocada, mas não a posição inicial-final. Se você &#8220;mover o ponteiro&#8221; e mandar desalocar a memória, você pode muito bem tentar desalocar memória de programas que não o seu, incluindo aí programas do sistema operacional. Desse modo, você pode comprometer o funcionamento do sistema como um todo ao fazer esse tipo de desalocação. Por via das dúvidas, é muito mais interessante fazer todas as operações por um segundo ponteiro, esse sim &#8220;livre&#8221; para ser usado à vontade e modificado como necessário. Você pode, obviamente, fazer o &#8220;movimento&#8221; do ponteiro usando sequenciaFib, se você souber como &#8220;recuar&#8221; o ponteiro de volta para o início de tudo, mas o nível de complexidade que isso vai gerar, em especial se você precisar modificar a memória alocada ou amarrá-la a outras coisas por meio de <i>ponteiros de ponteiros</i> (veremos esse tópico no futuro) vai mostrar que usar um ponteiro &#8220;âncora&#8221; representa um gasto de memória muito pequeno e o aumento de complexidade de código não compensará.<br />Bem, voltando ao nosso código: agora colocamos operFib como ponteiro para traabalharmos. Vamos ver o que ele irá fazer:<br />
<blockquote><font color="#003300"><b><font face="monospace">&nbsp; *operFib=1;</font></b></font><br /><font color="#003300"><b><font face="monospace">&nbsp; ++operFib;</font></b></font><br /><font color="#003300"><b><font face="monospace">&nbsp; *operFib=1;</font></b></font><br /><font color="#003300"><b><font face="monospace">&nbsp; ++operFib;</font></b></font></p></blockquote>
<p>A primeira coisa que fazemos é: pegar os dois primeiros espaços de memória alocados para <font face="monospace">sequenciaFib</font> (e que vamos alterar usando o ponteiro <font face="monospace">operFib</font>) e definir eles como 1. Eles são os primeiros dois números de Fibonacci, <a target="_blank" href="http://en.wikipedia.org/wiki/Fibonacci_number">segundo a definição do mesmo</a>. O que fazemos é repetido então pode-se pensar bem. A primeira linha: <font color="#003300"><b><font face="monospace">*operFib=1</font></b></font>, define que queremos armazenar na posição de memória apontada por operFib o valor 1. Aqui estamos tratando a memória apontada, portanto a derreferenciamos usando o operador <font face="monospace">*</font>. Em seguida, a segunda linha, <font color="#003300"><b><font face="monospace">++operFib</font></b></font>, indica que queremos passar para o próximo elemento de <font face="monospace">operFib</font>.<br />AQUI MORA DRAGÕES!!!<br />Pode parecer que simplesmente somamos 1 ao valor de <font face="monospace">operFib</font>, como mostramos na outra aula sobre ponteiros. Mas já falamos lá que nesse caso, o C soma o equivalente ao número de bytes ocupados por 1 elemento do tipo apontado pelo ponteiro (no caso, <font face="monospace">unsigned long int</font>). Normalmente, fazendo as coisas da maneira correta, nem precisamos nos preocupar com isso, mas é muito importante e explica, por exemplo, o porquê da exigência do <i>typecast</i> do ponteiro resultante do <font face="monospace">malloc</font> de <font face="monospace">void * </font>para o tipo necessário (além da óbvia mensagem de <i>warning</i> ou erro ao colocar-se um ponteiro <font face="monospace">void *</font> em um ponteiro <font face="monospace">unsigned long int *</font>). Com o devido <i>typecast</i>, o compilador, ao gerar o código, faz com que todas as abstrações sejam devidamente configuradas no nível do código de máquina. Sem isso, seria muito fácil o programador provocar erros e <i>bugs</i> devido ao apontamento incorreto de posições.<br />Dito isso, não há muito mais o que falar nesse momento.<br />O laço for que se segue, porém, é muito mais interessante:<br />
<blockquote><b><font color="#663366" face="monospace">&nbsp; for (i=0;i&lt;&lt;numeroFib-2;i++)</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp; {</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *operFib=*(operFib-1)+*(operFib-2);</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operFib++;</font></b><br /><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp; }</font></b></p></blockquote>
<p>Vamos analisar ele: a primeira coisa é que a condição de saída é o número de elementos de nossa seqüência de Fibonacci-2. Fazemos isso pois os dois primeiros valores já foram estipulados.<br />Em seguida vem o comando que é mais interessante nesse laço:<br />
<blockquote><b><font color="#663366" face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *operFib=*(operFib-1)+*(operFib-2);</font></b></p></blockquote>
<p>Aqui, usando a aritmética de ponteiros, conseguimos declarar normalmente a função para o cálculo de um número de Fibonacci: o valor da posição apontada por operFib será a soma do valor na posição apontada pelo elemento anterior ao atual (<b><font color="#663366" face="monospace">*(operFib-1)</font></b>) e pelo valor anterior a este (<b><font color="#663366" face="monospace">*(operFib-2)</font></b>).<br />Como ler uma dessas seqüência. A primeira coisa é perceber que temos uma aritmética de ponteiro aí, que é pedir para retornar o endereço corresponte a <font face="monospace">operFib-1</font>. Nesse caso, lembre-se de que é subtraído o número de bytes do tamanho do tipo indicado pelo ponteiro operFib. Por exemplo, imagine que <font face="monospace">operFib</font> aponte no momento o endereço 1000 (no caso, para facilitar a compreensão, trate como decimal &#8211; normalmente os endereços são apresentados pelo C em Hexadecimal) e que o tamanho de um <font face="monospace">unsigned long int</font> seja 64 bits (ou seja, 8 bytes). Ao pedirmos para obtermos o elemento anterior (<font face="monospace">operFib-1</font>), ele irá nos apresentar o valor que está na posição de memória 1000-8, ou seja, na posição 992. Por sua vez, o elemento anterior a esse (<font face="monospace">operFib-2</font>) estará na posição de memória 1000-16, ou seja, 984.<br />&#8220;<i>Isso não afeta <font face="monospace">operFib</font>?</i>&#8220;, você deve estar se perguntando?<br />Na verdade não. Ao usarmos os operadores aritméticos na aritmética de ponteiros, seus comportamentos são similares aos dos mesmos na aritmética &#8220;convencional&#8221;, ou seja, quando fazemos contas. Isso é importante ressaltar pois os comportamentos dos operando ++ e &#8212; é similar, assim como os efeitos de pré e pós-fixação que vimos quando falamos sobre os <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/24/uma-aprofundada-em-operadores-e-logica-em-c/">operadores e lógica em C</a>. Em especial, é importante que você tome muito cuidado com pré e pós-fixação na aritmética de ponteiros. Por exemplo, se eu usar:<font face="monospace"> *(meuPonteiro++)</font>, ele me retornará o valor apontado por meuPonteiro no momento em que o comando é executado e logo em seguida irá executar a soma de uma posição de memória do tipo apontado pelo ponteiro. Porém, se eu usar <font face="monospace">*(++meuPonteiro)</font>, ele irá avançar uma posição de memória <i>antes</i> de efetuar a leitura da memória. Particularmente não uso esse tipo de construção pois pode gerar confusão. Na dúvida, não a use: prefira escrever um código mais claro e limpo. Quando ganhar experiência poderá escrever código mais avançado.<br />Bem, em seguida o program irá executar o comando <b><font color="#663366" face="monospace">operFib++;</font></b>, que irá avançar uma posição de memória dentro dos valores apontados. Isso afetará a próxima interação, inclusive o cálculo acima mostrado, onde a posição <font face="monospace">operFib-1</font> representará a posição de <font face="monospace">operFib</font> antes dessa soma, ou seja, o valor calculado nessa iteração.<br />Bem, isso mostra como iremos calcular a nossa seqüência de Fibonacci.<br />Em seguida temos o código que irá exibir nosso:<br /><b><font face="monospace">&nbsp; operFib=sequenciaFib;</font></p>
<p><font face="monospace">&nbsp; for (i=0;&lt;numeroFib;i++)</font><br />
<font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br />
<font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;%do. numero Fibonacci e %u e esta armazenado no endereco %p\n&#8221;,i+1,*operFib,operFib);</font><br />
<font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++operFib;</font><br />
<font face="monospace">&nbsp;&nbsp;&nbsp; }</font><br />
</b>Primeira coisa que fazemos é &#8220;resetar&#8221; <font face="monospace">operFib</font>, sobrescrevendo o endereço dele com o de <font face="monospace">sequenciaFib</font>. Perceba que manipulamos o endereço, não o conteúdo do mesmo que continuará intacto.<br />Em seguida, um laço irá apresentar para nós o número Fibonacci recuperado de <font face="monospace">operFib</font>, seu valor e o endereço onde ele está armazenado, adicionando uma posição de memória a cada vez que a iteração <font face="monospace">for</font> for executada. A saída apresentada será algo como (para 12 números de Fibonacci):<br /><b><font face="monospace">1o. numero Fibonacci e 1 e esta armazenado no endereco <font color="#ff0000">0x9a91008</font><br />2o. numero Fibonacci e 1 e esta armazenado no endereco <font color="#ff0000">0x9a9100c</font><br />3o. numero Fibonacci e 2 e esta armazenado no endereco <font color="#ff0000">0x9a91010</font><br />4o. numero Fibonacci e 3 e esta armazenado no endereco <font color="#ff0000">0x9a91014</font><br />5o. numero Fibonacci e 5 e esta armazenado no endereco <font color="#ff0000">0x9a91018</font><br />6o. numero Fibonacci e 8 e esta armazenado no endereco <font color="#ff0000">0x9a9101c</font><br />7o. numero Fibonacci e 13 e esta armazenado no endereco <font color="#ff0000">0x9a91020</font><br />8o. numero Fibonacci e 21 e esta armazenado no endereco <font color="#ff0000">0x9a91024</font><br />9o. numero Fibonacci e 34 e esta armazenado no endereco <font color="#ff0000">0x9a91028</font><br />10o. numero Fibonacci e 55 e esta armazenado no endereco <font color="#ff0000">0x9a9102c</font><br />11o. numero Fibonacci e 89 e esta armazenado no endereco <font color="#ff0000">0x9a91030</font><br />12o. numero Fibonacci e 144 e esta armazenado no endereco <font color="#ff0000">0x9a91034</font></font></b><br />Aqui, perceba o endereço marcado em vermelho (ele variará na sua máquina conforme as execuções, e dificilmente será o mesmo que estou apresentando aqui). Note que ele vai subindo de 4 em 4 (<font face="monospace">c</font> em Hexadecima representa o número 12). Isso deve-se ao fato de que na plataforma onde executei esse código, o tamanho de um <font face="monospace">unsigned long int</font> é de 4 bytes (32 bits). Esse valor pode variar conforme a plataforma, mas o importante aqui é que ele vai almentando de 4 em 4 bytes, ou seja, a cada posição do tamanho de um <font face="monospace">unsigned long int</font>, enfatizando o que dissemos anteriormente sobre o tamanho do tipo de dado na questão da aritmética de ponteiro. Se você lembrar do código e da saída do programa que fizemos ao começarmos a explorar ponteiros, você verá que lá ele subia de 1 em 1 byte, o tamanho de um <font face="monospace">char</font>. Se você tivesse usando um tipo cujo tamanho fosse de 20 bytes, a aritmética de ponteiro aumentaria o valor da posição de memória de 20 em 20 bytes (imaginando que eles fossem cotiguos, ou seja, em seqüência, que é uma obrigatoriedade para o <font face="monospace">malloc</font> funcionar corretamente).<br />Por fim, antes de terminar o programa, o mesmo libera a memória com o comando <font face="monospace">free</font>. Embora não seja exatamente obrigatório (a maioria dos sistemas operacionais modernos desalocam completamente qualquer memória utilizada por um programa ao término de sua execução), é uma excelente prática ao sair do programa desalocar qualquer ponteiro que possa vir a estar alocado no momento do encerramento do programa. Na realidade, a melhor prática é desalocar qualquer memória alocada dinâmicamente tão logo o programa não mais precise dela, de modo a aproveitar melhor os recursos do computador. Tenha isso sempre em mente ao desenvolver com ponteiros.<br />Bem, aqui terminamos essa nossa aula. O próximo tópico ainda envolverá ponteiros: na realidade, ele irá mostrar as complexidades envolvendo ponteiros e funções, inclusive a técnica de <i>ponteiros de função</i>, muito usada em programação. Até lá, sugiro que brinque um pouco. Tente &#8220;remover&#8221; as limitações que impedem o ponteiro de &#8220;desgarrar&#8221; e veja as conseqüências (PS: não faça isso em produção. Vou repetir: NÃO FAÇA ISSO EM PRODUÇÃO. <b>NEM PENSE EM FAZER ISSO EM PRODUÇÃO!!!</b>). Analise os códigos aos poucos. Tente implementar outros algoritmos (por exemplo, o algoritmo de Fatorial).<br />Até a próxima, e lembre-se: os comentários estão abertos para dúvidas e sugestões!</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/69/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=69&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2011/03/09/matrizes-e-ponteiros-parte-2-alocacao-dinamica-de-memoria-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
		<item>
		<title>Matrizes e Ponteiros &#8211; Parte 1</title>
		<link>https://aulasdec.wordpress.com/2011/02/07/matrizes-e-ponteiros-parte-1/</link>
		<comments>https://aulasdec.wordpress.com/2011/02/07/matrizes-e-ponteiros-parte-1/#comments</comments>
		<pubDate>Mon, 07 Feb 2011 16:00:10 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Ponteiros]]></category>

		<guid isPermaLink="false">http://aulasdec.wordpress.com/?p=63</guid>
		<description><![CDATA[Olá todos! Espero que teham ido bem de Festas! Hoje começaremos talvez o tópico mais importante de programação C. Esse tópico é importantíssimo e com certeza provocará dúvidas, portanto lembro que os comentários deverão ser usados para tirar dúvidas. Não deixem nenhuma dúvida passar nesse momento, pois isso poderá depois complicar o aprendizado de outros [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=63&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá todos! Espero que teham ido bem de Festas!
<p align="justify">Hoje começaremos talvez o tópico mais importante de programação C. Esse tópico é importantíssimo e com certeza provocará dúvidas, portanto lembro que os comentários deverão ser usados para tirar dúvidas. Não deixem nenhuma dúvida passar nesse momento, pois isso poderá depois complicar o aprendizado de outros tópicos avançados.</p>
<p align="justify">O tema de hoje, e de mais alguns posts é Matrizes e Ponteiros.</p>
<p align="justify">Antes, porém, de vermos alguma programação, precisamos de alguma teoria:</p>
<h3 align="justify">Memória e Ponteiros:</h3>
<p align="justify">Quando vimos a <a href="https://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/" target="_blank">criação de variáveis</a>, ficou uma espécie de &#8220;aberto&#8221;. Lá foi dito que <em>&#8220;em C, as variáveis representam espaços de memória que o compilador irá preparar para determinadas funções para uso do programa.&#8221;</em> Na verdade, isso tá certo, mas não totalmente. Quando declaramos uma varíavel, indicamos ao computador que precisamos que uma derminada posição de memória seja separada para uso do programa e que, toda vez que o compilador achar o nome da variável, ele aponte o local em questão para onde a variável foi encontrada. Desse modo podemos dizer que o nome de uma variável é a &#8220;representação&#8221; do endereço onde fica o conteúdo da mesma.</p>
<p align="justify">Porém, existem situações onde precisamos utilizar uma posição de memória que não conhecemos previamente. Na realidade, isso é mais comum do que se imagina: não fosse assim, todo programa deveria ser artificialmente limitado em suas capacidades baseado em números arbitrários de informação a ser processada. Por exemplo: um programa teria que criar previamente 500 variáveis de notas para processar o boletim escolar de uma classe de 20 alunos, sendo inútil para uma classe de 501 alunos. Isso também aumentaria o custo de desenvolvimento e manutenção de um programa de computador, além de utilizar os recursos de um computador de maneira pouco eficiente.</p>
<p align="justify">O C nos oferece um mecanismo muito importante para apontar-se para um local de memória previamente desconhecido, ao qual chamamos de <em>ponteiro</em>.</p>
<p align="justify">Uma variável de ponteiro (que chamaremos de <em>ponteiro</em>, ou <em>pointer</em>&nbsp;em inglês) é uma variável que armazena o <em>endereço</em>&nbsp;de memória onde o conteúdo que desejamos está. Ela em si não é o conteúdo (embora possamos manipular o ponteiro de modo a mudar o local de memória indicado conforme a necessidade), mas indica onde esse conteúdo tá armazenado. Usando esse ponteiro, podemos chegar ao conteúdo e o trabalhar.</p>
<p align="justify">Imagine o ponteiro como a agência de correio. Ela não é as pessoas para quem são entregues as mercadorias, mas ele sabe de alguma forma onde elas moram. O ponteiro funciona de maneira similar.</p>
<h3 align="justify">Matrizes, <em>strings</em> e ponteiros</h3>
<p align="justify">OK&#8230; Mas o que os ponteiros têm a ver com matrizes e <em>strings</em> (que, como vimos lá no Hello World, é uma matriz de caracteres). Bem. na realidade, podemos dizer que uma matriz é um ponteiro.</p>
<p align="justify"><em>&#8216;Como assim Bial?&#8221;</em></p>
<p align="justify">Quando você declara, por exemplo <font face="monospace">char nome[80]</font>, você está alocando 80 caracteres em uma matriz e apontando para o primeiro deles, de 0 a 79. (Veremos isso mais para frente quando falarmos de aritmética de ponteiros).</p>
<h3 align="justify">Um programa exemplo com ponteiros</h3>
<p align="justify">OK. Vamos dar um tempo na teoria. Hora de colocar a mão na massa. Digite e compile o programa abaixo:</p>
<blockquote><p align="justify"><font face="monospace">#include &lt;stdio.h&gt;</p>
<p>int main (void)<br />{<br /><font color="#000099"><b>&nbsp; char palavra[80]=&#8221;Hello World!&#8221;;<br />&nbsp; char *palavra2;</b></font><br /></font></p>
<p align="justify"><font face="monospace"><b>&nbsp; <font color="#990000">palavra2=palavra;</font></b></p>
<p><b><font color="#993399">&nbsp; printf(&#8220;O texto %s esta armazenado no endereco %p\n&#8221;,palavra,palavra);</font></b><br /><font color="#006600"><b>&nbsp; while (*palavra2)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;O caracter %c da palavra %s esta no endereco %p\n&#8221;,*palavra2,palavra,palavra2);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; palavra2++;<br />&nbsp;&nbsp;&nbsp; }</b><br /></font>&nbsp; return(0);</p>
<p>}<br /></font></p>
</blockquote>
<p align="justify">Bem, o início cansamos de ver, mas vamos ver as declarações que temos coisas interessantes nelas:</p>
<blockquote><p align="justify"><font face="monospace"><font color="#000099"><b>&nbsp; char palavra[80]=&#8221;Hello World!&#8221;;</p>
<p>&nbsp; char *palavra2;</b></font></font></p>
</blockquote>
<p align="justify">Na primeira linha, declaramos uma matriz de 80 caracteres na qual armazenaremos a <i>string</i> &#8220;Hello World!&#8221;. O C possui uma convenção bastante prática para <i>strings</i>: sempre que você coloca uma <i>string</i> entre aspas duplas (&#8220;), o compilador já sabe que deverá colocar ao final da <i>string</i> em questão o caracter terminador nulo (<font face="monospace">\ 0</font> &#8211; já vimos ele lá atrás, lembra?). No momento em que o programa é carregado, o próprio sistema aloca o equivalente a 80 caracteres e dentro deles coloca a <i>string</i> &#8220;Hello World!&#8221;. Em seguida, declaramos uma varíavel ponteiro de caracter (<font face="monospace">char *</font> &#8211; ocasionalmente lendo-se <i>char pointer</i>) chamada <font face="monospace">palavra2</font>. O asterisco é o símbolo que indica que a variável em questão é um <i>ponteiro para o tipo de dado desejado</i>, não o próprio dado. Embora todos os ponteiros tenham o mesmo tamanho, é importante indicar o tipo de dados ao qual aquele ponteiro aponta, pois o uso de um ponteiro de um tipo de dados errado pode acarretar problemas seríssimos (a má interpretação e uso dos dados pelo programa sendo o menor deles).&nbsp;</p>
<p align="justify">A linha seguinte:</p>
<blockquote><p align="justify"><font face="monospace"><b>&nbsp; <font color="#990000">palavra2=palavra;</font></b></font></p>
</blockquote>
<p align="justify">Tem que ser pensada calmamente. No caso de matrizes , existe uma coisa a ser mencionada: quando você utiliza o nome da variável sem um <font face="monospace">[]</font> (indicador de posição a referenciar), o C entende que você deseja utilizar ou manipular a o endereço que indica o priemiro item da matriz. Ao mesmo tempo, quando utilizamos apenas o nome da varíavel ponteiro sem o indicador <font face="monospace">*</font>, indica a mesma coisa. No caso, essa linha pode ser traduzida como:</p>
<p align="justify"><i>&#8220;Pegue o endereço do primeiro item da matriz </i><font face="monospace">palavra</font><i> e coloque-o como o endereço a ser apontado por </i><font face="monospace">palavra2</font><i>&#8220;</i></p>
<p align="justify">Ponteiros em C podem ter a posição à qual eles apontam modificadas em tempo de execução. Na realidade, os ponteiros são feitos justamente para terem esse comportamento: veremos a importância desse comportamento mais adiante, quando falarmos de alocação dinâmica de memória.</p>
<p align="justify">Em seguida temos um <font face="monospace">printf</font>:</p>
<blockquote><p align="justify"><font face="monospace"><b><font color="#993399">&nbsp; printf(&#8220;O texto %s esta armazenado no endereco %p\n&#8221;,palavra,palavra);</font></b></font></p>
</blockquote>
<p align="justify">A ideia aqui é mostra onde é que está, na memória, a <i>string</i> &#8220;Hello World!&#8221;. Em seguida temos um loop:</p>
<p align="justify"><font face="monospace"><font color="#006600"><b>&nbsp; while (*palavra2)</p>
<p>&nbsp;&nbsp;&nbsp; {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;O caracter %c da palavra %s esta no endereco %p\n&#8221;,*palavra2,palavra,palavra2);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; palavra2++;<br /></b></font></font></p>
<div align="justify"><font face="monospace"><font color="#006600"><b><br />&nbsp;&nbsp;&nbsp; }</b></font></font><br /><font face="monospace"><font color="#006600"><br /></font></font></div>
<div align="justify">Que irá deslocar o ponteiro <font face="monospace">palavra2</font> e mostrar em que lugar da memória cada um dos elementos de <font face="monospace">palavra2</font> está armazenado. Para isso, em ambos os caso, utilizamos o modificador de formato <font face="monospace">%p</font> que faz com que o <font face="monospace">printf</font> imprima na tela o local na memória onde o ponteiro está apontando, e não o seu valor. <br />Agora, uma coisa pode ficar confusa no <font face="monospace">printf</font> dentro do <i>loop</i>: por que quando queremos mostrar o caracter, temos que usar o símbolo <font face="monospace">*</font> e quando queremos mostrar o string e o endereço apontado não? Isso acontece porque, tanto o modificador %s quanto o %p esperam um <i>endereço de memória</i>, enquanto o modificador %c (para caracteres) espera um conteúdo &#8220;real&#8221; (no caso, um caracter). Basicamente essa é a diferença e é uma diferença importante em C: em muitos casos, o C espera conteúdos &#8220;reais&#8221;, discretos, como um número ou um caracter. Nos demais casos, normalmente se trabalhará com ponteiros. Não existem em C conceitos como &#8220;strings&#8221;, &#8220;filas&#8221; e &#8220;listas&#8221; como o de linguagens de maior nível, como PHP, Java ou Python. Na realidade, o C oferece mecanismos para criar-se e manipular-se esses tipos de dados, em especial por meio dos ponteiros, mas a linguagem em si não possui tratativa para tais estruturas de dados mais amplas. Veremos no futuro como criar algumas dessas estruturas de dados.<br />Vamos destrinchar um pouco mais esse <font face="monospace">while</font>, pois ele nos oferece dicas interessantes e maiores informações sobre como lidar com ponteiros em geral e com uma <i>string</i> em C em particular. Primeiro, vamos ver a &#8220;condição de saída&#8221; do <font face="monospace">while</font>:<br />
<blockquote><font face="monospace"><font color="#006600"><b>&nbsp; while (*palavra2)</b></font></font></p></blockquote>
<p>Ou seja, enquanto o valor apontado por <font face="monospace">palavra2</font> (<font face="monospace">*palavra2</font>) for considerado verdadeiro, o laço segue adiante. Agora, a pergunta que deve estar passando na cabeça é: <i>&#8220;como ele vai saber se o valor apontado é verdadeiro?&#8221; </i>Quem ficou atento ao que dissemos quando <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/24/uma-aprofundada-em-operadores-e-logica-em-c/">falamos sobre os operadores lógicos</a> deve ter se lembrado de que falamos que para o C qualquer valor é verdadeiro, à exceção do número <font face="monospace">0</font>, do caracter terminador nulo <font face="monospace">\ 0</font> e do valor pré-definido <font face="monospace">null</font>. Se lembrarmos como as <i>strings</i> são compostas em C, elas são seqüências de caracteres terminadas com o caracter terminador nulo <font face="monospace">\ 0</font>. Portanto, uma vez que o deslocamento do ponteiro leve-o para o caracter terminador nulo, o valor do ponteiro será falso e o programa sairá do <i>loop</i> que criamos.<br />&#8220;<i>Mas como fazemos o ponteiro avançar nos da string?</i>&#8220;. Para isso, usamos um pouco de <i>aritmética de ponteiro</i>. No C, se usarmos os operandos aritméticos mais rudimentares <font face="monospace">+</font> e <font face="monospace">-</font>, além do incremento e decremento unitários <font face="monospace">++</font> e <font face="monospace">&#8211;</font>, podemos fazer o ponteiro avançar ou recuar, ou então indicar elementos adiante e anteriores à posição indicada pelo ponteiro. No nosso caso, utilizamos o incremento unitário:<br />
<blockquote><font face="monospace"><font color="#006600"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; palavra2++;</b></font></font></p></blockquote>
<p>No endereço em <font face="monospace">palavra2</font> (perceba a ausência do asterisco). Nesse caso, estamos indicando que queremos passar para o próximo elemento de <font face="monospace">palavra2</font>. Quando o C executar essa operação, ele irá somar o equivalente ao número de bytes do tipo apontado por palavra2 ao valor de palavra2. Essa No nosso exemplo, não muda muita coisa, pois em quase todas as plataformas, um char tem o tamanho de 1 byte, mas esse é um conceito que é importante ficar claro: quando usamos operadores aritméticos para modificar <i>o endereço apontado por um ponteiro</i>, ele sempre trabalha somando ou <i>subtraindo em bytes o número de elementos do mesmo tipo vezes o tamanho do tipo</i>. Isso ficará mais claro no próximo post, quando iremos usar ponteiros para valores inteiros.<br />Isso nos dá como o programa funcionará conceitualmente, mas para melhor entendermos o que aconteceu, vamos analisar a saída do mesmo:<br />
<h3 align="justify">Analisando a saída do programa<br /></h3>
<p>OK, e como será a saída disso tudo?<br />O que iremos ter de saída do programa aparentará ser algo como a seguir:<br />
<blockquote><b><font face="monospace">O texto Hello World! esta armazenado no endereco <font color="#006600">0xbffc5eb0</font></font><br /><font face="monospace">O caracter H da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb0</font></font><br /><font face="monospace">O caracter e da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb1</font></font><br /><font face="monospace">O caracter l da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb2</font></font><br /><font face="monospace">O caracter l da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb3</font></font><br /><font face="monospace">O caracter o da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb4</font></font><br /><font face="monospace">O caracter&nbsp;&nbsp; da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb5</font></font><br /><font face="monospace">O caracter W da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb6</font></font><br /><font face="monospace">O caracter o da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb7</font></font><br /><font face="monospace">O caracter r da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb8</font></font><br /><font face="monospace">O caracter l da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eb9</font></font><br /><font face="monospace">O caracter d da palavra Hello World! esta no endereco <font color="#006600">0xbffc5eba</font></font><br /><font face="monospace">O caracter ! da palavra Hello World! esta no endereco <font color="#006600">0xbffc5ebb</font></font></b></p></blockquote>
<p>Os valores ao final de cada linha são os endereços onde estão armazenados os conteúdos em questão. Com certeze eles irão aparecer diferentes para você no momento em que você executar o programa, mas o importante é entendê-lo.<br />A primeira coisa é que todos os endereços são indicados no <a target="_blank" href="http://pt.wikipedia.org/wiki/Hexadecimal">formato numérico de base 16, chamado <i>hexadecimal</i></a>. Essa é uma convenção antiga adotada no mundo da informática para indicar endereços de memória. Não importa para nós as posições em questão, pois esses valores poderão (e provavelmente irão) mudar de execução em execução.<br />Na primeira linha, é indicado o endereço da <i>string</i> &#8220;Hello World!&#8221;, pego pelo endereço do início da matriz que armazena o vetor de dados. Repare bem que o endereço de &#8220;Hello World!&#8221; e do caracter &#8220;H&#8221; são os mesmos, e depois o endereço onde ficam armazenados cara caracter aumenta de um em um byte (que é o tamanho do tipo <font face="monospace">char</font>).<br />Como &#8220;brincadeira&#8221;, uma sugestão é tentar fazer com que a string seja &#8220;corrida&#8221; <i>ao contrário</i>. Isso pode ser feito utilizando o decremento unitário na aritmética de ponteiros e usando os endereços para comparar o momento em que o ponteiro <font face="monospace">palavra2</font> chegar no início da <i>string </i><font face="monospace">palavra</font> (lembre-se que deverá fazer comparações com o <i>endereço armazenado</i> em ambos os casos, e não com seus conteúdos). É algo mais difícil, e portanto ressalto que qualquer dúvida os comentários estão abertos para que elas sejam tiradas.<br />Bem, esse é apenas o início do caminho nos ponteiros em C. Na próxima &#8220;aula&#8221;, veremos mais sobre a aritmética de ponteiros e alocação dinâmica de memória, um tópico muito importante em C.<br />Até lá, bom estudo!</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/63/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/63/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=63&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2011/02/07/matrizes-e-ponteiros-parte-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
		<item>
		<title>Funções &#8211; Parte 2</title>
		<link>https://aulasdec.wordpress.com/2010/12/16/funcoes-parte-2/</link>
		<comments>https://aulasdec.wordpress.com/2010/12/16/funcoes-parte-2/#comments</comments>
		<pubDate>Thu, 16 Dec 2010 14:04:55 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Controle de Fluxo]]></category>
		<category><![CDATA[Funções]]></category>

		<guid isPermaLink="false">https://aulasdec.wordpress.com/?p=56</guid>
		<description><![CDATA[Olá a todos!Bem, primeiramente desculpem a demora, pois tive muitas atividades de trabalho que me &#8220;frearam&#8221; um pouco. Mas não perdi a vontade de passar o que sei de C. E vocês, ainda estão aqui aprendendo?Bem, então vamos continuar o tópico da aula anterior: Funções.Na aula anterior, vimos como construir uma função, porque devemos usá-las, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=56&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div align="justify">Olá a todos!<br />Bem, primeiramente desculpem a demora, pois tive muitas atividades de trabalho que me &#8220;frearam&#8221; um pouco. Mas não perdi a vontade de passar o que sei de C. E vocês, ainda estão aqui aprendendo?<br />Bem, então vamos continuar o tópico da aula anterior: <a target="_blank" href="https://aulasdec.wordpress.com/2010/12/01/funcoes-parte-1/">Funções</a>.<br />Na aula anterior, vimos como construir uma função, porque devemos usá-las, e como passar parâmetros e receber seus retornos. Com isso, podemos dizer que sabemos construir funções. Porém, ainda não sabemos como aproveitar ao máximo as funções, uma vez que vimos regras que &#8220;amarram&#8221; a construção de funções, tornando-as complexas. Em especial a regra de criar-se a função antes do uso (ou seja, colocar o código da função antes de qualquer chamada que seja feita a ela) é muito estranha. Na aula de hoje, iremos ver como escapar dessa &#8220;amarra&#8221; de programação. Também veremos uma característica das funções em C chamada <i>recursividade</i>, que é a capacidade de uma função chamar a sí própria, o que torna mais simples construir-se determinados algoritmos e programas.<br />Bem, vamos ao que interessa:</div>
<h3 align="justify">Protótipos de Função:</h3>
<div align="justify">Bem, vamos começar com o primeiro tópico, que é o de protótipos. No caso, teremos um programa em cada tópico. Para o nosso tópico, usaremos o programa abaixo:<br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt;</font></p>
<p><font color="#333399"><b><font face="monospace">int soma(int a, int b);</font><br /><font face="monospace">int subtracao(int a, int b);</font><br /><font face="monospace">int multiplicacao(int a, int b);</font><br /><font face="monospace">int divisao(int a, int b);</font></b></font></p>
<p><b><font color="#cc0000" face="monospace">void main(void)</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">{</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp; /**</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; * No GCC, esse cabecalho para main retorna o seguinte warning:</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; *</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; * warning: return type of &#8216;main&#8217; is not &#8216;int&#8217;</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; */</font></b><br /><font face="monospace">&nbsp; int val1=0, val2=0, opt=0, res=0;</font></p>
<p><font face="monospace">&nbsp; do</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Digite um valor:&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;val1);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Digite outro valor:&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;val2);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Escolha a operação a ser realizada&#8230;\n\n&#8221;);<br /></font><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;1 &#8211; Soma\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;2 &#8211; Subtracao\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;3 &#8211; Multiplicacao\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;4 &#8211; Divisao&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;0 &#8211; Sair do Programa\n\nDigite os operadores e a operacao separados por espaco:&#8221;);</font></p>
<p><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;opt);</font></p>
<p><font color="#009900"><b><font face="monospace">&nbsp; &nbsp;&nbsp; switch(opt)</font><br /><font face="monospace">&nbsp; &nbsp; &nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 1:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; res=soma(val1,val2);</font><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; break;</font><br /><font face="monospace">&nbsp; &nbsp; &nbsp; case 2:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; res=subtracao(val1,val2);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 3:</font><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; res=multiplicacao(val1,val2);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 4:</font><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; res=divisao(val1,val2);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 0:</font><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; break;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf(&#8220;Opcao invalida\n&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; continue;</font><br /><font face="monospace">&nbsp; &nbsp; &nbsp; }</font></b></font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (opt!=0) printf (&#8220;O resultado da sua operacao para %d e %d e %d\n\n&#8221;,val1,val2,res);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; } while (opt!=0);</font></p>
<p><b><font color="#cc0000" face="monospace">&nbsp; /**</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; * No GCC, a linha abaixo provoca o seguinte warning:</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; * </font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; * warning: &#8216;return&#8217; with a value, in function returning void</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">&nbsp;&nbsp; */</font><font color="#cc0000"></p>
<p></font><font color="#cc0000" face="monospace">&nbsp; return(0);</font><font color="#cc0000"><br /></font><font color="#cc0000" face="monospace">}</font></b></p>
<p><font face="monospace">int soma(int a, int b)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; return a+b;</font><br /><font face="monospace">}</font></p>
<p><font face="monospace">int subtracao(int a, int b)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; return a-b;</font><br /><font face="monospace">}</font></p>
<p><font face="monospace">int multiplicacao(int a, int b)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; return a*b;</font><br /><font face="monospace">}</font></p>
<p><font face="monospace">int divisao(int a, int b)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; return a/b;</font><br /><font face="monospace">}</font></p></blockquote>
</div>
<p>Primeira coisa: perceba que usamos novamente um outro tipo de protótipo para <font face="monospace">main()</font>, <b><font color="#cc0000" face="monospace">void main(void)</font></b>. Como dissemos nos comentários do programa, o uso desse protótipo não é padrão e irá retornar alertas (<i>Warnings</i>) pelo compilador. Se preferir fazer um programa<i> &#8220;</i>pedante&#8221; (ou seja, sem erros ou alertas), você pode trocar o protótipo do <font face="monospace">main()</font> de volta para o velho e bom <font face="monospace">int main(int argc, char** argv)</font>. De qualquer forma, apenas fizemos isso para demonstrar o que acontece quando tenta-se utilizar um desses protótipos não-padrão.
<div align="justify">Agora, vamos a algo importante antes de entrarmos no nosso tópico. Olhe o código em verde:<br />
<blockquote><font color="#009900"><b><font face="monospace">&nbsp;&nbsp;&nbsp; switch(opt)</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 1:</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; res=soma(val1,val2);</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; break;</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 2:</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; res=subtracao(val1,val2);</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; break;</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 3:</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; res=multiplicacao(val1,val2);</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; break;</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 4:</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; res=divisao(val1,val2);</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; break;</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; case 0:</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; break;</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; printf(&#8220;Opcao invalida\n&#8221;);</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp; continue;</font></b></font><font color="#009900"><b><br /><font face="monospace">&nbsp;&nbsp;&nbsp; }</font></b></font></p></blockquote>
<p>Esse comando de controle de fluxo, o <font face="monospace">switch</font>, é muito usado como substituto para cadeias monstruosas de <font face="monospace">if&#8230;elseif&#8230;else</font>, em especial quando existem códigos que serão usados em uma ou mais opções. O <font face="monospace">switch&#8230;case</font> compara o valor da variável dada como entrada (no nosso caso, <font face="monospace">opt</font>) com o valor inserido em cada uma das linhas <font face="monospace">case</font>. Caso o valor da variável em questão seja igual ao valor de um dos <font face="monospace">case</font>, o programa irá seguir a execução desse ponto até o final do bloco <font face="monospace">switch&#8230;case</font> ou até encontrar um comando <font face="monospace">break</font>, o que acontecer primeiro. No caso de nenhum dos <font face="monospace">case</font> case com o valor da variável a ser comparada, nada será feito, a não ser que exista uma cláusula <font face="monospace">default</font> estipulada no bloco. Nesse caso, o programa irá continuar a execução a partir desse ponto, valendo as mesmas regras para os demais <font face="monospace">case</font>. No nosso caso, por exemplo, se opt for igual a 7, o <font face="monospace">default</font> será executado e exibirá na tela <i>Opcao Invalida</i>, e retornará ao início do laço <font face="monospace">do&#8230;while</font>. Caso, por exemplo, <font face="monospace">opt</font> estivesse em 2, o resultado da função <font color="#009900"><b><font face="monospace">subtracao(val1,val2) </font></b></font>seria associado à variavel <font face="monospace">res</font> e em seguida o <font face="monospace">switch&#8230;case</font> seria interrompido.<br />Bem, agora que falamos desse comando de controle de fluxo que &#8220;passou batido&#8221; até agora, vamos falar sobre o nosso tópico atual.<br />Como vimos na <a target="_blank" href="https://aulasdec.wordpress.com/2010/12/01/funcoes-parte-1/">aula anterior</a>, as funções devem, na teoria, vir antes de serem usadas por um programa. Na realidade, isso não é bem verdade. O que o compilador normalmente precisa é saber <i>como trabalhar</i> com uma função, ou seja, os valores que ele precisa passar para a mesma como <i>parâmetros</i> e o <i>tipo de retorno</i> da mesma. O código em si não precisa sequer ser descrito como parte do seu programa, podendo estar (o código em si) em qualquer outro lugar. (lembram das bibliotecas, como <font face="monospace">stdio.h</font>, <font face="monospace">string.h</font> e <font face="monospace">stdlib.h</font>? Na realidade eles são úteis para o compilador saber como usar as funções que eles &#8220;representam&#8221;. Os códigos estão armazenados em outras bibliotecas e arquivos dentro do sistema operacional ou do compilador). Como exemplo, podemos pensar em um conector para celular. Cada celular usa um conector específico e, desde que o conector siga o tipo de conexão que o celular exige, pode ser usado conectores de quaisquer marcas (vide a quantidade de carregadores &#8220;genéricos&#8221; que existem por aí) e com qualquer tipo de entrada de energia (não importa se é de tomada ou de carro, por exemplo).<br />No C, chamamos esses &#8220;padrões&#8221; de <i>protótipos de função</i>. Um protótipo de função nada mais é que um informativo que o compilador usa para saber como &#8220;chamar&#8221; uma função. A idéia é que os protótipos representam a seqüência de parâmetros e o tipo de retorno das funções a serem usadas no nosso código. Lembram-se de quando falamos que existe a idéia de &#8220;caixa preta&#8221; no código? Os protótipos são o que permitem a existência dessa &#8220;caixa preta&#8221;: o que o programador e o compilador precisa saber é o que a função precisa de entrada e o que ela devolve como resultado. O programador não precisa como saber como a função foi construída (imaginando que não tenha sido ele que a construiu) e o compilador só precisa saber se as chamadas de função são &#8220;encaixáveis&#8221; corretamente ao código.<br />Quando o programa é compilado, as funções que não fazem parte do programa e que estão em biblotecas são &#8220;encaixadas&#8221; ao programa de várias formas em um passo chamado de <i>linkedição</i> (em alguns livros mais atuais, usa-se o termo <i>ligação</i>). Um binário sem ser linkeditado é chamado ocasionalmente de código-objeto e, embora não seja útil para ser executado, eles são muito úteis (veremos no futuro compilação de programas com múltiplos fontes), inclusive podendo conter funções que possam ser ligadas <i>a posteriori</i> a outros programas (nessa situação, o código-objeto é chamado também de <i>biblioteca</i>). Uma vez que o ou os programas-fontes sejam compilados e linkeditados, o binário executável está pronto.<br />Voltando ao assunto, é por meio dos protótipos que o compilador sabe como &#8220;encaixar&#8221; cada função nas partes onde as funções são chamadas (na realidade, são colocados endereços para onde o programa vai e segue a execução). Além disso, por meio dos protótipos que o compilador, até certo ponto, consegue &#8220;perceber&#8221; se o código está corretamente construído, pois ele tem todas as informações da entrada de dados (parâmetros) e da saída (retorno).<br />Para o protótipo da função, a construção é igual ao do nome da função no início da mesma (que alguns chamam de <i>cabeçalhos</i>), com a diferença do <font face="monospace">;</font> no fim do protótipo. Na realidade, para o protótipo, você <i>não precisa</i> colocar nenhum nome de variável. uma vez que nesse momento, o que ele precisa saber é <i>quais</i> os tipos de parâmetro a serem recebidos, e <i>não seu nome</i>. No caso, embora tenhamos usado:<br />
<blockquote><font color="#333399"><b><font face="monospace">int soma(int a, int b);</font></b></font></p></blockquote>
</div>
<p>para uma maior legibilidade do código, poderíamos usar simplesmente:<br />
<blockquote><font color="#333399"><b><font face="monospace">int soma(int, int);</font></b></font></p></blockquote>
<div align="justify">que seria tão útil quanto o protótipo que o colocamos. De qualquer forma, aconselho que mantenha as declarações com &#8220;nomes de variáveis&#8221; como uma boa prática, para aumentar a legibilidade sobre quais são os parâmetros a serem passadas. <br />Não existe o que falar mais: uma vez que o protótipo tenha sido colocado de alguma forma à disposição, o compilador pode buscar funções em qualquer lugar, seja dentro do código objeto equivalente ao fonte compilado, em um arquivo de biblioteca ou no próprio sistema operacional e &#8220;encaixá-las&#8221; ou &#8220;ligá-las&#8221; ao programa do usuário.<br />De resto, existe pouco o que falar desse programa, pois ele não tem mistérios quanto ao que cada função faz. Para as &#8220;brincadeiras&#8221;, sugerimos:
<ol>
<li>Tente remover os protótipos (comentando-os, por exemplo) e compilar os programas. Alguns compiladores irão dar alertas mas irão compilar o seu fonte, enquanto outros simplesmente se recusarão a compilar o fonte;</li>
<li>Para comprovar que o &#8220;nome de variável&#8221; no protótipo não faz diferença, modifique o &#8220;nome de variável&#8221; de alguma das funções no protótipo, <i>mas não na função;</i></li>
<li>Para entender bem a idéia dos protótipos de função, uma boa forma é ler a documentação da biblioteca-padrão do C. Existem muitas funções interessantes nela, em especial em bibliotecas como <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html"><font face="monospace">stdlib.h</font></a>, <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.14.html"><font face="monospace">string.h</font></a>, <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.12.html"><font face="monospace">stdio.h</font></a>, <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.15.html"><font face="monospace">time.h</font></a> e <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.7.html"><font face="monospace">math.h</font></a>. <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/index.html">Nesse link </a>você encontra a documentação completa das bibliotecas-padrão (em inglês). Procure ler com calma e tentar entender o que cada função faz. Obviamente você não compreendará tudo no presente momento, pois muitas funções lidam com conceitos avançados que ainda falaremos, mas com calma você verá algumas funções interessantes. Se possível, tente construir seus próprios programas e funções a partir dos códigos que mencionamos no momento;</li>
</ol>
<p>Bem, com isso terminamos a parte de <i>protótipos de função.</i> Vamos a um tópico mais interessante: recursividade.<br />
<h3 align="justify">Recursividade &#8211; Chamando a si próprio:</h3>
<p>Existem certos algoritmos (formas de descrever-se algo para um computador) que são mais facilmente representáveis quando eles usam de algum modo a si próprio. Dois exemplos clássicos são os cálculos de <a target="_blank" href="http://pt.wikipedia.org/wiki/Fatorial">Fatorial</a> e do <a target="_blank" href="http://pt.wikipedia.org/wiki/Sequ%C3%AAncia_de_Fibonacci">número Fibonacci</a>. Para relembrar, um número N fatorial (representado N!) é representado pela multiplicação de todos os inteiros até N (sendo que os fatoriais de 0 e 1 são definidos como 1). No caso, esse é o algoritmo que iremos ver em C, pois pe um exercício clássico de programação recursiva.<br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt;</font></p>
<p><b><font color="#000066" face="monospace">unsigned int fatorial (unsigned int a)</font><font color="#000066"><br /></font><font color="#000066" face="monospace">{</font><font color="#000066"><br /></font><font color="#000066" face="monospace"></font><font color="#ff0000" face="monospace">&nbsp; if ((a==0) || (a==1))</font><font color="#ff0000"><br /></font><font color="#ff0000" face="monospace">&nbsp;&nbsp;&nbsp; return 1;</font><font color="#ff0000"><br /></font><font color="#ff0000" face="monospace">&nbsp; else</font><font color="#ff0000"><br /></font><font color="#ff0000" face="monospace">&nbsp;&nbsp;&nbsp; return a*fatorial(a-1);</font><font color="#000066"><br /></font><font color="#000066" face="monospace">}</font></b></p>
<p><font face="monospace">int main(void)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp; unsigned int numeroFatorial=0;</font></p>
<p><font face="monospace">&nbsp; printf(&#8220;Digite o numero ao qual deseja-se obter fatorial (apenas positivos): &#8220;);</font><br /><font face="monospace">&nbsp; scanf(&#8220;%d&#8221;, &amp;numeroFatorial);</font><br /><font face="monospace">&nbsp; </font><br /><font face="monospace">&nbsp; printf(&#8220;%d! = %d\n&#8221;,numeroFatorial,fatorial(numeroFatorial));</font></p>
<p><font face="monospace">&nbsp; return(0);</font><br /><font face="monospace">}</font></p></blockquote>
<p>Esse código é bem básico e tem pouco mistérios. O importante é atentar ao código da função fatorial:<br />
<blockquote><b><font color="#000066" face="monospace">unsigned int fatorial (unsigned int a)</font></b><b><font color="#000066"><br /></font><font color="#000066" face="monospace">{</font></b><b><font color="#000066"><br /></font></b><b><font color="#ff0000" face="monospace">&nbsp; if ((a==0) || (a==1))</font></b><b><font color="#ff0000"><br /></font><font color="#ff0000" face="monospace">&nbsp;&nbsp;&nbsp; return 1;</font></b><b><font color="#ff0000"><br /></font><font color="#ff0000" face="monospace">&nbsp; else</font></b><b><font color="#ff0000"><br /></font><font color="#ff0000" face="monospace">&nbsp;&nbsp;&nbsp; return a*fatorial(a-1);</font></b><b><font color="#000066"><br /></font><font color="#000066" face="monospace">}</font></b></p></blockquote>
<p>A primeira coisa que ele define é que, caso o valor passado na execução da função seja 0 ou 1, o valor a ser devolvido pela execução é 1. Caso contrário, ele irá devolver o valor passado vezes <i>o valor devolvido pela execução da mesma função com um valor igual ao valor passado-1</i>.<br />Como funcionaria então, por exemplo, para o fatorial 5? Vejamos em um <i>teste de mesa</i>:
<ul>
<li><font face="monospace">main</font> começa executando <font face="monospace">fatorial(5)</font>;</li>
<li>Como 5 não é igual a 0 ou 1, ele deveria retornar 5*o resultado de <font face="monospace">fatorial(5-1)</font>, ou seja, <font face="monospace">fatorial(4)</font>. Como não sabe o valor de <font face="monospace">fatorial(4)</font>, ele executa <font face="monospace">fatorial(4);</font></li>
<li>Como 4 também não é igual a 0 ou 1, ele deveria retornar 4*o resultado de <font face="monospace">fatorial(4-1)</font>, ou seja, <font face="monospace">fatorial(3)</font>. Como não sabe o valor de <font face="monospace">fatorial(3)</font>, ele executa <font face="monospace">fatorial(3);</font></li>
<li>Como 3 também não é igual a 0 ou 1, ele deveria retornar 3*o resultado de <font face="monospace">fatorial(3-1)</font>, ou seja, <font face="monospace">fatorial(2)</font>. Como não sabe o valor de <font face="monospace">fatorial(2)</font>, ele executa <font face="monospace">fatorial(2);</font></li>
<li>Como 2 também não é igual a 0 ou 1, ele deveria retornar 2*o resultado de <font face="monospace">fatorial(2-1)</font>, ou seja, <font face="monospace">fatorial(1)</font>. Como não sabe o valor de <font face="monospace">fatorial(1)</font>, ele executa <font face="monospace">fatorial(1);</font></li>
<li>Como 1 é igual a 1, a função fatorial retorna 1;</li>
<li>Agora ele volta para a execução de <font face="monospace">fatorial(2)</font>, pois obteve o valor de <font face="monospace">fatorial(1)</font>, que ele precisava. Ele faz 2*fatorial(1), ou seja, 2*1, retornando 2;</li>
<li>Em seguida, retoma a execução de <font face="monospace">fatorial(3)</font>, pois obteve o valor de <font face="monospace">fatorial(2)</font>, que ele precisava. Ele faz 3*fatorial(2), ou seja, 3*2, retornando 6;</li>
<li>Em seguida, retoma a execução de <font face="monospace">fatorial(4)</font>, pois obteve o valor de <font face="monospace">fatorial(3)</font>, que ele precisava. Ele faz 4*fatorial(3), ou seja, 4*6, retornando 24;</li>
<li>Por fim, retoma a execução de <font face="monospace">fatorial(5)</font>, pois obteve o valor de <font face="monospace">fatorial(4)</font>, que ele precisava. Ele faz 5*fatorial(4), ou seja, 5*24, retornando 120 para <font face="monospace">main</font>;</li>
</ul>
<p>Atenção para a questão de:<br />
<blockquote><b><font color="#ff0000" face="monospace">&nbsp; if ((a==0) || (a==1))</font></b><b><font color="#ff0000"><br /></font><font color="#ff0000" face="monospace">&nbsp;&nbsp;&nbsp; return 1;</font></b></p></blockquote>
<p>Todo algoritmo recursivo deve ter uma situação de &#8220;escape&#8221;, caso contrário provocará um <i>loop</i> infinito. No caso do fatorial, é o fato que os fatoriais de 0 e 1 são definidos por padrão como 1 (<a target="_blank" href="http://pt.wikipedia.org/wiki/Fatorial">no link da Wikipedia mostrado anteriormente</a> há uma explicação dos motivos desses valores serem <i>pré-definidos</i>). Somando-se isso e o fato de que a chamada recursiva é sempre equivalente ao valor da chamada atual-1, o resultado é que <i>cedo ou tarde</i>, o valor vai ser 0 ou 1 (valores negativos são negados já na tipagem <font face="monospace">unsigned int</font>), ou seja, a &#8220;escada&#8221; de chamadas irá ser desfeita, com cada chamada devolvendo os valores esperados pela anterior. Caso isso não ocorra, haverá um <i>loop</i> &#8220;infinito&#8221; que se encerrará com um estouro de memória (uma vez que cada chamada de função armazena localmente valores e portanto precisa de espaço de memória).<br />Bem, não existe mais o que se falar sobre recursividade. Como &#8220;brincadeiras&#8221; quanto recursividade, sugiro:
<ol>
<li>Uma circunstância a ser levada em consideração ao se construir algoritmos com recursividade é sobre o uso dos operadores unários de incremento e decremento (<font face="monospace">++</font> e <font face="monospace">&#8211;</font>). Para observar seu impacto, no <font face="monospace">return a*fatorial(a-1)</font>, tente substituir por <font face="monospace">return a*(a&#8211;)</font> e verifique o que acontece. Lembre-se que os operadores unários de incremento e decremento atuam como operadores de incremento/decremento <i>e </i>atribuição;</li>
<li>Edite o código da chamada recursiva e elimine a &#8220;condição de escape&#8221; da recursão. Coloque algum código que permita você visualizar os valores recebidos a cada chamada recursiva e seus impactos e analise o resultado final;</li>
<li>Tente implementar o algoritmo para determinar-se um <a target="_blank" href="http://pt.wikipedia.org/wiki/Sequ%C3%AAncia_de_Fibonacci">número Fibonacci</a>. Lembrando que um número de Fibonacci equivale à soma de todos os números naturais antecessores a ele, predefinido que o 0° Fibonacci é 0 e o 1° Fibonacci é 1. Se você reparar bem, não é muito diferente do cálculo de um número Fatorial;</li>
</ol>
<p>Com isso, acabamos o básico de Funções. Ainda existem tópicos a serem cobertos. Em especial, um tópico importante que estamos deixando para trás é o de <i>tipos de passagem de parâmetro</i>, um tópico importante que cobriremos quando falarmos de <i>ponteiros</i>, nosso próximo assunto.<br />Vamos ter algum tempo até começarmos o assunto de <i>ponteiros</i>. Enquanto isso, existem muitos sites e apostilas na internet com exercícios de programação em C que poderão ajudar você a fixar o conteúdo que vimos até agora. Enquanto a mim, vou ficar um tempo sem uma Internet de boa qualidade, mas prometo que, assim que voltar estarei postando o início do tópico de ponteiros, com a parte de matrizes, ponteiros e a correlação entre os dois. Esse será um tópico bastante complexo, mas que se lido com calma irá ser bem fixado.<br />Então, nos vemos em 2011, pessoal. Até lá, boas festas e muita programação C para todo mundo! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/56/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=56&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2010/12/16/funcoes-parte-2/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
		<item>
		<title>Funções &#8211; Parte 1</title>
		<link>https://aulasdec.wordpress.com/2010/12/01/funcoes-parte-1/</link>
		<comments>https://aulasdec.wordpress.com/2010/12/01/funcoes-parte-1/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 16:24:58 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Funções]]></category>

		<guid isPermaLink="false">https://aulasdec.wordpress.com/?p=52</guid>
		<description><![CDATA[Olá a todos!Bem, agora já estamos começando a pensar em programas nós mesmos, não é? Agora, vamos pensar um pouco no programas que fizemos lá atrás, quando falamos de Entrada de Dados e Variáveis. Aquele foi um programa razoavelmente grande. Agora imagine que você crie um programa realmente complexo, que realize atividades similares em diversos [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=52&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá a todos!<br />Bem, agora já estamos começando a pensar em programas nós mesmos, não é?
<div align="justify">Agora, vamos pensar um pouco no programas que fizemos lá atrás, quando falamos de <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/">Entrada de Dados e Variáveis</a>. Aquele foi um programa razoavelmente grande. Agora imagine que você crie um programa realmente complexo, que realize atividades similares em diversos pontos do mesmo. Se você escrever esse programa como criamos o programa de exemplo de Entrada de Dados e Variáveis, você teria um grande programa com vários pontos repetidos. Desse modo, caso precisasse alterar o modo como essas atividades similares seriam executadas, você teria que mexer em vários pontos similiares, o que mesmo o melhor dos programadores não conseguirá com facilidade e sem a possibilidade de provocar erros. <br />Por isso, o C (como toda boa linguagem de programação) prevê formas de dividir o programa em &#8220;pedaços&#8221; que executem a mesma tarefa. Chamamos esses pedaços de <i>funções</i>.<br />Na realidade, já usamos muitas funções até aqui. Todo comando que mostramos até agora, à exceção de palavras chaves como <font face="monospace">if</font> ou <font face="monospace">do&#8230;while</font>, são <i>funções</i>. A vantagem de dividir-se o programa em funções é que podemos isolar determinadas atividades nelas, o que permite:
<ol>
<li>Programas escritos de maneira mais legível;</li>
<li>Melhor manutenção do código, em especial em projetos complexos; você foca só no que está dando errado e uma vez que tudo esteja OK as melhorias se refletem <i>apenas</i> no que está dando errado;</li>
<li>Reutilização de código: por meio das <i>funções</i> podemos criar bibliotecas de funções (lembra do que falamos anteriormente sobre isso?) que englobem funções que usamos constantemente em um (ou mesmo em vários programas) e com isso reaproveitar esse código em muitos casos;</li>
</ol>
<p>Claro que uma função deve ser criada para ser suficientemente genérica, mas feito isso ela pode ser aproveitada nos mais diversos momentos.<br />Bem, dito essa teoria, vamos ao nosso programa exemplo: um programa de médias escolares.<br />
<blockquote><font face="monospace">#include &lt;stdio.h&gt;</font><br /><font face="monospace"></font><br /><font face="monospace">/**</font><br /><font face="monospace"> * Essa função de média irá acrescentar os valores adicionados à média </font><br /><font face="monospace"> * anterior e devolverá a média no momento</font><br /><font face="monospace"> */</font><br /><font color="#000099"><b><font face="monospace">float media(float nota)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp;&nbsp; static float mediaAtual=0.0;</font><br /><font face="monospace">&nbsp;&nbsp; mediaAtual=(mediaAtual==0)?nota:(mediaAtual+nota)/2;</font><br /><font face="monospace">&nbsp;&nbsp; return mediaAtual;</font><br /><font face="monospace">}</font><br /><font face="monospace"></font></b></font><br /><font face="monospace">int main(void)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; float nota=0.0;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; int notas=0;</font><br /><font face="monospace"></font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; do</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">        printf(&#8220;Digite a próxima nota ou -1 para sair:&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">        scanf(&#8220;%f&#8221;,&amp;nota);</font></p>
<p><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">        if (nota!=-1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br /></font>&nbsp; &nbsp; &nbsp;<font face="monospace"> &nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">notas++;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">           printf(&#8220;Com essa nota, a média total é de %9.2f\n&#8221;,media(nota));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;</font><font face="monospace">} while (nota!=-1);</font></p>
<p><font face="monospace"></font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">    return 0;</font><br /><font face="monospace">}</font></p></blockquote>
<p>Na parte do <font face="monospace">main()</font> fica a ressalva de que mudamos um pouco o início: de<font face="monospace"> int main (int argc, char** argv),</font> estamos usando <font face="monospace">int main(void)</font>. Como dissemos no <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/05/o-primeiro-programa-helloworld-c/"><i>Hello World</i></a>, essa construção (sobre a qual aproveitaremos para falar a seguir) pode ser mudada, embora o compilador possa gerar um aviso de que você está fugindo do padrão do C. No nosso caso, colocamos <font face="monospace">void</font> nos parâmetros para indicar que não receberemos parâmetros (<font face="monospace">void</font> é uma palavra reservada do C que indica algo &#8220;vazio&#8221; &#8211; veremos mais sobre isso adiante), ou melhor, que não utilizaremos parâmetros que sejam passados. De resto, o nosso <font face="monospace">main()</font> engloba coisas que já vimos nas últimas semanas e que você deve estar afiado caso tenha seguido as sugestões que fizemos para mexer no código e compreendido o que fizemos até agora. Na verdade, tem algo que iremos falar, mas apenas depois que vermos nossa função:<br />
<blockquote><b><font face="monospace"><font color="#000099">float media(float nota)</font></font><font face="monospace"><br />{</font><font face="monospace"><br />&nbsp;&nbsp; <font color="#993399">static float mediaAtual=0.0;</font></font><font face="monospace"><br />&nbsp;&nbsp; mediaAtual=(mediaAtual==0)?nota:(mediaAtual+nota)/2;</font><font face="monospace"><br />&nbsp;&nbsp; <font color="#006600">return mediaAtual;</font></font><font face="monospace"><br />}</font></b></p></blockquote>
<p>Já falamos anteriormente sobre o conceito de <i>blocos de código</i>. Basicamente, um bloco de código é uma parte do programa que é isolada logicamente e considerada como um comando único. Para &#8220;isolar-se&#8221; um bloco de código em C, usa-se as chaves (<font face="monospace">{}</font>). De maneira &#8220;rápida e suja&#8221;, podemos definir uma função como um &#8220;bloco de código com nome&#8221;. Na realidade, uma função pode estar em um outro ponto do programa ou até mesmo em um arquivo totalmente isolado. A única regra para uma função é que ela tem que vir de alguma forma &#8220;antes&#8221; de qualquer ponto do programa onde ele seja usado (na próxima semana, quando encerrarmos o assunto Funções, veremos que não é bem assim e existem técnicas simples que permitem ao programador colocar sua função onde deseejar).<br />Uma função na realidade é caracterizada por realizar alguma tarefa e retornar algum valor. Para facilitar a vida do programador e desobrigá-lo de saber o que a função <i>realmente faz</i>, toda linguagem de programação parte do princípio de que uma função é uma &#8220;caixa preta&#8221;: você coloca determinados <i>parâmetros</i> na entrada da mesma, ele realiza algum processamento (que o programador não precisa realmente saber do que se trata) e devolve ao usuário alguma saída. Porém, embora seja uma &#8220;caixa preta&#8221;, é sempre necessário a uma função indicar o que ela espera receber de parâmetros para trabalhar e o que o usuário irá receber de volta. No C isso é feito no momento em que se nomeia a função.<br />Como dissemos acima, podemos pensar em uma função como um &#8220;bloco de código com nome&#8221;. Em C, chamamos o &#8220;nome da função&#8221; de <i>protótipo</i> ou <i>assinatura</i> (esse último é mais usado em documentos focando C++ e tem a ver com certas propriedades da mesma). O <i>protótipo</i> de uma função costuma seguir o formato:
<div align="center"><b><font face="monospace">retorno nome (tipoPar1 par1[=init1],</font></b><b><font face="monospace">tipoPar2 </font></b><b><font face="monospace">par2[=init2],&#8230;,</font></b><b><font face="monospace">tipoParN </font></b><b><font face="monospace">parN[=initN])</font></b></div>
<p>Onde:
<ul>
<li><font face="monospace">retorno</font> indica o tipo de varíavel que a função retorna. Esse tipo pode ser qualquer tipo básico do C, ponteiros (veremos isso quando entrarmos nesse assunto) ou <font face="monospace">void</font>: <font face="monospace">void</font> pode ser entendido como um nulo, ou seja, quando C executar uma função cujo retorno seja void ele não deve esperar nenhum retorno do mesmo (na realidade, alguns compiladores costumam provocar erros de compilação);</li>
<li><font face="monospace">nome</font> é o nome pelo qual a função é chamada. Os nomes de função seguem as mesmas regras que vimos quanto aos nomes de variável que vimos quando falamos de  <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/">Entrada de Dados e Variáveis</a>.&nbsp; Além disso, não podem ter o mesmo nome de funções que tenham sido importadas por meio de <font face="monospace">#include</font>s. Uma coisa: mesmo para as funções da biblioteca padrão vale a mesma regra. Por exemplo: se eu não importar a <font face="monospace">stdio.h</font>, posso incluir minha própria versão de <font face="monospace">printf</font> sem problemas. Veremos o motivo disso adiante;</li>
<li>Dentro dos parênteses incluímos uma série de indicações sobre os <i>parâmetros da função</i>, <b><font face="monospace">tipoPar1 par1[=init1],</font></b><b><font face="monospace">tipoPar2 </font></b><b><font face="monospace">par2[=init2],&#8230;,</font></b><b><font face="monospace">tipoParN </font></b><b><font face="monospace">parN[=initN]</font></b>. Elas são distrinchadas assim: <font face="monospace">tipoPar</font> é o tipo da variável em questão, que pode ser de qualquer tipo básico do C, tipos do usuário ou ponteiros (veremos os dois últimos no futuro). A ele pode ser agregado um modificador <font face="monospace">const</font>, que indica que, não importa o que aconteça, esse valor não deve ser modificado (esse modificador só é útil quando usamos ponteiros &#8211; explicaremos o porque quando alcançarmos esse tópico); <font face="monospace">par</font> é o nome do parâmetro. Opcionalmente, você tem <font face="monospace">init</font>, que permite que você defina um valor <i>default </i>para inicialização, que será colocado caso esse parâmetro não seja passado (isso é feito ao deixar o espaço desse parâmetro vazio, sem nenhuma váriavel ou valor, mesmo <font face="monospace">null</font> &#8211; para o compilador, passar <font face="monospace">null</font> é passar um valor, ainda que nulo).</li>
<li>Uma ressalva sobre parâmetros: se você não esperar nenhum parâmetro em uma função, é uma boa prática inserir <font face="monospace">void</font> dentro dos parênteses, ainda que parênteses em branco (<font face="monospace">()</font>) seja igualmente suficiente para indicar uma função sem parâmetros. Essa boa prática ajuda na leitura do que a função faz e em muitas documentações você verá ela sendo adotada;</li>
</ul>
<p>Bom, após vermos como é nomeada uma função, vamos ver o nome de nossa função e destrinchá-la:
<div align="center"><b><font face="monospace"><font color="#000099">float media(float nota)</font></font></b></div>
<div align="justify">
<ul>
<li>Primeiro, indicamos que ela é uma função que irá devolver um valor de ponto flutuante (<b><font face="monospace"><font color="#000099">float</font></font></b>);</li>
<li>Depois, informamos que o seu nome é <b><font face="monospace"><font color="#000099">media</font></font></b>;</li>
<li>E na parte de parâmetros, indicamos que ela recebe apenas um parâmetro, do tipo flutuante e chamado nota (<b><font face="monospace"><font color="#000099">float nota</font></font></b>). Também, pela ausência de um igual, indicamos que ela não tem um valor <i>default</i>. Portanto, a ausência desse parâmetro irá provocar um erro. Se tivéssemos indicado um <i>default</i> e não passássemos um valor, o compilador poderia devolver um alerta, mas ainda assim o programa iria compilar normalmente;</li>
</ul>
<h3>Escopo de varável e o modificador <font face="monospace">static</font>:</h3>
<p>Dito isso, vamos falar sobre o código. Na nossa primeira linha, temos uma declaração especial:<br /><b><font face="monospace">&nbsp;&nbsp; <font color="#993399">static float mediaAtual=0.0;</font></font><font face="monospace"><br /></font></b>Essa única linha vai nos levar a todo um tópico de explicações. Na realidade, para entendermos ela totalmente, precisaremos falar sobre <i>escopo de variável</i> e sobre como funciona a declaração de variáveis dentro de uma função.<br />Como já fizemos no <font face="monospace">main()</font> quando falamos de  <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/">Entrada de Dados e Variáveis</a>, podemos declarar variáveis internas em uma função&nbsp; Na realidade, você pode declarar variáveis dentro de qualquer <i>bloco de código</i>. Como uma função é um &#8220;bloco de código nomeado&#8221;, podemos definir variáveis dentro delas. Além dos parâmetros (que são variáveis dentro da função), podemos declarar quantas variáveis que acharmos necessárias. No caso, da mesma forma que uma variável no <font face="monospace">main()</font> representa o local onde um conteúdo fica dentro do programa principal, uma variável dentro de uma função representa o local onde um conteúdo ficará armazenado dentro da função. Importante, porém, é notar que uma variável dentro de uma função pode ter um nome que já esteja sendo usado <i>fora da função</i>. Isso é possível pois, embora os nomes das variáveis sejam iguais, seus <i>escopos</i> são diferentes: uma vale para a função <font face="monospace">main()</font>  e outra para a função que o usuário criou, e o compilador, ao gerar o programa, tratará tais variáveis como variáveis <i>diferentes</i> e portanto com locais em memória <i>diferentes</i>. Existem algumas formas de mudar esse comportamento que veremos adiante.<br />Normalmente, ao chamar-se uma função, todas as suas variáveis são reinicializadas com os valores que o usuário definiu (ou com valores arbitrários, caso não o tenha feito), ou seja, podemos dizer que a cada chamada de uma função o valor de suas variáveis é resetado. Esse é o comportamento esperado, pois parte-se do princípio que cada chamada de uma função irá processaar valores não exatamente iguais. <br />Porém, existem casos onde podemos precisar que um ou mais valores permaneçam &#8220;salvos&#8221; entre chamadas de uma mesma função. Para garantir que isso aconteça, utilizamos um modificador na declaração da variável chamado <font face="monospace">static</font> (estático). O que ele faz é garantir que a variável em questão tenha seu valor mantido entre as várias chamadas à função. Ou seja, após a função terminar sua execução, seu valor não é resetado como normalmente acontece. Uma situação onde isso pode ser útil é quando, por exemplo, desejamos saber o número de pessoas que executou uma determinada transação bancária: uma forma bruta seria colocar uma variável somando o número de requisições feitas à função de transação e depois definir uma forma de obter-se esse valor. (Embora normalmente só um valor possa ser retornado por função, existem &#8220;truques&#8221; que permitem obter-se mais de um valor &#8211; veremos tais &#8220;truques&#8221; quando falarmos sobre passagem de valor para funções, no próximo <i>post</i>).<br />No caso, voltando ao nosso programa, o que fazemos é declarar nossa variável <font face="monospace">mediaAtual</font> como tipo flutuante (<font face="monospace">float</font>) e estática (<font face="monospace">static</font>), inicializando ela como <font face="monospace">0.0</font> (zero flutuante). Essa inicialização será feita <i>apenas na primeira chamada à função dentro do programa</i>. Uma vez que essa chamada tenha se encerrado, na entrada seguinte o sistema irá manter o valor com o qual a variável encerrou a chamada anterior. Ou seja, caso o valor final de&nbsp; <font face="monospace">mediaAtual</font> seja 2, esse será o valor de <font face="monospace">mediaAtual</font> na chamada seguinte.<br />Você deve estar se perguntando agora: &#8220;qual a diferença entre usar <font face="monospace">static</font> e <font face="monospace">const</font> em uma função?&#8221;. Aparentemente seria nenhuma, mas na verdade é ENORME:
<ul>
<li><font face="monospace">const</font> é usado quando você não quer que, <i>durante a execução da função</i>, o valor da varíavel seja alterado. Porém, uma vez que uma <font face="monospace">const</font> é uma variável como outra qualquer até ser inicializada, ela também tem valores arbitrários preenchidos nela até ser inicializada (lembre-se que uma <font face="monospace">const</font> só pode ser inicializada, ou seja, receber um valor, UMA ÚNICA VEZ). No caso de <font face="monospace">const</font>, após o término da execução da função, o valor definido na inicialização é perdido e poderá receber um valor completamente diferente na próxima execução;</li>
<li><font face="monospace">static</font> deve ser usado quando você não quer que, <i>entre execuções da função</i>, o valor da variável em questão seja perdido. Dentro da função, durante a execução da mesma, você poderá alterar normalmente, como qualquer outra variável. Porém, seu valor não será &#8220;resetado&#8221; após o término da execução da função.</li>
<li>Aqui cabe dizer ainda que é possível criar-se uma variável <font face="monospace">static const</font>. Esse &#8220;pequeno monstrinho&#8221; seria uma variável dentro de uma função cujo valor permaneceria sempre o mesmo entre todas as chamadas da mesma, definido na inicialização da variável na primeira chamada. CUIDADO: esse tipo de &#8220;monstrinho&#8221; pode gerar dor de cabeça séria na programação e normalmente não fará nada de mais interessante que não possa ser feito, por exemplo, com símbolos <font face="monospace">#define</font>;</li>
</ul>
<p>Bem, não temos muito o que dizer aqui mais sobre o <i>escopo</i>. Veremos um pouco mais sobre escopo de variáveis no futuro. Agora, vamos continuar analizando nosso código.<br />
<h3>Retorno &#8211; a palavra chave <font face="monospace">return</font>:</h3>
<p>Continuando nosso código, após a declaração de variável, temos o seguinte código:<br />
<blockquote><b><font face="monospace">&nbsp;&nbsp; mediaAtual=(mediaAtual==0)?nota:(mediaAtual+nota)/2;</font></b><br /><b><font face="monospace">&nbsp;&nbsp; <font color="#006600">return mediaAtual;</font></font></b></p></blockquote>
<p>A primeira linha representa uma <i>atribuição condicional </i>que <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/24/uma-aprofundada-em-operadores-e-logica-em-c/">vimos na última &#8220;aula&#8221; ao aprofundarmos operadores e lógica</a>. No caso, quando <font face="monospace">mediaAtual</font> for 0 (no caso, na primeira chamada de função), ele receberá o valor de <font face="monospace">nota</font> (parâmetro passado pelo usuário). Caso contrário, irá manter em mediaAtual o valor médio entre <font face="monospace">mediaAtual</font> e <font face="monospace">nota</font>. Não há muito mistério aqui e, embora a construção possa ser confusa, é só ler com atenção que fica claro o que estamos fazendo. Em seguida, usamos a palavra chave <font face="monospace">return</font> para devolver a main (que chamou essa função) o valor calculado. <br />Se lembrarmos bem, temos visto <font face="monospace">return</font> desde <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/05/o-primeiro-programa-helloworld-c/">nosso primeiro &#8220;Hello World&#8221;</a>. Isso porque, como dissemos na época, mesmo main() é uma função para o C, ainda que especial. E a última coisa que qualquer função precisa fazer é <i>devolver o controle </i>da execução para a função que a chamou. Para isso, utilizamos <font face="monospace">return</font> para indicar que terminamos de processar tudo o que devíamos e que o processador pode voltar para onde ele tinha parado antes de começar a executar nossa função.<br /><i>&#8220;Como assim?&#8221;</i>, você deve se perguntar. Bem, ao darmos início ao programa, o mesmo é carregado na memória por um processo de todo sistema operacional chamado <i>loader</i> e sua execução é iniciada. Conforme os comandos são executados, o sistema vai respondendo adequadamente, modificando espaços de memória (representados no programa pelas variáveis) e seguindo adiante de maneira sequencial (isso também considerando os comandos de controle de fluxo). Quando uma função é chamada, o programa principal passa o controle da execução para outro ponto completamente arbitrário dentro do espaço que o programa ocupa na memória e executa os comandos informados na função. Uma vez que termine, ele tem que devolver o controle para que o programa principal volte a ser executado, o que em C indicamos com <font face="monospace">return</font>, e assim sucessivamente até que o programa chegue ao fim do programa principal e seja encerrado.<br />O que precisamos saber então sobre o funcionamento de uma função:
<ol>
<li>Um programa pode requisitar a qualquer momento a execução de uma função;</li>
<li>Funções são usadas para tornar o programa mais reutilizável, mais fácil de manter-se e mais legível;</li>
<li>Ao requisitar a execução de uma função, o programa pode precisar passar <i>parâmetros</i> em uma ordem determinada, indicando o que a função precisa ter de entrada para trabalhar;</li>
<li>A função irá trabalhar como foi estipulado pelo criador da função: para o programa, uma função atua como uma &#8220;caixa-preta&#8221;;</li>
<li>A função devolve o controle de execução ao programa principal ao encerrar-se, devolvendo valores determinados pelo tipo de retorno da função como saída;</li>
</ol>
<p>Uma coisa antes de encerrarmos: ao devolver dados para o programa principal, devolvemos ele segundo o tipo estipulado <i>lá no protótipo da função</i>. Se for necessário por qualquer motivo, a função pode fazer <i>typecast</i> do valor devolvido antes de o retornar. Porém, é adequado que não seja usado tal expediente: use uma varíavel do mesmo tipo de retorno estipulado no protótipo e faça as operações necessárias a usando e use ela como valor para <font face="monospace">return</font>. Assim evitará dores de cabeças e <i>bugs</i> difíceis de depurar-se.<br />Bem, não temos mais o que falar sobre a função em questão, então vamos voltar ao programa principal.<br />No programa principal não há mistérios:<br />
<blockquote><font face="monospace">int main(void)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; float nota=0.0;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; int notas=0;</font></p>
<p><font face="monospace">&nbsp;&nbsp;&nbsp; do</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; {</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">        printf(&#8220;Digite a próxima nota ou -1 para sair:&#8221;);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">        scanf(&#8220;%f&#8221;,&amp;nota);</font></p>
<p><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">        if (nota!=-1)</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font><br />&nbsp; &nbsp; &nbsp;<font face="monospace"> &nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">notas++;</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">           printf(&#8220;Com essa nota, a média total é de %9.2f\n&#8221;,media(nota));</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;</font><font face="monospace">} while (nota!=-1);</p>
<p>&nbsp;&nbsp;&nbsp; printf(&#8220;Você inseriu %d notas.\n&#8221;, notas);</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">    return 0;</font><br /><font face="monospace">}</font></p></blockquote>
<p>Inicializamos duas variáveis, uma <font face="monospace">float</font> chamada <font face="monospace">nota</font> (que receberá a nota a ser &#8220;adicionada&#8221; à média) e uma inteira chamada <font face="monospace">notas</font> (que usamos como um contador do número de notas &#8220;adicionadas). Um laço do&#8230;while é usado para que novas notas sejam inseridas uma após a outra até que o usuário entre com -1 (que é considerado valor de saída).<br />A única coisa que precisamos aqui é a linha:<br /><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">&nbsp;&nbsp;&nbsp; </font><font face="monospace">           printf(&#8220;Com essa nota, a média total é de %9.2f\n&#8221;,<b><font color="#333399">media(nota)</font></b>);</font><br />A pergunta é <i>&#8216;essa é uma entrada válida&#8217;?</i> A resposta é: SIM.<br />No nosso caso, o <font face="monospace">printf</font> espera um valor de tipo flutuante (repare no formato <font face="monospace">%9.2f</font>), o que é oferecido por nossa função <font face="monospace">media</font> (que retorna um tipo flutuante). <i>&#8216;E se o programa esperasse, por exemplo, um <font face="monospace">int</font>, ou recebesse um <font face="monospace">int</font>?&#8217;</i> No caso, ocorreriam <i>typecasts</i>, mas o C sempre fará o possível para oferecer um retorno ao usuário, não importa se os valores saiam espúrios (ele parte do princípio de que o programador mantenha seus dados de maneira correta, não fazendo muitas checagens).<br />Bem&#8230; Vamos encerrar por agora nessa semana. Na próxima, iremos falar mais sobre funções, incluindo uma aprofundada nos tipos de escopo de variáveis e algumas dicas úteis (e IMPORTANTÍSSIMAS) sobre funções e seus <i>protótipos</i>.<br />Para essa semana, umas brincadeiras:
<div align="justify">
<ol>
<li>Renomeie <font face="monospace">mediaAtual</font> para outros nomes de variáveis que ocorram e veja o que irá acontecer;</li>
<li>Remova <font face="monospace">static</font> da declaração de variável da função <font face="monospace">media</font>;</li>
<li>Tente reescrever media de modo que você não precise usar uma variável <font face="monospace">static</font> nela;</li>
<li>Escolha um segundo valor (por exemplo, -2) para &#8220;resetar&#8221; os valores de <font face="monospace">media</font>;</li>
<li>Tente imprimir o valor retornado por <font face="monospace">media</font> como inteiro e veja o que acontecerá;</li>
<li>Tente deslocar o código da função <font face="monospace">media</font> para abaixo da função <font face="monospace">main</font> e veja as mensagens de erro. Procure entender os motivos das mensagens;</li>
</ol>
<p>Bem, até semana que vem, quando veremos mais sobre funções, praticamente &#8220;fechando&#8221; o assunto.</div>
</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/52/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/52/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/52/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=52&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2010/12/01/funcoes-parte-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
		<item>
		<title>Uma aprofundada em operadores e lógica em C</title>
		<link>https://aulasdec.wordpress.com/2010/11/24/uma-aprofundada-em-operadores-e-logica-em-c/</link>
		<comments>https://aulasdec.wordpress.com/2010/11/24/uma-aprofundada-em-operadores-e-logica-em-c/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 18:21:08 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Operadores]]></category>

		<guid isPermaLink="false">https://aulasdec.wordpress.com/?p=47</guid>
		<description><![CDATA[OK.Vamos dar uma pequena pausa para aprofudar uma teoria que é necessária para seguirmos em frente: os operadores. Na nossa última &#8220;aula&#8221;, vimos um pouco sobre os operadores, em especial operadores matemáticos, lógicos e relacionais. Mas na verdade o C é composto por uma enorme gama de operadores, capazes de realizar muitas atividades. Aprender bem [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=47&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>OK.<br />Vamos dar uma pequena pausa para aprofudar uma teoria que é necessária para seguirmos em frente: os <i>operadores</i>.
<div align="justify">Na <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/">nossa última &#8220;aula&#8221;</a>, vimos um pouco sobre os operadores, em especial operadores matemáticos, lógicos e relacionais. Mas na verdade o C é composto por uma enorme gama de operadores, capazes de realizar muitas atividades. Aprender bem como usar operadores é algo importantíssimo para construir bons programas em C. Portanto, vamos dar uma pausa e reforçar essa teoria antes de seguirmos em frente.<br />A primeira coisa a entender é que temos vários tipos de operadores em C, que podemos dividir&nbsp; em &#8220;grupos&#8221; para facilitar a compreenção:
<ul>
<li>Operadores de atribuição &#8211; são operadores usados para atribuir-se valores a variáveis;</li>
<li>Operadores aritméticos &#8211; com ele realizamos operações matemáticas simples usando dois valores, os <i>operandos</i>;</li>
<li>Operadores relacionais &#8211; comparam os valores de dois operandos, verificando se eles representam verdades ou falsidades lógicas naquele momento;</li>
<li>Operadores lógicos &#8211; comparam os valores de dois operandos em termos lógicos, ou seja, comparações baseadas na lógica booleana (E, OU e NÃO);</li>
<li>Operadores de bits &#8211; Permitem realizar operações diretamente nos bits de um determinado valor (em geral, inteiro);</li>
<li>Operadores compostos &#8211; são operadores complexos que podem combinar as funções de dois operadores do tipos acima;</li>
<li>Operadores especiais -são operadores usados no desenvolvimento da aplicação;</li>
</ul>
<p>Além disso, existe uma ordem de prioridade dos operadores que iremos mostrar no final desse <i>post</i>. Você não precisa decorar essa tabela: você pode utilizar esse <i>post</i> como referência ou então facilmente pegar uma &#8220;cola&#8221; dessa tabela na Internet em vários sites de referência.<br />Bem, vamos começar então com o Operador de Atribuição.<br /><big><big></big></big><br />
<h3>Operador de atribuição &#8211; <font face="monospace">=</font></h3>
<p>O operador de atribuição <font face="monospace">=</font> serve para indicar ao C que desejamos armazenar (ou <i>atribuir</i>) a uma determinada variável um valor. Já vimos nos programas anteriores vários exemplos de atribuições, em especial quando inicializamos variáveis como fizemos no programa de <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/">Entrada de Dados</a>. Uma coisa, porém, que é importante dizer é que o C permite fazer-se múltiplas atribuições, desde que os tipos sejam compatíveis. Por exemplo, o trecho de código abaixo:<br />
<blockquote><b><font face="monospace">int a,c;</font><br /><font face="monospace">float b,d;</font><br /><font face="monospace">a = b = c = d = 0;</font></b></p></blockquote>
<p>É válido, uma vez que <font face="monospace">b</font> e <font face="monospace">d</font>, ainda que sejam do tipo <font face="monospace">float</font>, podem receber valores inteiros (por causa do <i>autocast</i> &#8211; lembra que vimos quando mostramos o programa de <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/">Entrada de Dados</a>?). Basicamente, esse comando faz a seguinte salada na atribuição:
<ul>
<li>Atribui 0 a <font face="monospace">d</font> &#8211; como <font face="monospace">d</font> é <font face="monospace">float</font>, dá o <i>autocast</i> do <font face="monospace">0</font> (que nesse caso é tratado como inteiro) para <font face="monospace">float</font>;</li>
<li>Em seguida, atribui a <font face="monospace">c</font> o valor de <font face="monospace">d</font> &#8211; <font face="monospace">d</font> está inicializado como <font face="monospace">0.0</font> (0 no tipo <font face="monospace">float</font>). Ao receber o valor para <font face="monospace">c</font>, o sistema faz o <i>autocast</i> do valor, truncando-o para <font face="monospace">0</font> (inteiro);</li>
<li>Após isso, atribui a <font face="monospace">b</font> o valor de <font face="monospace">c</font> &#8211; repete-se o caso da atribuição para <font face="monospace">d</font>;</li>
<li>E por fim, atribui a <font face="monospace">a</font> o valor de <font face="monospace">b</font> &#8211; repetindo o que aconteceu quando atribui-se a <font face="monospace">c</font> o valor de <font face="monospace">d</font>;</li>
</ul>
<p>Importante notar que os <i>autocasts</i> são sempre executados no momento da <i>atribuição </i>do valor a uma variável. Por isso que, se dividimos dois inteiros e precisamos de um valor <font face="monospace">float</font>, mesmo atribuindo o resultado, precisamos forçar o <i>cast</i> de um dos inteiros para <font face="monospace">float</font> antes: se usarmos a divisão normalmente, ele irá tratá-la como divisão entre dois inteiros e dará um resultado inteiro, que será convertido <i>depois da operação</i> em <font face="monospace">float</font>. Ao forçar um deles como <font face="monospace">float</font>, indicamos que precisamos de um resultado em ponto flutuante e, dando o <i>autocast</i> no outro operando, o programa realizará uma divisão em ponto flutuante e retornará um valor <font face="monospace">float</font>.<br />Aproveitando que entramos no assunto <i>typecast</i>, existe uma prioridade nos <i>autocasts</i>: isso é feito com o objetivo de impedir que os resultados percam valor (por exemplo, ao converter-se um valor de um tipo para um outro tipo cujo tamanho seja menor em <i>bits</i> e, portanto, capaz de representar uma gama inferior de valores). Tenha isso em mente ao recorrer ao <i>autocast</i>: prefira, se possível, fazer você mesmo o <i>typecast</i>, pois isso irá garantir que você sabe qual será o tipo resultante.<br />Dito isso, vamos para o próximo conjunto de operadores.<br />
<h3>Operadores aritméticos<font face="monospace"></font></h3>
<p>Já falamos sobre eles antes: são operadores que realizam contas matemáticas simples entre dois operandos (valores), &#8220;devolvendo&#8221; um deles como valor da expressão aritmética (em C, uma <i>expressão aritmética</i> tem o mesmo significado que na matemática, e o termo <i>expressão</i> é extrapolado a partir daí como a representação de uma operação lógico-matemática que será resolvida em um determinado momento). Esse valor pode ser usado em uma atribuição ou em qualquer lugar onde exija-se um valor. Isso é interessante pois pode-se executar operações matemáticas, por exemplo, antes de operações lógicas, obviamente respeitando as prioridades determinadas pelo C (veremos abaixo as prioridades e como alterar a ordem de execução das operações).<br />Basicamente, as operações matemáticas são:<br />
<table width="400" border="1">
<tbody>
<tr>
<td style="width:20%;height:100%;">Operador
<div align="center"><font face="monospace">*</font><br /><font face="monospace">/</font><br /><font face="monospace">%</font><br /><font face="monospace">-</font><br /><font face="monospace">+</font></div>
</td>
<td>
<div align="center">Operação</div>
<p>Multiplicação<br />Divisão<br />Resto da Divisão Inteira (mod)<br />Subtração<br />Soma</td>
<td style="width:20%;height:100%;">Prioridade
<div align="center">1<br />1<br />1<br />2<br />2</div>
</td>
</tr>
</tbody>
</table>
<p>
<div align="justify">Na coluna Prioridade, fazemos uma referência a como o C prioriza as operações aritméticas entre si. No caso, primeiro o C executa divisões, multiplicações e resto de divisões conforme apareçam da esquerda para direita (como é feito na matemática). Em seguida, o C executa somas e subtrações (também da esquerda para a direita, conforme a matemática). Existem formas de alterar a prioridade da execução de fórmulas complexas, que veremos mais abaixo. Mas, basicamente, essas são as operações matemáticas possíveis de serem feitas com o C. Uma ressalva: diferentemente de outras linguagens de programação, C não possui um operador matemático para potenciação.<br />Em C, a divisão é palco de uma controversa. Normalmente em C, é feita divisão inteira entre valores se ambos forem do tipo <font face="monospace">int</font>, mesmo que a atribuição do resultado seja feita para uma variável de valor flutuante. Isso deve-se ao fato de que o C considera dois momentos: (1) quando a operação de divisão é feita e (2) quando o valor resultante é atribuido à variável de ponto flutuante. Porém, se no momento da execução da divisão, um dos valores for de tipo flutuante (seja por ser uma varíavel <font face="monospace">float</font> ou por um <i>cast</i>), o C irá pegar o termo restante, forçar o <i>cast</i> (<i>autocasting</i>) do mesmo para um tipo flutuante e retornar o resultado da operação com um valor de tipo flutuante. Isso é algo a manter-se em mente.<br />O operando % (resto da divisão inteira) é um caso a parte: ele vai transformar <i>ambos os termos </i>em inteiros, uma vez que o conceito de resto só existe em matemática quando falamos de número inteiros (mesmo nos casos de dízimas periódicas ou não periódicas, a matemática parte do princípio que, cedo ou tarde podemos descobrir o &#8220;último dígito&#8221; de um valor). Essa conversão é feita <i>truncando-se</i> o valor decimal do número com tipo flutuante, tornando-o inteiro. Porém, isso pode provocar inexatidão em resultados, podendo afetar os resultados finais do programa. Para isso, o C oferece uma <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.7.html">biblioteca especializada em funções matemáticas, <font face="monospace">math.h</font></a>, sobre a qual ainda iremos falar de maneira mais aprofundada.<br />Bem, dito isso, vamos seguir falando dos operadores. No caso, vamos falar dos operadores relacionais.<br />
<h3>Operadores relacionais</h3>
<p>O nome meio que diz tudo: operadores relacionais envolvem a relação entre dois valores específicos de maneira lógica, comparando-os entre si e vendo se a relação em questão é verdadeira ou não. Basicamente eles devolvem 1 caso a relação seja verdadeira, e 0 caso a mesma seja falsa. (Lembrando que, como vimos na <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/">nossa última &#8220;aula&#8221;</a> não existe no C um tipo booleano, então ele adota <font face="monospace">0</font>, <font face="monospace">&#8220;&#8221;</font> (<i>string</i> vazia) ou o símbolo <font face="monospace">null</font> como convenções para <i>falso</i> e quaisquer outros valores como verdadeiro). Para ter uma noção do funcionamento do mesmo, rode o seguinte programa (retirado do <a target="_blank" href="http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c360.html">material do Curso de C da UFMG</a>):<br />
<blockquote>
<pre>#include &lt;stdio.h&gt;
int main()
{
    int i, j;

    printf("\nEntre com dois numeros inteiros: ");
    scanf("%d%d", &amp;i, &amp;j);

    printf("\n%d == %d é %d\n", i, j, i==j);
    printf("\n%d != %d é %d\n", i, j, i!=j);
    printf("\n%d &lt;= %d é %d\n", i, j, i&lt;=j);
    printf("\n%d &gt;= %d é %d\n", i, j, i&gt;=j);
    printf("\n%d &lt; %d é %d\n", i, j, i&lt;j);
    printf("\n%d &gt; %d é %d\n", i, j, i&gt;j);
    return(0);
}</pre>
</blockquote>
<p>Não existe muito a ser dito sobre novos comandos como fizemos em outros casos. O importante aqui é estudar o comportamento dos operadores relacionais, que estamos listando abaixo, já indicando também sua prioridade entre si:</div>
</div>
<table width="400" border="1">
<tbody>
<tr>
<td style="width:20%;height:100%;">Operador
<div align="center">&gt;&nbsp; <br />    &gt;=&nbsp; <br />    &lt;&nbsp; <br />    &lt;= <br />    ==&nbsp; <br />    != </div>
</td>
<td>
<div align="center">Operação</div>
<p>Maior do que&nbsp; <br />Maior ou igual a&nbsp; <br />Menor do que&nbsp; <br />Menor ou igual a&nbsp; <br />Igual a&nbsp; <br />Diferente de </td>
<td style="width:20%;height:100%;">Prioridade
<div align="center">1<br />1<br />1<br />1<br />2<br />2</div>
</td>
</tr>
</tbody>
</table>
<p>Aqui voltaremos a enfatizar:<br />
<blockquote>
<div align="center"><b>NÃO EXISTE TIPO BOOLEANO EM C! EM C, QUALQUER VALOR DIFERENTE DE 0 OU DA <i>STRING</i> VAZIA &#8220;&#8221; OU DE NULL É CONSIDERADO VERDADEIRO!</b></div>
</blockquote>
<div align="justify">Além disso, vamos reenfatizar outra coisa: <i>nunca confunda o operador relacional de igualdade (</i><font face="monospace">==</font><i>) com o de atribuição (</i><font face="monospace">=</font><i>)</i>. Isso irá provocar erros de lógica de aplicação que são de difícil depuração.<br />Pois bem, esses três primeiros tópicos, falando de operadores de atribuição, aritméticos e relacionais são apenas uma revisão do que vimos anteriormente. A partir de agora iremos ver operadores que vimos por alto ou não vimos anteriormente, a começar pelos&#8230;</div>
<h3 align="justify">Operadores lógicos</h3>
<div align="justify">Operadores lógicos são basicamente operadores que realizam comparações. De certa forma, são um subgrupo dos operadores relacionais, mas que trabalham apenas com valores segundo a <a target="_blank" href="https://secure.wikimedia.org/wikipedia/pt/wiki/L%C3%B3gica_booleana"><i>lógica booleana</i></a>. De uma forma rápida, podemos dizer que eles podem comparar se dois valores são verdadeiros ao mesmo tempo (E/AND), se pelo menos um entre dois valores pode ser considerado verdadeiro (OU/OR) e se um determinado valor é falso naquele momento (NÃO/NOT). A vantagem de usar-se operadores lógicos é que, combinando-os com os operadores relacionais, podemos construir condições complexas, em especial em situações de controle de fluxo. Por exemplo, vamos relembrar um trecho de código de <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/">nossa última &#8220;aula&#8221;</a>:<br /><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; do<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(“Quantas tentativas você acha que precisa para descobrir ele? “);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(“%d”,&amp;maximoTentativas);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (maximoTentativas&lt;1)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(“Você precisa tentar ao menos uma vez! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  \n”);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (maximoTentativas&gt;limiteTentativas)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(“%d tentativas? Tá querendo demais também! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  \n”,maximoTentativas);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } while (<b>maximoTentativas&lt;1 || maximoTentativas&gt;limiteTentativas</b>);</font></p>
</div>
<div align="justify">Relembrando: o <font face="monospace">do&#8230;while</font> executa enquanto a condição indicada no final do bloco de código for considerada verdadeira. No caso, nossa intenção foi garantir que o usuário não entrasse com nenhum número negativo e nem fosse além de um limite de tentativas estipulado previamente. Para isso, utilizamos duas condições relacionais (<font face="monospace"><b>maximoTentativas&lt;1</b></font> e <font face="monospace"><b>maximoTentativas&gt;limiteTentativas</b></font>), cada uma atuando em uma das situações que determinamos. Para &#8220;unirmos&#8221; as duas situações, usamos o operador lógico OU (<font face="monospace">||</font> em C) que indica que, enquanto pelo menos uma dessas condições relacionais for verdadeira, a condição lógica será verdadeira e, portanto, o programa permanecerá executando esse bloco de código.<br />C implementa os principais operadores relacionais, que são o E (AND), OU (OR), e NÃO (NOT), conforme representado abaixo:<br />
<table width="400" border="1">
<tbody>
<tr>
<td style="width:20%;height:100%;">Operador
<div align="center"><font face="monospace">!</font><br /><font face="monospace">&amp;&amp;</font><br /><font face="monospace">||</font></div>
</td>
<td>
<div align="center">Operação</div>
<p>NÃO Lógico<br />E Lógico<br />OU Lógico</td>
<td style="width:20%;height:100%;">Prioridade
<div align="center">1<br />2<br />3</div>
</td>
</tr>
</tbody>
</table>
<p>O programa abaixo, também retirado do <a target="_blank" href="http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c360.html">material do Curso de C da UFMG</a> poderá ilustrar melhor o comportamento de E, OU e NÃO:<br />
<blockquote>
<pre>#include &lt;stdio.h&gt; &lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; &nbsp; int i, j;&lt;br /&gt;&nbsp;  printf("informe dois números(cada um sendo 0 ou 1): ");&lt;br /&gt;  &nbsp;scanf("%d%d", &amp;i, &amp;j);&lt;br /&gt;  &nbsp;printf("%d AND %d é %d\n", i, j, i &amp;&amp; j);&lt;br /&gt;  &nbsp;printf("%d OR %d é %d\n", i, j, i || j);&lt;br /&gt;  &nbsp;printf("NOT %d é %d\n", i, !i);&lt;br /&gt;}&lt;br /&gt;</pre>
</blockquote>
<p>Na verdade, com o tempo esse conceito ficará bem arraigado na cabeça. Então vamos para os próximos operadores.<br />Antes, um parênteses: em vários momentos, e em especial quando falamos dos <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/">tipos de dados em C,</a> mencionamos que em C, as<i> strings</i> de caracteres possuem um comportamento diferenciado em relação ao que vemos em outras linguagens de programação. Por isso, você NÃO DEVE utilizar os operadores lógicos e relacionais apresentados anteriormente com <i>strings</i>. Isso irá provocar certamente resultados espúrios. Para comparações envolvendo strings, a <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.14.html">biblioteca padrão </a><font face="monospace"><a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.14.html">string.h</a> </font>oferece uma série de funções úteis, sobre as quais falaremos no futuro.<br />
<h3 align="justify">Operadores de bit (<i>bitwise</i>)<br /></h3>
<p>O C oferece um conjunto de operadores lógicos voltados exclusivamente para o &#8220;acesso direto&#8221; aos bits. Mais exatamente, para realizar operações lógicas com bits. Chamamos esses operadores de operadores de bit, bit-a-bit ou <i>bitwise</i>, dependendo do autor do livro. <br />C foi uma linguagem originalmente projetada para facilitar o desenvolvimento de aplicações em baixo nível, como sistemas operacionais, <i>firmware</i> (software de baixo nível para dispositivos eletrônicos, como celulares e players de DVD), compiladores, com o objetivo de substituir o Assembler e oferecer um mínimo de portabilidade de código, ainda que mantendo os benefícios do Assembler de acesso direto ao <i>hardware</i>. Como o <i>software </i>de um <i>appliance</i>, o <i>firmware</i>, se comunica com o <i>hardware</i> por pulsos eletrônicos interpretados pela CPU como <i>bits</i> 0s e 1s específicos em determinados locais de memória, é interessante que C possua comandos capazes de trabalhar com esses <i>bits</i>, que chamamos em programação de <i>flags</i>. Para isso, utiliza-se os operadores de bit.<br />Os operadores de bit lembram um pouco os operadores aritméticos e um pouco os operadores lógicos, pois eles irão realizar a operação lógica em cada bit de um determinado número, usando outro, e retornando um terceiro. Por exemplo, imaginemos que precisamos obter de um conjunto de <i>flags</i> (normalmente representados por um int) se o 5° <i>bit</i> dessa conjunto de <i>flags</i> está ativo. Uma forma é aplicar o <i>bitwise</i> AND (E bit-a-bit) contra o número 8 (representado 00001000). Esse valor (que alguns autores chamam de <i>bitmask</i> &#8211; máscara de bits) atua de tal forma que zera todos os outros bits do <font face="monospace">int</font> em questão: lembrando que ambos os <i>bit</i> tem que ser 1 &#8211; verdadeiro &#8211; para que o bit na saída seja 1. Como os demais bits no <i>bitmask</i> são 0, o valor de tais bits é zerado. Se o bit na flag estiver zerado, o resultado será 0, caso contrário o valor de saída será 8.<br />Existem também operadores de movimentação de <i>bits</i>: algumas operações matemáticas e lógicas são resolvidas facilmente quando utilizamos essa movimentação de <i>bits</i>, &#8220;empurrando&#8221; os bits à esquerda ou direita, com isso aumentando e diminuindo seus valores. Como exemplo: uma forma &#8220;rápida e suja&#8221; de fazer-se a potência de 2 em um número é &#8220;empurrando&#8221; seus <i>bits</i> uma casa para a direita. Como em numeração binária um bit é sempre uma potência de 2 acima do bit à direita ao seu, ao empurrar-se os bits à direita temos o efeito da potência de 2. (PS: esse método não faz as checagens matemáticas de casos especiais como potências de 0 e 1 e nem verificam estouros do tamanho de variável). Ao empurrar-se os bits, o último bit na direção para a qual os bits foram &#8220;empurrados&#8221; é eliminado e o primeiro bit da direção oposta é preenchido com 0.<br />Os operadores de bit são:<br />
<table width="463" border="1">
<tbody>
<tr>
<td style="width:20%;height:100%;">Operador
<div align="center">!<br />&lt;&lt;<br />&gt;&gt;<br /><font face="monospace">&amp;</font><br />^<br />|</div>
</td>
<td>
<div align="center">Operação</div>
<p>NÃO por bit a bit<br />Deslocamento de bits à esquerda<br />Deslocamento de bits à direita<br />E bit a bit<br />OU Exclusivo (um e apena um bit)<br />OU bit a bit</td>
<td style="width:20%;height:100%;">Prioridade
<div align="center">1<br />2<br />2<br />3<br />4<br />5</div>
</td>
</tr>
</tbody>
</table>
<p>Uma coisa a salientar de diferente entre os operadores bit-a-bit e os operadores lógicos é a existência do OU-Exclusivo (<i>eXclusive OR</i>, XOR) bit-a-bit. Nessa situação, ao comparar-se os dois números bit a bit, um bit na saída só será um se UM E APENAS UM dos bits comparados for 1. Caso contrário (ambos 0 ou ambos 1) o bit será zero.<br />Bem, esse é um tema complexo e pouco útil para nós. Vamos falar agora de&#8230;<br />
<h3>Operadores Compostos</h3>
<p>Operadores Compostos englobam operadores que atuam ao mesmo tempo como dois tipos diferentes de operadores, em geral uma operação bit-a-bit ou aritmética e uma atribuição. Além desses, existe o operador de <i>atribuição condicional</i> ?.<br />Vamos englobar em três subgrupos os operadores compostos: os de atribuição &#8220;aditiva&#8221;, os de incremento e decremento em um e o de atribuição condicional.<br />Os de atribuição &#8220;aditiva&#8221; são operadores que realizam uma determinada operação envolvendo um parâmetro com uma variável e atribuem <i>à mesma variável </i>o resultado da operação. Por exemplo, a expressão <font face="monospace">a+=4</font> é equivalente em termos de programação a <font face="monospace">a=a+4</font>. Esses operadores existem para ambientes onde o espaço para a leitura do código fonte é pequeno e determinadas redundâncias de digitação comprometeriam a compilação. Alguns autores consideram que o uso desse tipo de operador torna o programa mais legível, enquanto outros defendem que esse tipo de operador provoca a ofuscação do código (ou seja, torna a leitura do código complexa). A lista dos operandos compostos segue abaixo:<br />
<table width="607" border="1">
<tbody>
<tr>
<td style="width:20%;height:100%;">Operador
<div align="center">/=<br />*=<br />%=<br />+=<br />-=<br />&lt;&lt;<br />&gt;&gt;<br /><font face="monospace">&amp;</font><br />^<br />|</div>
</td>
<td>
<div align="center">Operação</div>
<p>Divisão com atribuição<br />Multiplicação com atribuição<br />Resto da divisão inteira com atribuição<br />Soma com atribuição<br />Subtração com atribuição<br />Deslocamento de bits à esquerda com atribuição<br />Deslocamento de bits à direita com atribuição<br />E bit a bit com atribuição<br />OU Exclusivo (um e apena um bit) com atribuição<br />OU bit a bit com atribuição</td>
<td style="width:20%;height:100%;">Prioridade
<div align="center">1<br />1<br />1<br />2<br />2<br />3<br />3<br />4<br />4<br />4</div>
</td>
</tr>
</tbody>
</table>
<p>Esse é um subtipo complexo, e o próximo também demanda atenção, que são os operadores de incremento e decremento em um. Na verdade, esses operadores são indicados por <font face="monospace">++</font> e <font face="monospace">&#8211;</font> e indicam que a variável onde eles estão sendo usados terá seu valor somado ou subtraído em 1. Porém, existe um comportamento que deve ser levado em conta ao usar-se tais operadores, que é o de <i>prefixação</i> e <i>pós-fixação</i>. Para usar-se os operadores desse tipo, você pode colocar o operador antes ou depois da varíavel. A posição onde o colocar, porém, irá afetar o comportamento sobre qual será o valor realmente usado. <br />Ao <i>prefixar</i> o operador antes da variável (ou seja, colocar<font face="monospace"> ++</font> ou <font face="monospace">&#8211;</font> antes da variável), o valor será modificando <i>antes</i> de qualquer uso. Por exemplo, se você usar <font face="monospace">a=++b</font>, e <font face="monospace">b</font> for 4, acontecerá o seguinte: (1) <font face="monospace">b</font> será incrementada em 1, para 5 e (2) <font face="monospace">a</font> receberá o novo valor de <font face="monospace">b</font>, 5. Ao pós-fixar o operador, acontecerá o contrário: o valor será usada para qualquer outro fim <i>antes</i> de ser modificado. Mantendo o exemplo anterior, imagine que você, ao invés de usar <font face="monospace">a=++b</font>, utilizou <font face="monospace">a=b++</font>. Nesse caso (1) a receberá o valor atual de b, 4 e depois é que (2) b será incrementado em 1. Essa diferença é importante de ter-se em mente, pois ela pode provocar <i>bugs</i> (em especial quando utiliza-se esse operador em conjutnto com comparações relacionais), mas é uma ferramenta muito poderosa.<br />Por exemplo: nas &#8220;brincadeiras&#8221; da <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/">nossa última &#8220;aula&#8221;</a> sugeri:<br />
<blockquote>
<ul>
<li><i>Da mesma forma que existe o operador <font face="monospace">++</font>, existe o operador <font face="monospace">–</font>, que subtrai um da variável que o antecede. Considerando isso e o funcionamento do laço <font face="monospace">for</font>, tente reconstruir o laço para não ter uma condição no sentido exato da palavra. Dica: lembre-se que C trata <font face="monospace">0</font> como falso;</i></li>
</ul>
</blockquote>
<p>A forma para fazer isso é lembrar que o <font face="monospace">for</font>, na comparação, exige um &#8220;booleano&#8221; verdadeiro (ou seja, qualquer valor diferente de 0). Portanto, se usarmos o operador de decremento em 1 pós-fixado, podemos fazer com que o número de tentativas vá se reduzindo até que, na última tentativa, ele chegue na condição em 0 e, sendo &#8220;falso&#8221;, saia do laço. Portanto, basta substituir a linha:<br />
<blockquote><font color="#993399"><b><font face="monospace">for (i=1; i&lt;=maximoTentativas;i++)</font></b></font></p></blockquote>
<p>no programa da <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/">nossa última &#8220;aula&#8221;</a> por:</div>
<blockquote><p><font face="monospace">for (i=1; maximoTentativas&#8211;; i++)</font></p></blockquote>
<p>e teremos feito a mágica. Na realidade, se não usarmos a variável i para exibir o número da tentativa, podemos simplesmente reduzir o comando para:<br />
<blockquote><font face="monospace">for (; maximoTentativas&#8211;;)</font></p></blockquote>
<p>e o código terá o mesmo comportamento, sem precisar de uma variável de controle.
<div align="justify">Mas, ATENÇÃO: isso só funcionará bem se você usar o decremento <b>pós-fixado</b>. Se tentar prefixar o decremento, ele irá, na prática, tirar uma tentativa do usuário, ao ponto de, se o usuário pedir apenas uma tentativa o sistema nem pedir o número: no caso, ele irá subtrair 1 de <font face="monospace">maximoTentativas</font> (que será 1), reduzindo-o para 0 e tornando a condição &#8220;falsa&#8221;.<br />Bem, aqui podemos dizer que terminamos de falar do incremento e decremento de um. Vamos falar, para acabar com os atributos compostos, da <i>atribuição condicional</i>.<br />Chamamos de <i>atribuição condicional </i>um operador que funciona como o seguinte tipo de lógica:<br />
<blockquote><font face="monospace">if (condicao)<br />&nbsp;&nbsp; var=x;<br />else<br />&nbsp;&nbsp; var=y;</font></p></blockquote>
<p>O C oferece um operador que permite-nos fazer esse tipo de condição diretamente na atribuição, o operador <font face="monospace">?</font>. Esse é um operador <i>ternário</i> (ou seja, exige três operandos), sendo composto por <font face="monospace">&lt;condicao&gt;?&lt;atr_verdadeiro&gt;:&lt;atr_falso&gt;</font>. Nesse caso, caso condicao seja verdadeira (diferente de 0), o operador irá devolver <font face="monospace">atr_verdadeiro</font>, enquanto que, caso condicao seja falsa (igual a zero), ele irá devolver o valor de <font face="monospace">atr_falso</font>. Por exemplo, imagine que você irá precisa do <i>módulo</i> de um número, ou seja, do valor sem sinal do mesmo. Ao invés de construir um if só para isso, você pode usar uma atribuição condicional:<br />
<blockquote><font face="monospace">modulo=(numero&lt;0)?numero*-1:numero;</font></p></blockquote>
<p>O que quer dizer que <font face="monospace">modulo</font> irá receber o valor de <font face="monospace">numero</font> vezes -1 caso <font face="monospace">numero</font> seja menor que 0; caso contrário, ele irá receber o valor normal de <font face="monospace">numero</font>.</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/47/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=47&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2010/11/24/uma-aprofundada-em-operadores-e-logica-em-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
		<item>
		<title>Controle de Fluxo e Operandos Lógicos</title>
		<link>https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/</link>
		<comments>https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 13:52:12 +0000</pubDate>
		<dc:creator>Fábio Emilio Costa</dc:creator>
				<category><![CDATA[Básico]]></category>
		<category><![CDATA[Controle de Fluxo]]></category>
		<category><![CDATA[Operadores]]></category>

		<guid isPermaLink="false">https://aulasdec.wordpress.com/?p=27</guid>
		<description><![CDATA[Olá!Vamos continuar então a programar em C. Os dois primeiros programas, Hello World e o de Entrada de Dados, tinham como ponto comum o fato de serem, vamos dizer assim, diretos. Eles eram executados, realizavam cada instrução em sequencia e se encerravam.Isso em si não é ruim: muitos programas simples e interessantes podem ser feitos [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=27&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Olá!<br />Vamos continuar então a programar em C.</p>
<div align="justify">Os dois primeiros programas, <a target="_blank" href="http://aulasdec.wordpress.com/2010/11/05/o-primeiro-programa-helloworld-c/"><i>Hello World</i></a> e o de <a target="_blank" href="https://aulasdec.wordpress.com/2010/11/08/tipos-de-dados-e-variaveis/">Entrada de Dados</a>, tinham como ponto comum o fato de serem, vamos dizer assim, <i>diretos</i>. Eles eram executados, realizavam cada instrução em sequencia e se encerravam.<br />Isso em si não é ruim: muitos programas simples e interessantes podem ser feitos assim. Porém, é perceptível que eles não possuem nenhuma &#8220;inteligência&#8221;: eles não conseguem executar instruções dependendo das entradas que lhe são oferecidas. Isso se deve ao fato de eles não possuírem nenhum <i>controle de fluxo</i>. Em programação, esse termo é adotado para definir situações onde o programa pode mudar a sequencia de execução do programa conforme condições estipuladas no momento do desenvolvimento da aplicação. Por exemplo: no programa de Entrada de Dados, poderíamos estipular valores limite para <font face="monospace">primeiro</font> e <font face="monospace">segundo</font> que não os limites do tipo <font face="monospace">int</font>.<br />Pois bem, veremos agora um programa com um pouco mais de &#8220;inteligência&#8221;, pois iremos falar mais sobre os comandos de <i>controle de fluxo</i> em C e sobre os <i>operadores lógicos</i>, além de questões sobre o tipo booleano (ou melhor, sobre a ausência de um tipo booleano) em C.<br />No caso, vamos escrever um outro programa comum, o &#8220;adivinhe o número&#8221;. Mas vamos adicionar alguma &#8220;inteligência&#8221; a ele e tornar ele um pouco mais desafiador:</p>
<blockquote><p><b><font face="monospace">#include &lt;stdio.h&gt;</font></b><br /><font color="#ff0000"><b><font face="monospace">#include &lt;stdlib.h&gt;</font></b><br /></font><b><font face="monospace"><font color="#ff0000">#include &lt;time.h&gt;</font></font></b></p>
<p><b><font face="monospace">/* Definindo o número limite para a pessoa tentar descobrir */</font></b></p>
<p><b><font face="monospace"><font color="#6666cc">#define LIMITE 10</font></font></b><br /><b><font face="monospace"><font color="#6666cc">#define ENCERRA printf(&#8220;Pressione qualquer tecla para continuar!\n&#8221;); while(!getchar());</font></font></b></p>
<p><b><font face="monospace">int main (int argc, char** argv)</font></b><br /><b><font face="monospace">{<br />&nbsp; const int </font></b><font color="#000000"><b><font face="monospace">limiteTentativas=(LIMITE/2)-1;</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp; int numeroPensado=0, numeroDoUsuario=0, maximoTentativas=0,i;</font></b></font><br /><b><font face="monospace">&nbsp; </font></b><br /><b><font face="monospace">&nbsp; srand(time(<font color="#009900">NULL</font>)); // Serve para modificar a tabela de números pseudo-aleatórios</font></b><br /><b><font face="monospace">&nbsp; numeroPensado=rand()%LIMITE+1;</font></b></p>
<p><b><font face="monospace">&nbsp; printf(&#8220;OK! Pensei em um número entre 1 e %d e te desafio a achar ele!\n&#8221;, LIMITE);</font></b><br /><font color="#339999"><b><font face="monospace">&nbsp; do</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; {</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Quantas tentativas você acha que precisa para descobrir ele? &#8220;);</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;maximoTentativas);</font></b></p>
<p><font color="#ff6600"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (maximoTentativas&lt;1)</font></b><br /><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; printf(&#8220;Você precisa tentar ao menos uma vez! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> \n&#8221;);</font></b></font><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (maximoTentativas&gt;limiteTentativas)</font></b><br /><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; printf(&#8220;%d tentativas? Tá querendo demais também! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> \n&#8221;,maximoTentativas);</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; } while (maximoTentativas&lt;1 || maximoTentativas&gt;limiteTentativas);</font></b></font></p>
<p><font color="#993399"><b><font face="monospace">&nbsp; for (i=1; i&lt;=maximoTentativas;i++)</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; {</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Vamos lá! %da. tentativa! &#8220;,i);</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;numeroDoUsuario);</font></b></p>
<p><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (numeroDoUsuario==numeroPensado)</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Parabéns! Você acertou!\n&#8221;);</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; ENCERRA</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return(0);</font></b><br /><b><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; }</font></b><br /><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; else</font></b><br /><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; {</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; printf(&#8220;Não pensei em %d. &#8220;, numeroDoUsuario);</font></b><br /><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; if (numeroDoUsuario&lt;numeroPensado)</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&#8220;Pensei em um número maior.\n&#8221;);</font></b><br /><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; if (numeroDoUsuario&gt;numeroPensado)</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&#8220;Pensei em um número menor.\n&#8221;);</font></b><br /><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; }</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; }</font></b></font></p>
<p><b><font face="monospace">&nbsp; &nbsp; printf(&#8220;Que pena! Eu pensei em %d! Melhor sorte da próxima vez! \n&#8221;,numeroPensado);</font></b><br /><b><font face="monospace">&nbsp;&nbsp;&nbsp; ENCERRA</font></b><br /><b><font face="monospace">&nbsp; &nbsp; return(0);</font></b><br /><b><font face="monospace">}</font></b></p>
</blockquote>
<p>Como de costume, iremos ignorar algumas coisas que já vimos anteriormente. Portanto, se você ficar com alguma dúvida, dê uma relida nos <i>posts</i> anteriores para fixar bem o conteúdo que já lidamos. No caso, vamos falar sobre os trechos de código que estão com destaque colorido no fonte àcima.</p>
<h3><font face="monospace">#define</font> e os &#8220;números mágicos&#8221;<br /></h3>
<p>Logo de cara incluímos duas novas bibliotecas em C: <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html"><font face="monospace">stdlib.h</font> &#8211; <i>STanDard Library</i> (biblioteca padrão), que contêm uma série de funções cotidianas em C</a> &#8211; e <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.15.html"><font face="monospace">time.h</font>, que contem funções para lidar com tempo</a>. Dessas, a <font face="monospace">stdlib.h</font> em especial é muito importante, pois uma grande quantidade de comandos C muito usados está incluída nela. No caso, estamos muito interessados nas funções relacionadas à geração de números randômicos, mas existe muito mais nela e no futuro falaremos muito sobre essa biblioteca.<br />Logo após, vemos dois novos comandos<i></i> do pré-processador (ou <i>macros</i>, como são chamados tecnicamente):</p>
<blockquote><p><b><font face="monospace"><font color="#6666cc">#define LIMITE 10</font></font></b><br /><b><font face="monospace"><font color="#6666cc">#define ENCERRA printf(&#8220;Pressione qualquer tecla para continuar!\n&#8221;); while(!getchar());</font></font></b></p>
</blockquote>
<p>A <i>macro</i> <font face="monospace">#define</font> permite ao programador definir um símbolo que o pré-processador irá substituir por uma informação qualquer no momento da compilação. No caso, definimos dois símbolos:</p>
<ul>
<li>LIMITE &#8211; um número com valor 10;</li>
<li>ENCERRA &#8211; uma sequencia de comandos C;</li>
</ul>
<p>No caso, você pode se perguntar sobre a utilidade de definir-se símbolos. Esse sistema de símbolos permite:</p>
<ol>
<li>Criar &#8220;comandos&#8221; simples (caso do ENCERRA);</li>
<li>Criar situações de compilação condicional (um tópico mais avançado, veremos no futuro);</li>
<li>Evitar os chamados &#8220;números mágicos&#8221;;</li>
</ol>
<p><i>&#8220;Números mágicos?! Virou Hogwarts agora?&#8221;</i><br />Na verdade não. Em programação, chamamos de <i>números mágicos</i> determinados números ou expressões que são colocadas no código para realizar determinadas funções. No nosso caso, precisamos limitar o maior número no qual nosso programa irá &#8220;pensar&#8221;. Poderíamos simplesmente escrever ele no nosso programa de maneira direta, mas como esse número iria se repetir várias vezes em vários trechos de código aparentemente sem relação um com o outro, com certeza a leitura e análise de erros do programa (que em programação é chamada de <i>depuração</i>) seria complicada. Por isso chamamos tais números de <i>números mágicos</i>: uma vez que ele entra, temos dificuldades para entender o que eles fazem.<br />No caso, ao criarmos um símbolo (LIMITE), podemos usar ele no nosso código que o próprio compilador (através do pré-processador) irá substituir todas as entradas do símbolo LIMITE pelo valor desejado (no caso, 10). Isso torna o programa mais legível e mais simples de ser modificado.<br />O mesmo vale para ENCERRA. Com ENCERRA, criamos um &#8220;pseudo-comando&#8221;, um símbolo que será substituído por uma série de comandos C. No caso, o comando escrito em ENCERRA ajuda alguns usuários de IDEs (em especial no Windows) a visualizarem os resultados dos seus programas.<br />Existe mais sobre <font face="monospace">#define</font> que ainda iremos ver, em especial na questão dos &#8220;pseudo-comandos&#8221;, mas esse básico deve ajudar a compreender melhor as coisas até termos uma oportunidade de nos aprofundarmos nele (em especial, quando falarmos no futuro de outras <i>macros</i> de pré-processador, quando revisitaremos <font face="monospace">#include</font> e <font face="monospace">#define</font>).</p>
<h3><font face="monospace"></font>Variáveis Constantes:<br /></h3>
<p>Após as <i>macros</i> temos uma declaração de variáveis: logo de cara, temos uma que é um pouco diferente do que o que vimos quando falamos dos <a target="_blank" href="http://wp.me/p1aUtI-e">tipos de variáveis e como as declaramos</a>:</p>
<blockquote><p><b><font face="monospace">&nbsp; const int </font></b><font color="#000000"><b><font face="monospace">limiteTentativas=(LIMITE/2)-1;</font></b></font></p>
</blockquote>
<p>A principal diferença está na palavra reservada <font face="monospace">const</font> antes da declaração do tipo <font face="monospace">int</font> da variável <font face="monospace">limiteTentativas</font>. O que essa palavra faz é indicar ao compilador que essa variável na verdade é uma <i>constante</i> do tipo desejado, portanto não poderá mais ser modificada uma vez que seja inicializada, o que acontece em seguida. No caso, a variável constante  <font face="monospace">limiteTentativas</font> tem seu valor inicializado com o resultado de <font color="#000000"><font face="monospace">(LIMITE/2)-1</font></font>, ou seja, na divisão do valor do nosso símbolo LIMITE por 2, menos 1 (no caso atual, o valor final é 4).<br />Você deve estar se perguntando: &#8220;<i>usar um símbolo com </i><font face="monospace">#define</font><i> não seria mais interessante?&#8221;</i><br />Bem, nesse caso não. Perceba que o limite de tentativas é determinado baseando-se no valor de LIMITE, e o <font face="monospace">#define</font> não realiza <i>per se</i> contas ou qualquer processamento: tudo o que ele faz é dizer que (1) existe um símbolo e (2) qual seu valor. Se modificarmos o valor de LIMITE, teríamos que modificar o valor desse novo <font face="monospace">#define</font> manualmente. <br />Você pode pensar então: <i>&#8220;por que não tornar a fórmula um símbolo via </i><font face="monospace">#define</font><i>?&#8221;</i>. A ideia parece boa, mas ela cai em um problema: quando você substituir o símbolo, você obrigaria o sistema a repetir várias vezes uma determinada conta. Podemos pensar em desktops com gigas de poder de processamento e isso aparentemente ser uma boa ideia, mas pense em um sistema embarcado e você verá que uma situação como essa iria provocar redução na velocidade do programa.<br />Já com a variável constante, temos uma situação onde a variável não poderá ser modificada mas ainda assim será calculada apenas uma vez, apenas exigindo uma recompilação no caso de uma mudança de LIMITE (o que iria acontecer de qualquer maneira), pois ao compilar, LIMITE seria substituído pelo seu valor.<br /><i>&#8220;Eu tenho que OBRIGATORIAMENTE inicializar uma variável constante no momento em que a declaro?&#8221;</i>, você deve estar se perguntando. Na realidade, da mesma forma que ocorre com as variáveis comuns, as variáveis constantes PODEM ser inicializadas após a declaração. O que é impedido é que uma variável constante receba OUTROS VALORES após a inicialização. Como constantes são normalmente usadas para delimitar de alguma forma o comportamento do programa (no nosso caso, utilizaremos <font face="monospace">limiteTentativas</font> para delimitar o máximo de tentativas que uma pessoa terá de adivinhar o número &#8220;pensado&#8221; pelo computador), é uma boa prática inicializá-la antes de qualquer entrada de dados.<br />Bem, acho que fechamos aqui a questão das variáveis constantes, à exceção de uma coisa: por que logo abaixo vem uma segunda linha de declarações <font face="monospace">int</font>?<br />Quando você coloca várias declarações e/ou inicializações de variáveis em uma mesma linha, o compilador irá entender que todas elas tem o mesmo comportamento. Se colocássemos as <font face="monospace">int</font> em questão junto com a declaração <font face="monospace">const int </font>de limiteTentativas, essas variáveis também seriam declaradas constantes, o que não é o comportamento desejado. Nesse caso, a regra é clara: declarações de constantes devem ser separadas das declarações de variáveis comuns.<br />Bem, agora que vimos o bastante sobre constantes para entendermos o programa, sigamos em frente.</p>
<h3><font face="monospace">rand()</font>, <font face="monospace">srand()</font> e o gerador de números pseudo-aleatórios:<br /></h3>
<p>Vamos dar uma olhada nesse bloco de código:</p>
<blockquote><p><b><font face="monospace">srand(time(<font color="#009900">NULL</font>)); // Serve para modificar a tabela de números pseudo-aleatórios</font></b><br /><b><font face="monospace">numeroPensado=rand()%LIMITE+1;</font></b></p>
</blockquote>
<p>A primeira linha utiliza duas funções: a primeira é <font face="monospace">srand()</font>, da <font face="monospace">stdlib.h</font>, que recebe um <font face="monospace">long int</font> como entrada. Essa função serve para modificar a tabela de números <i>pseudo-aleatórios</i> do sistema, usando o <font face="monospace">long int</font> de entrada como parâmetro para essa modificação. No caso, usamos a função <font face="monospace">time(NULL)</font>, da biblioteca <a target="_blank" href="http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.15.html"><font face="monospace">time.h</font></a>, que devolve o horário do sistema atual em <a target="_blank" href="https://secure.wikimedia.org/wikipedia/en/wiki/Unix_time">UNIX TimeStamp</a> (<a target="_blank" href="https://secure.wikimedia.org/wikipedia/pt/wiki/Era_Unix">o número de segundos passados desde as 0:00 do dia 01/01/1970 até o momento atual</a>). Na verdade, ela retorna o <i>epoch time</i> (outra forma pela qual pode ser chamado o UNIX TimeStamp) para qualquer data passada de maneira correta (não entraremos nesse detalhe aqui).<br />Por que chamamos os números do sistema de <i>pseudo-aleatórios</i>?<br />Porque o computador não consegue, pela própria natureza lógica, gerar um padrão 100% aleatório. O que pode ser feito é utilizar-se algoritmos que gerem números, considerando-se a probabilidade de sua ocorrência em sequencia, que se aproximem da aleatoriedade e montar uma tabela com ela. O problema é que, ao se &#8220;pegar&#8221; um número nessa tabela é que, caso ela não seja &#8220;inicializada&#8221; de maneiras diferentes entre cada execução, o valor deixará de ser aleatório, ainda que continue sendo <i>não-determinístico</i> (ou seja, você não consegue, a partir das sequencias de números, determinar com precisão as fórmulas matemáticas que as geraram). Para evitar esse problema, utilizamos um comando, o <font face="monospace">srand()</font>, que irá modificar a <i>semente</i> da tabela de números pseudo-aleatórios, o que irá garantir que, a cada execução, como o Timestamp será diferente, a <i>semente</i> da tabela será diferente e, por sua vez, a saída da mesma será diferente (se quiser saber mais sobre a idéia de geração de números pseudo-aleatórios, <a target="_blank" href="https://secure.wikimedia.org/wikipedia/en/wiki/Pseudorandom_number_generator">dê uma olhada nesse artigo da Wikipedia</a>). De qualquer modo, sabemos que o <font face="monospace">srand()</font> irá garantir que os números &#8220;aleatórios&#8221; tenham esse comportamento o mais próximo possível da realidade.<br />Na linha seguinte, utilizamos <font face="monospace">rand()</font> para obter um número aleatório. Porém, esse comando não nos permite definir qual o valor máximo a ser obtido, normalmente obtendo qualquer valor entre 0 e uma definição chamada <font face="monospace">RAND_MAX </font>(normalmente o limite de um <font face="monospace">unsigned int</font>). A opção padrão é obter o resto da divisão inteira entre o maior número que desejamos e o valor retornado. Nesse caso, obtemos um número que vai de 0 ao limite estipulado menos 1. No nosso caso, queremos um número entre 1 e o <font face="monospace">LIMITE</font> estipulado, por isso adicionamos 1 ao valor obtido (lembre-se da prioridade de execução da operação de resto em relação à soma).<br />Bem, acho que já falamos demais sobre <font face="monospace">rand()</font>, até porque não tem como aprofundar nesse caso sem entrar uma teoria extremamente complexa e totalmente fora do nosso escopo atual (e muito provavelmente futuro). Tudo que é preciso saber é que precisaos usar <font face="monospace">srand() </font>antes de <font face="monospace">rand()</font> para garantir o comportamento aleatório e que precisamos utilizar a operação resto para &#8220;limitar&#8221; o valor de <font face="monospace">rand()</font>.</p>
<h3>Laço de repetição condicional &#8211; <font face="monospace">do {&#8230;} while</font> e operações relacionais e lógicas:<br /></h3>
<p>Em seguida, vemos que ele irá apresentar o desafio ao usuário e entrará no bloco de código abaixo:</p>
<blockquote><p><font color="#339999"><b><font face="monospace">&nbsp; do</font></b></font><br /><font color="#339999"><b><font face="monospace">&nbsp;&nbsp;&nbsp; {</font></b></font><br /><font color="#339999"><font color="#333333"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Quantas tentativas você acha que precisa para descobrir ele? &#8220;);</font></b></font></font><br /><font color="#339999"><font color="#333333"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;maximoTentativas);</font></b></font></font></p>
<p><font color="#339999"><font color="#333333"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (maximoTentativas&lt;1)</font></b></font></font><br /><font color="#339999"><font color="#333333"><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; printf(&#8220;Você precisa tentar ao menos uma vez! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> \n&#8221;);</font></b></font></font><br /><font color="#339999"><font color="#333333"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (maximoTentativas&gt;limiteTentativas)</font></b></font></font><br /><font color="#339999"><font color="#333333"><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; printf(&#8220;%d tentativas? Tá querendo demais também! <img src='https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> \n&#8221;,maximoTentativas);</font></b></font></font><br /><font color="#339999"><b><font face="monospace">&nbsp;&nbsp;&nbsp; } while (maximoTentativas&lt;1 || maximoTentativas&gt;limiteTentativas);</font></b></font></p>
</blockquote>
<p>No nosso caso, nos focaremos nos comandos em ciano. Eles representam um tipo de controle de fluxo que chamamos de <i>repetição (ou iteração, em alguns lugares) condicional</i>. O nome pomposo apenas quer dizer que o laço em questão vai ser executado enquanto uma determinada condição for cumprida. No nosso caso, esse comando funciona assim:</p>
<blockquote><p><font color="#339999"><b><font face="monospace">&nbsp; do</font></b></font><br /><font color="#339999"><b><font face="monospace">&nbsp;&nbsp;&nbsp; {</font></b></font><br /><font color="#339999">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8230;&gt;</font><br /><font color="#339999"><font color="#333333"><b><font face="monospace"></font></b></font><b><font face="monospace">&nbsp;&nbsp;&nbsp; } while (&lt;condicao&gt;);</font></b></font></p>
</blockquote>
</div>
<p>O que fazemos aqui é indicar que, enquanto a <font face="monospace">condicao</font> estipulada for verdadeira, o programa continuará no laço.</p>
<div align="justify">Mas como construir uma condição lógica? Para isso, C nos fornece os <i>operadores lógicos</i>, que comparam valores e retornam &#8220;verdadeiro&#8221; ou &#8220;falso&#8221; conforme a situação.<br />Aqui cabe um parenteses antes de entrarmos nos operadores: o C <i>não possui um tipo booleano</i> (ou seja, verdadeiro ou falso) <i>específico</i>. Para o C, um valor <font face="monospace">0</font>, <font face="monospace">NULL</font> (que é definido por padrão como <font face="monospace">0</font>) ou <font face="monospace">&#8220;&#8221;</font> (<i>string</i> vazia) como <i>falso</i> e qualquer outro valor como <i>verdadeiro</i>. Isso é importante pois existe um <i>bug</i> em C muito comum que iremos discutir adiante.<br />Bem, dito isso, os operadores lógicos em C padrão são:&nbsp; </p>
<table border="1">
<tbody>
<tr>
<td align="CENTER"><b><font size="+1">Operador&nbsp;</font></b>&nbsp; <br /><font face="monospace">&gt;&nbsp; <br />&gt;=&nbsp; <br />&lt;&nbsp; <br />&lt;=&nbsp; <br />==&nbsp; <br />!= <br />&amp;&amp;<br />||<br />!</font></td>
<td><b><font size="+1">Ação&nbsp;</font></b>&nbsp; <br />    Maior do que <br />    Maior ou igual a <br />Menor do que&nbsp; <br />Menor ou igual a&nbsp; <br />Igual a&nbsp; <br />Diferente de<br />E lógico<br />OU lógico<br />NÃO lógico</td>
</tr>
</tbody>
</table>
<p>(fonte: <a target="_blank" href="http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c360.html">curso de C da UFMG</a>)<br />Os operadores lógicos são escritos de maneira similar aos matemáticos, sempre comparando um valor a outro. No caso, por exemplo, do comando acima, temos três expressões:</p>
<ul>
<li>primeiro, uma comparação <font color="#339999"><b><font face="monospace">maximoTentativas&lt;1</font></b></font>;</li>
<li>depois, uma comparação <font color="#339999"><b><font face="monospace">maximoTentativas&gt;limiteTentativas</font></b></font>;</li>
<li>e por fim, uma operação lógica ou entre os dois;</li>
</ul>
<p>Como isso é resolvido no C? Primeiro, o sistema irá analisar se o  <font color="#339999"><b><font face="monospace">maximoTentativas&lt;1</font></b></font>. Caso seja, ele nem irá fazer a segunda comparação <font color="#339999"><b><font face="monospace">maximoTentativas&gt;limiteTentativas</font></b></font>, pois o fato de a comparação lógica ser OU vai fazer o programa aceitar como verdadeira a condição e continuará no laço (chama-se a isso <i>short-circuit logical analysis</i> &#8211; análise lógica de curto-circuito, e parte do princípio que uma vez que tenhamos garantido que uma condição é sabidamente verdadeira ou falsa, não há necessidade de continuar-se processando a lógica em questão). Caso contrário, ele irá tentar a segunda comparação, <font color="#339999"><b><font face="monospace">maximoTentativas&gt;limiteTentativas</font></b></font>, para verificar se ela é verdadeira ou falsa e, portanto, a condição o será.<br />Parece meio confuso, mas é só pensar com calma que você irá entender. Procure imaginar valores para <font face="monospace">maximoTentativas</font> e pense em qual será a resposta (lembre-se: no caso atual, <font face="monospace">limiteTentativas</font> é 4).<br />O que acontecerá se o valor não fizer nenhuma das duas condições estipuladas ser verdadeira? Simples: a expressão como um todo será falsa (0) e o laço <font face="monospace">do&#8230;while</font> irá se encerrar normalmente, com o programa seguindo adiante. Ou seja, somente quanto o usuário entrar com um número máximo de tentativas maior que 1 e menor ou igual que o limite de tentativas estipulado (no caso, 4), o laço será interrompido.<br />Temos uns <font face="monospace">if</font>s engraçadinhos dentro desse laço, mas não falaremos sobre ele agora. Vamos então seguir em frente.<br />Para fecharmos esse tópico, existe uma versão do <font face="monospace">do&#8230;while</font> chamada simplesmente <font face="monospace">while</font>. Ela é representada assim:</p>
<blockquote><p><b><font face="monospace">while(&lt;condicao&gt;)</font><br /><font face="monospace">{</font><br /><font face="monospace">&nbsp;&nbsp;&nbsp; &lt;&#8230;&gt;</font><br /><font face="monospace">}</font></b></p>
</blockquote>
<p>e sua única diferença em relação ao seu &#8220;irmão&#8221; é que, caso <i>ao chegar na entrada do laço</i> a condição for satisfeita, o sistema sequer irá entrar no bloco de código em questão. O <font face="monospace">do&#8230;while</font> irá executar ao menos uma vez, uma vez que a condição é testada no momento da <i>saída do laço</i>, diferentemente do <font face="monospace">while</font>, que é executada quando da <i>entrada no laço</i>.</p>
<h3>Iterações &#8211; o comando <font face="monospace">for</font>:<br /></h3>
<p>Após nosso usuário ter determinado quantas tentativas ele quer ter para acertar o número mágico, vamos então dar a chance a ele.</p>
<blockquote><p><font color="#993399"><b><font face="monospace">&nbsp; for (i=1; i&lt;=maximoTentativas;i++)</font></b></font><br /><font color="#993399"><b><font face="monospace">&nbsp;&nbsp;&nbsp; {</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Vamos lá! %da. tentativa! &#8220;,i);</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf(&#8220;%d&#8221;,&amp;numeroDoUsuario);</font></b></p>
<p></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (numeroDoUsuario==numeroPensado)</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Parabéns! Você acertou!\n&#8221;);</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; ENCERRA</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return(0);</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; }</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; else</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; {</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; printf(&#8220;Não pensei em %d. &#8220;, numeroDoUsuario);</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; if (numeroDoUsuario&lt;numeroPensado)</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&#8220;Pensei em um número maior.\n&#8221;);</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; if (numeroDoUsuario&gt;numeroPensado)</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(&#8220;Pensei em um número menor.\n&#8221;);</font></b><br /></font><font color="#000000"><b><font face="monospace">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; }</font></b><br /></font><font color="#993399"><b><font face="monospace">&nbsp;&nbsp;&nbsp; }</font></b></font></p>
</blockquote>
<p>Aqui temos um número delimitado de tentativas por máximo de tentativas. Desse modo, podemos utilizar um outro comando de laço, o <font face="monospace">for</font>, que é um outro caso de <i>laço de repetição</i> ou <i>iteração</i>. Diferentemente do <font face="monospace">do&#8230;while</font>, porém, o <font face="monospace">for</font> é uma iteração <i>não-condicional</i>. Na verdade, ele é <i>condicional</i>, mas ele é mais usado em situações na qual se espera que ele se execute um determinado número de vezes (pode-se usar ele até como um <font face="monospace">while</font> diferente, mas não é boa prática e não falaremos sobre isso aqui).<br />O for tem como estrutura a seguinte:<br /><font color="#993399"><b><font face="monospace">&nbsp; for (&lt;inicializacao&gt;; &lt;condicao&gt;; &lt;iteracao&gt;)</font></b></font><br /><font color="#993399"><b><font face="monospace">&nbsp;&nbsp;&nbsp; {<br /></font></b></font><font color="#993399"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;&#8230;&gt;<br />&nbsp;&nbsp;&nbsp; }</font></b></font><br />No caso, ele é um pouquinho complexo, portanto vamos dar uma olhada no seu comportamento:</p>
<ul>
<li>no momento em que o programa chega no <font face="monospace">for</font>, a primeira coisa que é feita é executar os comandos em <font face="monospace">&lt;inicializacao&gt;</font>. No nosso caso, ele inicializa a variável <font face="monospace">i</font> em 1. Essa inicialização pode ser feita como desejado, mas restringindo-se a um comando (ou bloco de código);</li>
<li>Em seguida, o bloco de código do for será executado;</li>
<li>Ao terminar de executar-se o bloco de código do <font face="monospace">for</font>, ele executa o comando que está em <font face="monospace">&lt;iteracao&gt;</font>. No nosso caso, utilizamos um operador matemático <font face="monospace">++</font>, que é utilizado em C para adicionar-se um ao valor da variável ao qual ela sucede. Na verdade ele se comporta de uma maneira mais complexa, mas para o momento basta entender que <font face="monospace">i++</font> seria o equivalente a <font face="monospace">i=i+1</font>;</li>
<li>Depois de executar a <font face="monospace">&lt;iteracao&gt;</font>, o sistema irá verificar se a <font face="monospace">&lt;condicao&gt;</font> colocada é verdadeira. Caso o seja, ele irá interromper o laço <font face="monospace">for</font> da mesma forma que o <font face="monospace">while</font>, caso contrário ele entrará e executará uma nova iteração. No nosso caso, testamos se <font face="monospace">i</font> ainda é menor ou igual ao número de <font face="monospace">limiteTentativas</font>. Lembrando que C não possui tipo booleano e que basta que o valor seja <font face="monospace">0</font> ou <font face="monospace">&#8220;&#8221;</font> para ser considerado falso e, portanto, o laço <font face="monospace">for</font> seja interrompido;</li>
</ul>
<p>Bem, acho que isso deve ter deixado claro como o <font face="monospace">for </font>funciona. O primeiro <font face="monospace">printf</font> do programa deve deixar claro que você vai passando por várias iterações até acertar o &#8220;número mágico&#8221; &#8220;pensado&#8221; pelo nosso programa (o do <font face="monospace">rand()</font> do início do programa). Mas como o programa saberá quando fomos bem-sucedidos?<br />Para isso existe o nosso próximo comando.</p>
<h3>Execução condicional &#8211; o comando <font face="monospace">if</font>:<br /></h3>
<p>OK&#8230; Paramos falando sobre como o nosso programa saberá que fomos bem sucedido. Veja que temos um <font face="monospace">scanf</font> lendo o que o personagem entrou naquela tentativa. Precisamos de um comando para decidir fomos bem sucedidos ou não em acertar a descoberta do número &#8220;mágico&#8221;&nbsp; &#8220;pensado&#8221; pelo programa. Quem cuida disso é comando <font face="monospace">if</font> do bloco abaixo:</p>
<blockquote><p><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (numeroDoUsuario==numeroPensado)</font></b></font><br /><font color="#000000"><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></b></font></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Parabéns! Você acertou!\n&#8221;);</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; ENCERRA</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; return(0);</font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; }</font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp; &nbsp;&nbsp;&nbsp; else</font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp; &nbsp; &nbsp; {</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; printf(&#8220;Não pensei em %d. &#8220;, numeroDoUsuario);</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; if (numeroDoUsuario&lt;numeroPensado)</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; printf(&#8220;Pensei em um número maior.\n&#8221;);</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; if (numeroDoUsuario&gt;numeroPensado)</font></b></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; printf(&#8220;Pensei em um número menor.\n&#8221;);</font></b></font><br /><font color="#000000"><font color="#cc66cc"><b><font face="monospace">&nbsp; &nbsp; &nbsp; }</font></b></font></font></p>
</blockquote>
</div>
<p>O <font face="monospace">if</font> é uma estrutura importante de programação, pois ele executa blocos de código caso a condição determinada seja verdadeira:</p>
<blockquote><p><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (&lt;condicao&gt;)</font></b></font><br /><font color="#000000"><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></b></font></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;&#8230;&gt;</font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; }</font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp; &nbsp;&nbsp;&nbsp; else if (&lt;outra_condicao&gt;)</font></b></font><br /><font color="#000000"><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</font></b></font></font><br /><font color="#000000"><b><font face="monospace">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &lt;&#8230;&gt;</font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp;&nbsp; &nbsp;&nbsp; }</font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp; &nbsp;&nbsp;&nbsp; else </font></b></font><br /><font color="#cc66cc"><b><font face="monospace">&nbsp; &nbsp; &nbsp; {</font></b></font><br /><font color="#000000"><b><font face="monospace"><font color="#cc66cc">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font color="#000000">&lt;&#8230;&gt;</font><br /></font></font></b></font><font color="#000000"><font color="#cc66cc"><b><font face="monospace">&nbsp; &nbsp; &nbsp; }</font></b></font></font></p>
</blockquote>
<p>O <font face="monospace">if</font> irá executar o bloco de código abaixo da instrução caso <font face="monospace">condicao</font> seja verdadeira. Caso contrário ele pode:</p>
<ol>
<li>Testar outras condições. Para isso, utiliza-se <font face="monospace">else if</font>, com uma nova condição e um bloco de código adequado;</li>
<li>Executar um código para exceção. Para isso, utiliza-se <font face="monospace">else</font> e o bloco de código adequado;</li>
<li>Não fazer nada;</li>
</ol>
<div align="justify">Agora, vamos tentar ler esse trecho de código. A primeira coisa que ele testa é se <font color="#cc66cc"><b><font face="monospace">numeroDoUsuario==numeroPensado</font></b></font>, ou seja, se o número que o usuário entrou é igual ao número &#8220;pensado&#8221; pelo sistema. Caso seja, ele indica que foi bem sucedido e encerra o mesmo (perceba que temos um <font face="monospace">return(0)</font> dentro do <font face="monospace">if</font>. Isso é permitido pelo C). Perceba que o operador de relação de igualdade é <font face="monospace">==</font>. NUNCA CONFUNDA COM O OPERADOR DE ATRIBUIÇÃO,<font face="monospace"> =</font>. Esse é um <i>bug</i> (falha de programação) muito comum que é provocado por falta de atenção na programação. No caso de colocar =, o valor de <font face="monospace">numeroDoUsuario</font> seria substituído pelo de numeroPensado. A não ser que <font face="monospace">numeroPensado</font> fosse <font face="monospace">0</font> (o que é impossível, devido à lógica do programa) o programa acusaria verdadeiro independentemente do valor realmente ser (lembre-se, qualquer valor diferente de <font face="monospace">0</font> ou <font face="monospace">&#8220;&#8221;</font> ou <font face="monospace">NULL</font> é considerado pelo C como verdadeiro em relações lógicas).<br />Bem, dito isso, vamos continuar a analisar nosso programa. Caso a condição acima não seja verdadeira, ele irá ignorar o bloco abaixo de <font face="monospace">if</font> e irá ver que temos um <font face="monospace">else</font> com um bloco de código. Ele então entrará nesse bloco de código. A primeira coisa que ele irá fazer é dizer que não pensou no <font color="#000000"><b><font face="monospace">numeroDoUsuario</font></b></font> e testar se <font color="#000000"><b><font face="monospace">numeroDoUsuario&lt;numeroPensado</font></b></font>. Caso seja verdadeiro, ele irá imprimir na tela uma mensagem dizendo que pensou em um número maior que o que o usuário entrou. Caso contrário, irá verificar se <font color="#000000"><b><font face="monospace">numeroDoUsuario&gt;numeroPensado</font></b></font>. Se verdadeiro (provavelmente será, se tudo mais deu errado), irá imprimir que pensou em um número menor que o que o usuário pensou. <br />Os <font face="monospace">if</font>s dessas linhas possuem uma característica interessante que é o fato de terem comandos diretamente abaixo deles, e não dentro de blocos de código. Na realidade isso deve-se ao fato que <font face="monospace">if</font>, <font face="monospace">while</font>, <font face="monospace">for</font> e afins, todos eles possuem uma característica de executar na realidade <i>apenas um comando</i>. A diferença é que, para o compilador C, um <i>bloco de código</i> (lembre-se: blocos de código são comandos isolados pelos colchetes <font face="monospace">{}</font>) são considerados comandos isolados. Portanto, um <i>bloco de código</i> == um comando.<br />Lendo com calma o código você irá compreender muito bem o mesmo. Leia e releia o códigoo e faça exercícios mentais para entender o código do <font face="monospace">if</font>.</p>
<h3>Quando tudo dá errado &#8211; considerações:<br /></h3>
<p>OK&#8230; Mas e caso o usuário não acerte mesmo depois de ter tentado o número de vezes que ele desejou (<font face="monospace">maximoTentativas</font>).<br />Isso ocorre quando a variável <font face="monospace">i</font>, após a iteração do <font face="monospace">for</font>, ficar com um valor maior que <font face="monospace">maximoTentativas</font>, tornando a condição&nbsp; <font color="#993399"><b><font face="monospace">i&lt;=maximoTentativas</font></b></font> falsa e saindo do laço <font face="monospace">for</font> (ao atingir o limite de iterações estipulado). Para encerrar o programa, nós fazemos o sistema imprimir uma mensagem dizendo qual o número no qual ele pensou e saindo do mesmo.<br />Antes de irmos para as &#8220;brincadeiras&#8221; finais, algumas considerações:</p>
<ul>
<li>Os operadores relacionais que mostramos anteriormente só servem para valores numéricos ou para o tipo <font face="monospace">char</font>. Em especial para <i>strings</i>, a biblioteca <font face="monospace">string.h</font> traz funções que nos permite testar igualdade entre textos. Veremos eles melhor no futuro;</li>
<li>Ainda não esgotamos o assunto controle de fluxo. Em especial falaremos ainda sobre um tipo de execução condicional para múltiplos valores e sobre como &#8220;quebrar&#8221; laços como o <font face="monospace">for</font> e o <font face="monospace">while</font>;</li>
<li>É possível aninhar <font face="monospace">if</font>s ccom múltiplos <font face="monospace">else if</font> e afins. Porém, tome cuidado ao usá-los: além de tornar o código de difícil leitura, você pode ter problemas dependendo do compilador (normalmente o C exige no mínimo 8 &#8220;níveis&#8221; de <font face="monospace">if</font>s aninhados, mas esse valor não é obrigatório);</li>
</ul>
<p>Bem, dito isso, vamos fazer algumas sugestões para &#8220;brincadeiras&#8221; com o nosso código:</p>
<ul>
<li>Comente ou remova o <font face="monospace">srand()</font> e veja o comportamento do gerador de números pseudo-aleatórios;</li>
<li>Tente reescrever o código para tornar maximoTentativas uma constante. Lembre-se que não é necessário inicializar o valor imediatamente, podendo ser inicializado em um momento futuro;</li>
<li>No caso de quando o usuário erra o número &#8220;pensado&#8221;, você pode ter percebido que os dois <font face="monospace">if</font>s são redundantes. Tente reescrever o código usando apenas um <font face="monospace">if</font>;</li>
<li>Da mesma forma que existe o operador <font face="monospace">++</font>, existe o operador <font face="monospace">&#8211;</font>, que subtrai um da variável que o antecede. Considerando isso e o funcionamento do laço <font face="monospace">for</font>, tente reconstruir o laço para não ter uma condição no sentido exato da palavra. Dica: lembre-se que C trata <font face="monospace">0</font> como falso;</li>
<li>Para ter uma idéia do problema que pode ocorrer quando se confunde o operador de igualdade com o de atribuição, modifique o código removendo um dos sinais de igual de <font color="#000000"><b><font face="monospace">if (numeroDoUsuario==numeroPensado)</font></b></font> e veja o que acontece com o programa. Para maior clareza, coloque um <font face="monospace">printf</font> que apresente o número &#8220;pensado&#8221; antes do usuário entrar o seu número e digite outro completamente diferente. Coloque também um <font face="monospace">printf</font> mostrando o <font face="monospace">numeroDoUsuario</font> após o <i>bug</i>;</li>
<li>Para entender a questão das definições, altere o valor de LIMITE e veja como o programa se comporta. Como dica, o cálculo do <font face="monospace">limiteTentativas</font> baseia-se na idéia de buscar-se o número sempre indo na metade do que é válido. Por exemplo: computador escolhe 6. Na primeira interação, tento 5, e ele me fala que pensou um maior. Tento 7 (metade do bloco &#8220;acima de cinco&#8221;) e ele me diz que pensou um menor. Tento 6 e acerto;</li>
</ul>
<p>Bem, semana que vem iremos reeforçar a teoria dos operadores (lista completa e exemplos) e daremos uma terminada na questão dos controles de fluxo. Até lá, divirtam-se!</p></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/aulasdec.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/aulasdec.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/aulasdec.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/aulasdec.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/aulasdec.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/aulasdec.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/aulasdec.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/aulasdec.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/aulasdec.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/aulasdec.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/aulasdec.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/aulasdec.wordpress.com/27/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/aulasdec.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/aulasdec.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=aulasdec.wordpress.com&amp;blog=17376722&amp;post=27&amp;subd=aulasdec&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>https://aulasdec.wordpress.com/2010/11/16/controle-de-fluxo-e-operandos-logicos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="https://secure.gravatar.com/avatar/7a9d92740b73d8a4a04d1a783880f5d4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">FabioCosta</media:title>
		</media:content>
	</item>
	</channel>
</rss>
