<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Plínio Ribeiro</title>
    <description>The latest articles on DEV Community by Plínio Ribeiro (@pliniohr).</description>
    <link>https://dev.to/pliniohr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F840787%2F85342e1c-de5e-442d-b1ad-f7b4d18a3f76.jpeg</url>
      <title>DEV Community: Plínio Ribeiro</title>
      <link>https://dev.to/pliniohr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pliniohr"/>
    <language>en</language>
    <item>
      <title>Threads na linguagem C</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Mon, 06 May 2024 12:12:10 +0000</pubDate>
      <link>https://dev.to/pliniohr/threads-na-linguagem-c-598k</link>
      <guid>https://dev.to/pliniohr/threads-na-linguagem-c-598k</guid>
      <description>&lt;h2&gt;
  
  
  O que são threads?
&lt;/h2&gt;

&lt;p&gt;Vamos aos ensinamentos do mestre Tanenbaum (2016) no seu livro Sistemas Operacionais Modernos que escreve que "&lt;em&gt;Um processo tem um espaço de endereçamento contendo o código e dados do programa, assim, como outros recursos&lt;/em&gt;". Em seguida, ele nos apresenta o conceito de &lt;em&gt;threads&lt;/em&gt;: "&lt;em&gt;um processo tem uma linha de execução (thread) de execução, normalmente abrevidado para apenas &lt;strong&gt;thread&lt;/strong&gt;. O thread tem um contador de programa que controla qual instrução deve ser executada em seguida&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;O autor pontua que "&lt;em&gt;Processos são usados para agrupar recursos; threads são as entidades escalonadas para execução na CPU&lt;/em&gt;". Por fim, complementando, "&lt;em&gt;os threads compartilham um espaço de endereçamento e outros recursos&lt;/em&gt;" e "&lt;em&gt;processos compartilham memórias físicas, discos, impressoras e outros recursos&lt;/em&gt;". &lt;/p&gt;

&lt;p&gt;Para este estudo estarei utilizando a Linguagem C e a biblioteca &lt;code&gt;POSIX threads&lt;/code&gt;. Que segundo a sua documentação (&lt;code&gt;man pthreads&lt;/code&gt;): &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;POSIX.1  specifies a set of interfaces (functions, header files) for threaded programming commonly known as POSIX threads, or Pthreads.  A single&lt;br&gt;
    process can contain multiple threads, all of which are executing the same program.  These threads share the same global  memory  (data  and  heap&lt;br&gt;
    segments), but each thread has its own stack (automatic variables).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para utilizar, adicionamos a flag &lt;code&gt;-pthread&lt;/code&gt; ao compilar os nossos códigos. &lt;/p&gt;

&lt;p&gt;Exemplo simples de uso de threads na linguagem C.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;pthread.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;thread_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;pthread_t&lt;/span&gt;     &lt;span class="n"&gt;thread1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;pthread&lt;/span&gt;       &lt;span class="n"&gt;thread2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt;           &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;pthread_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;thread1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread_function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;pthread_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;thread2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread_function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;pthread_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;pthread_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Threads finalizadas.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;thread_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt;       &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Thread ID: %ld, Número: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pthread_self&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;pthread_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicação das funções acima:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Função&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pthread_create&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cria uma nova thread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pthread_exit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Conclui uma chamada de thread&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pthread_join&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Espera que um thread específico seja abandonado&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Sincronização de threads
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Race Conditions
&lt;/h2&gt;

&lt;p&gt;Como vimos acima sobre &lt;code&gt;threads&lt;/code&gt;, que diferente de processos, &lt;code&gt;threads&lt;/code&gt; compartilham o mesmos recursos disponíveis para o processo a qual pertencem. Nesse cenário, pode acontecer comportamentos inesperados quando &lt;code&gt;threads&lt;/code&gt; acessam um mesmo recurso ao mesmo tempo ou mesma região da memória. &lt;/p&gt;

&lt;p&gt;A esses casos são denominados &lt;em&gt;race conditions&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Podemos dizer que está ocorrendo uma &lt;em&gt;race condition&lt;/em&gt; quando "&lt;em&gt;dois ou mais processos estão lendo ou escrevendo alguns dados compartilhados e o resultado final depende de quem executa precisamente e quando&lt;/em&gt;", Tanenbaum (2016).&lt;/p&gt;

&lt;p&gt;Coleciono também, o conceito presente em &lt;a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html"&gt;POSIX thread (pthread) libraries&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A contention or race condition often occurs when two or more threads need to perform operations on the same memory area, but the results of computations depends on the order in which these operations are performed. Mutexes are used for serializing shared resources such as memory. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vejamos o exemplo. O código abaixo, temos uma variável global &lt;code&gt;count&lt;/code&gt; que será incrementada &lt;code&gt;n&lt;/code&gt; vezes por 5 &lt;code&gt;threads&lt;/code&gt; "ao mesmo tempo".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;pthread.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;assert.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;volatile&lt;/span&gt; &lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pthread_t&lt;/span&gt;       &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;             &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;             &lt;span class="n"&gt;qtd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;qtd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; 
        &lt;span class="n"&gt;qtd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pthread_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;qtd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pthread_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Count: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;         &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;         &lt;span class="n"&gt;qtd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;qtd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;qtd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executando o código com valores mais altos podemos ver que os resultados não saem com esperado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ make race
gcc &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-Wextra&lt;/span&gt; &lt;span class="nt"&gt;-Werror&lt;/span&gt; &lt;span class="nt"&gt;-pthread&lt;/span&gt; race.c &lt;span class="nt"&gt;-o&lt;/span&gt; race 
❯ ./race
Count: 44599
❯ ./race 10
Count: 50
❯ ./race 100
Count: 500
❯ ./race 1000
Count: 5000
❯ ./race 10000
Count: 26448
❯ ./race 100000
Count: 150643
❯ ./race 1000000
Count: 1506256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aproveitar e colocar uma nota sobre o modificador &lt;code&gt;volatile&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Ele indica para o compilador que variável pode ser modificada por fatores externos, aplicando uma restrição às otimições realizadas pelo compilador. &lt;/p&gt;

&lt;h3&gt;
  
  
  ThreadSanitizer
&lt;/h3&gt;

&lt;p&gt;Uma ferramenta que pode nos ajudar é ThreadSanitizer.&lt;/p&gt;

&lt;p&gt;Para utilizarmos, compilarmos nosso código com flag &lt;code&gt;-fsanitize=thread&lt;/code&gt;. &lt;br&gt;
Ao executar, é disparado um aviso que está ocorrendo uma condição de corrida à variável &lt;code&gt;count&lt;/code&gt;. Vejamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ ./race
&lt;span class="o"&gt;==================&lt;/span&gt;
WARNING: ThreadSanitizer: data race &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;pid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;14464&lt;span class="o"&gt;)&lt;/span&gt;
  Read of size 4 at 0x56453e338014 by thread T2:
    &lt;span class="c"&gt;#0 increment &amp;lt;null&amp;gt; (race+0x141a)&lt;/span&gt;

  Previous write of size 4 at 0x56453e338014 by thread T1:
    &lt;span class="c"&gt;#0 increment &amp;lt;null&amp;gt; (race+0x1432)&lt;/span&gt;

  Location is global &lt;span class="s1"&gt;'count'&lt;/span&gt; of size 4 at 0x56453e338014 &lt;span class="o"&gt;(&lt;/span&gt;race+0x000000004014&lt;span class="o"&gt;)&lt;/span&gt;

  Thread T2 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;14467, running&lt;span class="o"&gt;)&lt;/span&gt; created by main thread at:
    &lt;span class="c"&gt;#0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605b8)&lt;/span&gt;
    &lt;span class="c"&gt;#1 main &amp;lt;null&amp;gt; (race+0x1333)&lt;/span&gt;

  Thread T1 &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;14466, finished&lt;span class="o"&gt;)&lt;/span&gt; created by main thread at:
    &lt;span class="c"&gt;#0 pthread_create ../../../../src/libsanitizer/tsan/tsan_interceptors_posix.cpp:969 (libtsan.so.0+0x605b8)&lt;/span&gt;
    &lt;span class="c"&gt;#1 main &amp;lt;null&amp;gt; (race+0x1333)&lt;/span&gt;

SUMMARY: ThreadSanitizer: data race &lt;span class="o"&gt;(&lt;/span&gt;/mnt/c/Users/win11/lab/conpar/yolinux/race+0x141a&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;increment
&lt;span class="o"&gt;==================&lt;/span&gt;
Count: 27076
ThreadSanitizer: reported 1 warnings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por mais informações, veja: &lt;a href="https://www.cs.columbia.edu/%7Ejunfeng/11fa-e6121/papers/thread-sanitizer.pdf"&gt;https://www.cs.columbia.edu/~junfeng/11fa-e6121/papers/thread-sanitizer.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Diante desse cenários que temos a &lt;strong&gt;sincronização de *threads&lt;/strong&gt;*. &lt;/p&gt;

&lt;h2&gt;
  
  
  Mecanismos para lidar com sincronização de threads
&lt;/h2&gt;

&lt;p&gt;A biblioteca &lt;code&gt;POSIX threads&lt;/code&gt; fornece três mecanismo para lidar com sincronização de threads. São: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mecanismo&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mutexes (Mutual exclusion lock)&lt;/td&gt;
&lt;td&gt;Bloqueia o acesso a determinada variável/recurso para outros threads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Joins&lt;/td&gt;
&lt;td&gt;Faz com que um &lt;code&gt;thread&lt;/code&gt; aguarde que outras estejam terminadas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variáveis de condição&lt;/td&gt;
&lt;td&gt;Utiliza o tipo &lt;code&gt;pthread_cond_t&lt;/code&gt; para controlar o acesso a determinada variável/recurso&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Mutexes
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Mutexes&lt;/em&gt; são utilizados para evitar comportamentos inesperados ou inconsistências com os dados durante operações de vários &lt;code&gt;threads&lt;/code&gt;na mesma área de memória ou recurso. É uma forma de prevenir &lt;em&gt;race conditions&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;O seu uso se dá por meio de uma variável do tipo &lt;code&gt;pthread_mutex_t&lt;/code&gt;. Quando um &lt;code&gt;thread&lt;/code&gt; tentar acessar uma área de memória, primeiro ela tentar bloquear a variável &lt;em&gt;mutex&lt;/em&gt;; caso consiga: realiza sua ação; caso contrário: aguarda até que a &lt;em&gt;mutex&lt;/em&gt; esteja liberada para uso.&lt;/p&gt;

&lt;p&gt;Mais um vez, trago aqui os ensinamentos do mestre Tanenbaum (2016):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Um &lt;strong&gt;mutex&lt;/strong&gt; é uma variável compartilhada que pode estar em um de dois estados: destravado ou travado. Em consequência, apenas 1 bit é necessário para representá-lo, mas na prática muitas vezes um inteiro é usado, com 0 significando destravado e todos os outros valores significando travado. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vamos utilizar o mesmo código acima e o modificar para implementar &lt;em&gt;mutexes&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Logo após as importações da bibliotecas &lt;/span&gt;
&lt;span class="n"&gt;pthread_mutex_t&lt;/span&gt; &lt;span class="n"&gt;mutex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PTHREAD_MUTEX_INITIALIZER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// [...]&lt;/span&gt;

&lt;span class="c1"&gt;// Na função increment modificamos &lt;/span&gt;
    &lt;span class="n"&gt;pthread_mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;qtd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pthread_mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compilamos e executamos. Como se poder, a versão com &lt;em&gt;mutexes&lt;/em&gt; comportou conforme esperado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ ./race 100000
Count: 159154
❯ ./race_mutexes 100000
Count: 500000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicando: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Função / tipo&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PTHREAD_MUTEX_INITIALIZER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Macro utilizado para inicializar uma &lt;em&gt;mutex&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pthread_mutex_lock()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Aqui está adquirindo o &lt;em&gt;lock&lt;/em&gt; de uma variável &lt;em&gt;mutex&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pthread_mutex_unlock(&amp;amp;mutex)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Desbloqueia o &lt;em&gt;lock&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Join
&lt;/h3&gt;

&lt;p&gt;Utilizamos o mecanismo &lt;em&gt;join&lt;/em&gt; quando desejamos aguardar que um thread seja finalizado antes de continuar com a execução do código. É semelhante às chamadas das funções &lt;code&gt;wait&lt;/code&gt; e &lt;code&gt;waitpid&lt;/code&gt; no contexto de processos. &lt;/p&gt;

&lt;p&gt;Para isso fazemos uso da função &lt;code&gt;pthread_join&lt;/code&gt;, que atua quando "&lt;em&gt;um thread precisa esperar outro terminar seu trabalho e sair antes de continuar. O que esperando chamada &lt;code&gt;pthread_join&lt;/code&gt; para esperar outro thread específico terminar&lt;/em&gt;" Tanenbaum (2016);&lt;/p&gt;

&lt;p&gt;Indicamos qual thread é para aguardar passando como primeiro argumento da função. O segundo argumento da função é informado quando queremos recuperar algum valor retornado pelo thread. Esse argumento é facultativo, caso não se tenha valor para recuperar, passamos &lt;code&gt;NULL&lt;/code&gt; como argumento. &lt;/p&gt;

&lt;p&gt;É assinatura da função&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;pthread_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pthread_t&lt;/span&gt; &lt;span class="kr"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;retval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vejamos um exemplo o uso de &lt;em&gt;join&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;pthread.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define NTHREADS 10
&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;thread_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pthread_mutex_t&lt;/span&gt;     &lt;span class="n"&gt;mutex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PTHREAD_MUTEX_INITIALIZER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;                 &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pthread_t&lt;/span&gt;   &lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;NTHREADS&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;         &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;NTHREADS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pthread_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thread_function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;NTHREADS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pthread_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Counter: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;thread_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Thread number: %ld&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pthread_self&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;pthread_mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pthread_mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, inicializamos 10 threads, que chamam a função &lt;code&gt;thread_function&lt;/code&gt;, que por sua vez, incrementa o valor de &lt;code&gt;counter&lt;/code&gt;, e depois aguardamos o encerramento de cada uma dos threads inicializados para depois continuar com o fluxo de execução do código. &lt;/p&gt;

&lt;p&gt;Observa que aqui também utilizamos &lt;em&gt;mutexes&lt;/em&gt; para controlar as alterações da variável &lt;code&gt;counter&lt;/code&gt;, e assim evitar que o programa se comporte de forma inesperada: seja deixando de fazer uma incrementação, seja incrementando a mais. Bem, que nesse caso, como a quantidade de incrementações é pífia a chance de ocorrer uma condição de corrida é baixa. &lt;/p&gt;

&lt;p&gt;Uma explicação à chamada da função &lt;code&gt;pthread_self()&lt;/code&gt;: ela retorna o ID da thread chamada, é mesmo valor que retornado por uma chamada &lt;code&gt;pthread_create(3)&lt;/code&gt; quando criamos um thread. &lt;/p&gt;

&lt;h3&gt;
  
  
  Variáveis de Condição
&lt;/h3&gt;

&lt;p&gt;Variáveis de condição são variáveis que suspende a execução do thread até que determinada condição seja atendida. Segundo Tanenbaum (2016), "&lt;em&gt;variáveis de condição permitem que threads sejam bloqueados devido a alguma condição não estar sendo atendida&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;Deve-se atentar, que quando estamos lidando com variável de condição, sempre devemos associar ela com um mutex, o qual será responsável por bloquear a região crítica. &lt;/p&gt;

&lt;p&gt;Acrescentando, segundo o OSTEP: a "&lt;em&gt;condition variable is an explicit queue that threads can put themselves on when some state of execution (i.e., some condition) is not as desired (by waiting on the condition); some other thread, when it changes said state, can then wake one (or more) of those waiting threads and thus allow them to continue (by signaling on the condition)&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;Abaixo temos o código que utiliza variável de condição e mutex. Fazemos uso de dois threads. A execução varia entre a execução de cada thread, cada execução realiza uma atividade de incremento da variável &lt;code&gt;count&lt;/code&gt;. Utilizamos a variável de condição para controlar a execução dos threads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;pthread.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;pthread_mutex_t&lt;/span&gt; &lt;span class="n"&gt;count_mutex&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PTHREAD_MUTEX_INITIALIZER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;pthread_cond_t&lt;/span&gt;  &lt;span class="n"&gt;condition_var&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PTHREAD_COND_INITIALIZER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cp"&gt;#define     COUNT_DONE      10
#define     COUNT_HALT1     3
#define     COUNT_HALT2     6
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;fcount1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;fcount2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;volatile&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pthread_t&lt;/span&gt;       &lt;span class="n"&gt;th1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pthread_t&lt;/span&gt;       &lt;span class="n"&gt;th2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pthread_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;th1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fcount1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;pthread_create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;th2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fcount2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;pthread_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;th1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;pthread_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;th2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Final count: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;fcount1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pthread_mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count_mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pthread_cond_wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;condition_var&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count_mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[fcount1] value: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pthread_mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count_mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;COUNT_DONE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pthread_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;fcount2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;pthread_mutex_lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count_mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;COUNT_HALT1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;COUNT_HALT2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pthread_cond_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;condition_var&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; 
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[fcount2] value: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;pthread_mutex_unlock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;count_mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;to_increment&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;COUNT_DONE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pthread_exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicando as funções acima uti&lt;/p&gt;

&lt;p&gt;O macro &lt;code&gt;PTHREAD_COND_INITIALIZER&lt;/code&gt;: &lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;pthread_cond_wait&lt;/code&gt;: &lt;br&gt;
&lt;a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_cond_wait"&gt;http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_cond_wait&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;pthread_cond_signal&lt;/code&gt; &lt;br&gt;
&lt;a href="http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_cond_signal"&gt;http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_cond_signal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma observação quanto ao uso de &lt;code&gt;while&lt;/code&gt; e porque não podemos utilizar &lt;code&gt;if&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Semáforos
&lt;/h2&gt;

&lt;p&gt;Outro mecanismo para controle de threads, são os semáforos. Bem o que são? &lt;/p&gt;

&lt;p&gt;Desenvolvidos pelo cara, o E. W. Dijkstra, é a utilização de uma variável inteira para contar o número de sinais de acordar salvos para uso futuro, assim ensina o Tanenbaum (2016).&lt;/p&gt;

&lt;p&gt;Realizamos duas operações básicas sobre semáforos: incrementar ou decrementar. &lt;br&gt;
Quando desejamos sinalizar que operações estão disponíveis para serem realizar, incrementamos o valor do semáforo. &lt;br&gt;
E a cada vez que um operação é realizada, o decrementamos até chegar o valor de zero. &lt;br&gt;
O ato de decrementar o semáforo dever ser realizado antes de realizar alguma atividade. Funciona como uma verificação de disponibilidade. &lt;/p&gt;

&lt;p&gt;Se após, o valor for superior a (-1), o thread segue o fluxo de execução, caso contrário, ela vai dormir até ser acordado novamente para uma nova tentativa. &lt;/p&gt;

&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Tanenbaum, Andrew S. Sistemas operacionais modernos / Andrew S. Tanenbaum, Herbert Bos; tradução Jorge Ritter; revisão técnica Raphael Y. de Camargo. –  4. ed. – São Paulo: Pearson Education do Brasil, 2016&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fidelissauro.dev/concorrencia-paralelismo/"&gt;https://fidelissauro.dev/concorrencia-paralelismo/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html"&gt;http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/wdalmorra/Problema-Produtor-Consumidor/tree/master"&gt;https://github.com/wdalmorra/Problema-Produtor-Consumidor/tree/master&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://hpc-tutorials.llnl.gov/posix/"&gt;https://hpc-tutorials.llnl.gov/posix/&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.inf.ufpr.br/maziero/lib/exe/fetch.php?media=socm:socm-12.pdf"&gt;https://wiki.inf.ufpr.br/maziero/lib/exe/fetch.php?media=socm:socm-12.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pages.cs.wisc.edu/%7Eremzi/OSTEP/threads-cv.pdf"&gt;https://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cs.columbia.edu/%7Ejunfeng/11fa-e6121/papers/thread-sanitizer.pdf"&gt;https://www.cs.columbia.edu/~junfeng/11fa-e6121/papers/thread-sanitizer.pdf&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://pt.stackoverflow.com/questions/10175/para-que-serve-o-modificador-volatile-do-c-c"&gt;https://pt.stackoverflow.com/questions/10175/para-que-serve-o-modificador-volatile-do-c-c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://embarcados.com.br/modificadores-de-acesso-na-linguagem-c/"&gt;https://embarcados.com.br/modificadores-de-acesso-na-linguagem-c/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Notas de Estudos sobre processos Linux</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Wed, 20 Mar 2024 15:53:59 +0000</pubDate>
      <link>https://dev.to/pliniohr/notas-de-estudos-sobre-processos-linux-3kfm</link>
      <guid>https://dev.to/pliniohr/notas-de-estudos-sobre-processos-linux-3kfm</guid>
      <description>&lt;h1&gt;
  
  
  Processos Linux
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1.1 Conceitos básicos de processos Linux
&lt;/h2&gt;

&lt;p&gt;O que é um processo? Respondendo diretamente: um processo é um binário em execução. O qual pode ser dito, em outras palavras, é uma abstração de um software em execução. Segundo Tanenbaum (2016, p. 60), "&lt;em&gt;Um processo é apenas uma instância de um programa em execução, incluindo os valores atuais do contador do programa, registradores e variáveis&lt;/em&gt;". &lt;/p&gt;

&lt;p&gt;De forma simples, um processo é um programa em execução. Em outras palavras, é um programa ativo, realizando suas atividades pelo qual foi desenvolvido, é um software em execução, em atividade.&lt;/p&gt;

&lt;p&gt;Cada processo tem um ID, que é atribuido pelo sistema operacional, cujo valor máximo em sistemas Linux é 32768. &lt;br&gt;
Para vermos o ID dos processos em execução, podemos utilizar a ferramenta &lt;code&gt;ps&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ps
  PID TTY          TIME CMD
 1479 pts/3    00:00:01 zsh
 1483 pts/3    00:00:00 zsh
 1491 pts/3    00:00:00 zsh
 1493 pts/3    00:00:00 zsh
 1494 pts/3    00:00:00 gitstatusd-linu
 3816 pts/3    00:00:00 ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando estamos programando na linguagem C, um ID de um processo é representado pelo tipo &lt;code&gt;pid_t&lt;/code&gt;. O qual é definido no cabeçalho &lt;code&gt;&amp;lt;sys/types.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.1.1 Criação de processos
&lt;/h3&gt;

&lt;p&gt;Tanenbaum (2016, p. 61), aponta quatro eventos principais em que os processos são criados:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inicialização do sistema.&lt;/li&gt;
&lt;li&gt;Execução de uma chamada de sistema de criação de processo por um processo em execução.&lt;/li&gt;
&lt;li&gt;Solicitação de um usuário para criar um novo processo.&lt;/li&gt;
&lt;li&gt;Início de uma tarefa em lote.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Em termos de código, para se criar um processo em ambiente Linux, fazemos uma chamada ao kernel, por meio da &lt;em&gt;syscall&lt;/em&gt; &lt;code&gt;fork()&lt;/code&gt; que criará um clone do processo que a chamou. Em seguida, é chamada uma das funções da família &lt;code&gt;exec()&lt;/code&gt; que substitui a imagem do processo atual pela imagem do novo processo.  &lt;/p&gt;

&lt;p&gt;Também, podemos utilizar a função &lt;code&gt;system()&lt;/code&gt;. Essa forma é mais direta e simples, porém não muito eficiente, pois faz uma chamada para o shell &lt;code&gt;sh -c&lt;/code&gt; antes de iniciar o novo processo com o programa desejado. &lt;/p&gt;

&lt;p&gt;O processo que deu origem ao novo processo é chamado de &lt;strong&gt;processo pai&lt;/strong&gt; e o novo processo é chamado de &lt;strong&gt;processo filho&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1.2 Término de processos
&lt;/h3&gt;

&lt;p&gt;Um processo poderá terminar de forma voluntária ou involuntária. Ensina Tanenbaum (2016, p. 63) as quatras formas que um processo poderá terminar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Saída normal (voluntária): encerra a execução após realizar o seu trabalho;&lt;/li&gt;
&lt;li&gt;Erro fatal (involuntário): ocorre quando o processo tenta acessar um recurso não disponível;&lt;/li&gt;
&lt;li&gt;Saída por erro (voluntária): ocorre um erro na execução do programa, a exemplo, dividir por zero;&lt;/li&gt;
&lt;li&gt;Morto por outro processo (involuntário): outro processo pede ao sistema operacional interromper a execução de outro processo. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1.1.3 Estados do processo
&lt;/h3&gt;

&lt;p&gt;Um processo em execução pode se encontrar em um dos três estados: em execução, pronto e bloqueado. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Em execução: o processo está executando suas instruções; &lt;/li&gt;
&lt;li&gt;Pronto: o processo está pronto para ser executado, aguardando a decisão do sistema operacional de o colocar em execução;&lt;/li&gt;
&lt;li&gt;Bloqueado: está à espera de um evento para que seja possível continuar a sua execução. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Anota-se que todos os estados de um processo são determinados pelo sistema operacional, por meio do escalonador de processos. &lt;/p&gt;

&lt;h3&gt;
  
  
  1.1.4 Exemplos de código
&lt;/h3&gt;

&lt;p&gt;Neste tópico, será destinado para exemplos de códigos utilizando a API do Linux para manusear processos. &lt;/p&gt;

&lt;h4&gt;
  
  
  Função fork()
&lt;/h4&gt;

&lt;p&gt;No primeiro exemplo, vamos criar um processo com a utilização da função &lt;code&gt;fork()&lt;/code&gt; para criar um processo filho.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;fork()&lt;/code&gt; cria um clone do processo pai, compartilhando mesmo trecho de código e recursos do processo criador. &lt;/p&gt;

&lt;p&gt;É a assinatura da função.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta função retorna o seguinte: &lt;br&gt;
Em caso de sucesso, retornar o PID do processo filho para o pai, e &lt;code&gt;0&lt;/code&gt; para o processo criado. Em caso de falha, &lt;code&gt;-1&lt;/code&gt; é retornado. &lt;/p&gt;

&lt;p&gt;Outro detalhe, o processo filho inicia a sua execução a partir do &lt;code&gt;fork()&lt;/code&gt;. O processo filho não inicia a sua execução a partir da função &lt;code&gt;main&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;No exemplo seguinte, o processo pai declara a variável &lt;code&gt;x&lt;/code&gt;, a assinala um valor para ela. Posteriormente, faz uma chamada para a criação de novo processo, e, respectivamente, cada um alterar o valor da variável e o imprimi na tela.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;assert.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt;   &lt;span class="n"&gt;cpid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Initial x value: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;cpid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Child x value: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Parent x value: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo seguinte, temos um caso onde os processos pai e filho compartilham o mesmo &lt;em&gt;file descritor&lt;/em&gt;, escrevendo no mesmo arquivo, o qual foi aberto pelo pai.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;assert.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt;   &lt;span class="n"&gt;cpid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"out.txt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_CREAT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_WRONLY&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_TRUNC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;S_IRWXU&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao abrir o arquivo"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;cpid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Fork error&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;dprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Child writed!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;dprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Parent writed!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Funções wait() e waitpid()
&lt;/h4&gt;

&lt;p&gt;Vemos no primeiro exemplo acima, que o processo pai imprimi o valor de &lt;code&gt;x&lt;/code&gt; antes do filho. E caso for necessário, que o processo criador aguardasse a execução de um ou mais processos filhos. &lt;/p&gt;

&lt;p&gt;Para esses casos, temos as funções &lt;code&gt;wait()&lt;/code&gt; e &lt;code&gt;waitpid()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;São as suas assinaturas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/wait.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;wstatus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="nf"&gt;waitpid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid_t&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;wstatus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Segundo ensinam STEVENS, W. Richard e RAGO, Stephen (2013), quando um processo termina, seja normalmente e não, o kernel informa o processo pai enviando o sinal (SIGCHLD). O envio desse sinal é assíncrono, o que pode ocorrer com o processo pai em execução ou não. O processo criador pode escolher entre ignorar o sinal, via de regra, ou executar alguma outra ação. &lt;/p&gt;

&lt;p&gt;Há outros sinais que podem ser enviados, mas, por ora, se atermos ao SIGCHLD. &lt;br&gt;
Como o envio do sinal é assíncrono, temos situação em que devemos suspender a execução do processo pai, enquanto aguardamos o término de um ou mais processos filhos. &lt;/p&gt;

&lt;p&gt;Nesse cenário, que entram em cena as funções &lt;code&gt;wait()&lt;/code&gt; e &lt;code&gt;waitpid()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sendo direto, o MAN relata que as funções esperam por uma mudança de &lt;em&gt;status&lt;/em&gt; no processo. Uma explicação que gostei é do Prof. Eduardo Zambon: &lt;br&gt;
"&lt;em&gt;A chamada wait() é usada para esperar por mudanças de estado nos filhos do processo chamador (pai) e obter informações sobre aqueles filhos cujos estados tenham sido alterados (ex: morte de um filho). Quando o pai executa o wait(), se o filho já teve o seu estado alterado (ex: já morreu) no momento da chamada, ela retorna imediatamente; caso contrário, o processo chamador é bloqueado até que ocorra uma mudança de estado do filho ou então um “signal handler” interrompa a chamada (isso será explicado mais adiante)&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Essas funções retornam o PID do processo encerrado ou &lt;code&gt;-1&lt;/code&gt; no caso de erro. &lt;/p&gt;

&lt;p&gt;fonte: &lt;a href="http://www.inf.ufes.br/%7Ergomes/so_fichiers/roteiro2.pdf"&gt;http://www.inf.ufes.br/~rgomes/so_fichiers/roteiro2.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vejamos um exemplo de uso da função &lt;code&gt;wait()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/wait.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt;   &lt;span class="n"&gt;cpid1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt;   &lt;span class="n"&gt;cpid2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;cpid1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processo filho um&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;cpid2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processo filho dois&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processo pai&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observa-se que passamos o endereço de uma variável na chamada da função &lt;code&gt;wait()&lt;/code&gt;. Por meio dela, o processo pai receberá informações a respeito do processo filho. No qual se dá por meio de &lt;em&gt;flags&lt;/em&gt; binárias, as quais são lidas por meio de macros específicos. &lt;/p&gt;

&lt;p&gt;Mais um vez, coleciono as anotações do Prof. Eduardo Zambon: &lt;/p&gt;

&lt;p&gt;O POSIX expecifica seis macros, projetadas para operarem em pares:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WIFEXITED(status): permite determinar se o processo filho terminou normalmente. Se WIFEXITED avalia um valor não zero, o filho terminou normalmente. Neste caso, WEXITSTATUS avalia os 8-bits de menor ordem retornados pelo filho através de _exit(), exit() ou return de main.&lt;/li&gt;
&lt;li&gt;WEXITSTATUS(status): retorna o código de saída do processo filho.&lt;/li&gt;
&lt;li&gt;WIFSIGNALED(status): permite determinar se o processo filho terminou devido a um
sinal.&lt;/li&gt;
&lt;li&gt;WTERMSIG(status): permite obter o número do sinal que provocou a finalização do
processo filho.&lt;/li&gt;
&lt;li&gt;WIFSTOPPED(status): permite determinar se o processo filho que provocou o retorno se encontra congelado/suspenso (stopped).&lt;/li&gt;
&lt;li&gt;WSTOPSIG(status): permite obter o número do sinal que provocou o congelamento do processo filho. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vejamos um exemplo com uso de verificação do retorno da chamada da função &lt;code&gt;wait()&lt;/code&gt; e do valor do &lt;em&gt;status&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/wait.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt;   &lt;span class="n"&gt;cpid1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;pid_t&lt;/span&gt;   &lt;span class="n"&gt;r_wait&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;cpid1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_FAILURE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processo filho - PID: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;r_wait&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Valor de retorno da chamada wait: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r_wait&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WIFEXITED&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processo filho um retornou o código: %d.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WEXITSTATUS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outra função é a &lt;code&gt;waitpid()&lt;/code&gt;, a qual, diferente da sua irmã, ela permite que definamos o PID de um processo específico que estamos aguardando o seu encerramento. &lt;/p&gt;

&lt;p&gt;Exemplo com &lt;code&gt;waitpid()&lt;/code&gt;, no qual trocamos a parte final do código acima pelo seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;  &lt;span class="n"&gt;waitpid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processo filho um terminou&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;waitpid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cpid2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processo filho dois terminou&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Diferenças entre &lt;code&gt;wait()&lt;/code&gt; e &lt;code&gt;waitpid&lt;/code&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;As funções &lt;code&gt;wait()&lt;/code&gt; e &lt;code&gt;waitpid&lt;/code&gt; se diferenciam nos seguintes. &lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;wait()&lt;/code&gt; bloqueia o processo até que qualquer dos filhos termine. &lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;waitpid()&lt;/code&gt;, aguarda um processo filho específico tenha o seu &lt;em&gt;status&lt;/em&gt; alterado. Por padrão, ela aguarda o término do processo indicado, porém, o seu comportamento pode ser alterado por meio das opções do terceiro argumento. &lt;/p&gt;

&lt;p&gt;São as opções disponíveis. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WNOHANG: retorna imediatamente, em vez de bloquear, se não houver nenhum processo filho que tenha terminado ou parado. Isso permite verificar o status dos processos filhos sem ficar bloqueado.
&lt;/li&gt;
&lt;li&gt;WUNTRACED: Essa opção faz com que a função waitpid() também retorne informações sobre processos filhos parados (stopped), além dos processos filhos que terminaram. Por padrão, a função só retorna informações sobre processos filhos que terminaram.&lt;/li&gt;
&lt;li&gt;WCONTINUED: retorna informações sobre processos filhos retomados (resumed) após terem sido parados. Isso é útil quando se deseja monitorar o ciclo de vida completo dos processos filhos, incluindo pausas e retomadas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referências:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;STEVENS, W. Richard; RAGO, Stephen A. Advanced programming in the UNIX environment. Addison-Wesley, 2013.&lt;/li&gt;
&lt;li&gt;Tanenbaum, Andrew S. Sistemas operacionais modernos / Andrew S. Tanenbaum, Herbert Bos; tradução Jorge Ritter; revisão técnica Raphael Y. de Camargo. – 4. ed. – São Paulo: Pearson Education do Brasil, 2016.&lt;/li&gt;
&lt;li&gt;MATTHEW, Neil; STONES, Richard. Beginning linux programming. John Wiley &amp;amp; Sons, 2008.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pages.cs.wisc.edu/%7Eremzi/OSTEP/"&gt;https://pages.cs.wisc.edu/~remzi/OSTEP/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pages.cs.wisc.edu/%7Eremzi/OSTEP/cpu-api.pdf"&gt;https://pages.cs.wisc.edu/~remzi/OSTEP/cpu-api.pdf&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.inf.ufes.br/%7Ergomes/so_fichiers/roteiro1.pdf"&gt;http://www.inf.ufes.br/~rgomes/so_fichiers/roteiro1.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.inf.ufes.br/%7Ergomes/so_fichiers/roteiro2.pdf"&gt;http://www.inf.ufes.br/~rgomes/so_fichiers/roteiro2.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.educative.io/answers/wait-vs-waitpid-in-c"&gt;https://www.educative.io/answers/wait-vs-waitpid-in-c&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>braziliandevs</category>
      <category>unix</category>
      <category>linux</category>
    </item>
    <item>
      <title>Notas introdutórias à ferramenta Address Sanitizer</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Mon, 15 Jan 2024 19:25:43 +0000</pubDate>
      <link>https://dev.to/pliniohr/notas-introdutorias-a-ferramenta-address-sanitizer-3edc</link>
      <guid>https://dev.to/pliniohr/notas-introdutorias-a-ferramenta-address-sanitizer-3edc</guid>
      <description>&lt;p&gt;A Address Sanitizer, ASan, é uma ferramenta que permite identificar erros de memória em tempo de execução. &lt;br&gt;
Em outras palavras, quando executamos nossos programa e ocorre algum erro de memória: a ASan acusa a ocorrência do problema, bem como interrompendo a sua execução. &lt;/p&gt;

&lt;p&gt;Segundo o descrito no &lt;em&gt;paper&lt;/em&gt; "&lt;em&gt;AddressSanitizer: A Fast Address Sanity Checker&lt;/em&gt;", ela é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a new memory error detector. Our tool finds out-of-bounds accesses to heap, stack, and global objects, as well as use-after-free bugs. It employs a specialized memory allocator and code instrumentation that is simple enough to be implemented in any compiler, binary translation system, or even in hardware.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por meio dela é possível identificar os seguintes erros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use after free (dangling pointer dereference)&lt;/li&gt;
&lt;li&gt;Heap buffer overflow&lt;/li&gt;
&lt;li&gt;Stack buffer overflow&lt;/li&gt;
&lt;li&gt;Global buffer overflow&lt;/li&gt;
&lt;li&gt;Use after return&lt;/li&gt;
&lt;li&gt;Use after scope&lt;/li&gt;
&lt;li&gt;Initialization order bugs&lt;/li&gt;
&lt;li&gt;Memory leaks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ela já vem disponível nos dois compiladores mais utilizados GCC e CLANG. Sua utilização é por meio de &lt;em&gt;flags&lt;/em&gt; &lt;br&gt;
definidas durante a compilação. Assim, a ASan insere no código da aplicação, que está sendo compilada, mecanismos que permite "&lt;em&gt;identificar diversos problemas de acesso à memória, incluindo o uso de memória desalocada, estouros de buffer no stack e no heap, acesso à memória não inicializada e vazamentos de memória&lt;/em&gt;" (PRADO, 2018).&lt;/p&gt;

&lt;p&gt;A sua forma de atuação pode ser consultada na &lt;a href="https://github.com/google/sanitizers/wiki/AddressSanitizerCallStack"&gt;documentação&lt;/a&gt;. Mas, basicamente, a ASan atua trocando as chamadas &lt;code&gt;malloc/free&lt;/code&gt; do código pelas suas próprias versões de gerenciadores de acesso/uso de memória. &lt;/p&gt;

&lt;p&gt;A utilização dessa ferramenta é fundamental para identificar problemas/erros escondidos. Por que escondidos? Pois, pode ocorrer que o programa seja executado em sua totalidade com aparente estado de normalidade, todavia, sem que seja disparado algum erro ou interrompido a sua execução. Sendo que, há alguns erros que podem estarem ocorrendo e que terão consequências em outras execuções ou exporem o software à alguma vulnerabilidade.   &lt;/p&gt;

&lt;p&gt;Deve-se ressaltar que o seu uso provoca uma sobrecarga na execução e processamento da aplicação. Em razão disso, é recomenddo a sua utilização apenas em versões de desenvolvimento e testes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Uso
&lt;/h2&gt;

&lt;p&gt;Para habilitar o ASan, adicione a seguinte flag quando estiver compilando o progama. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;-fsanitize=address (clang)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gcc app.c -fsanitize=address -o app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tem outras &lt;em&gt;flgas&lt;/em&gt; que podem serem consultadas na &lt;a href="https://github.com/google/sanitizers/wiki/AddressSanitizerCallStack"&gt;documentação&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Exemplos de usos
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Erro Stack buffer overflow
&lt;/h3&gt;

&lt;p&gt;"&lt;em&gt;Buffer Overflow, também chamado de Buffer Overrun, é uma anomalia em um programa em que, ao escrever dados em um buffer (armazenamento temporário de dados), a escrita ultrapassa o tamanho do buffer e começa a escrever nos espaços adjacentes.&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;Veja-se o exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt;     &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

   &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'O'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'l'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'a'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando compilado e executado, não é apresentado qualquer erro;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; gcc test.c &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; 
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ./test
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Ola
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, quando compilado com a &lt;em&gt;flag&lt;/em&gt; &lt;code&gt;-fsanitize=address&lt;/code&gt; e executado, a ASan entra em ação para apresentar os erros encontrados e interromper a respectiva execução.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; gcc test.c -fsanitize=address -o test
&amp;gt; ./test

=================================================================
==389==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffe948a7662 at pc 0x55d86850528f bp 0x7ffe948a7630 sp 0x7ffe948a7628
WRITE of size 1 at 0x7ffe948a7662 thread T0
    #0 0x55d86850528e in main (/home/senhor/School42/ft_printf/test+0x128e)
    #1 0x7f06f5c9cd09 in __libc_start_main ../csu/libc-start.c:308
    #2 0x55d8685050b9 in _start (/home/senhor/School42/ft_printf/test+0x10b9)

Address 0x7ffe948a7662 is located in stack of thread T0 at offset 34 in frame
    #0 0x55d868505184 in main (/home/senhor/School42/ft_printf/test+0x1184)

  This frame has 1 object(s):
    [32, 34) 'str' (line 6) &amp;lt;== Memory access at offset 34 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/home/senhor/School42/ft_printf/test+0x128e) in main
Shadow bytes around the buggy address:
  0x10005290ce70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290ce80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290ce90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290cea0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290ceb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=&amp;gt;0x10005290cec0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1[02]f3 f3 f3
  0x10005290ced0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290cee0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290cef0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290cf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10005290cf10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==389==ABORTING

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Erro Memory leaks
&lt;/h3&gt;

&lt;p&gt;Outro exemplo é com &lt;em&gt;Memory leaks&lt;/em&gt;. &lt;em&gt;Memory leaks&lt;/em&gt; ou vazamento de memória, é segundo a Wikipédia, "&lt;em&gt;um fenômeno que ocorre quando um programa de computador gerencia incorretamente alocações de memória de maneira que certa memória não é liberada quando não é mais necessária&lt;/em&gt;". &lt;/p&gt;

&lt;p&gt;Veja-se o exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;char&lt;/span&gt;     &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
   &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando compilado e executado, novamente, não é apresentado qualquer erro;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; gcc test.c &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt; 
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ./test hello
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, quando compilado com a &lt;em&gt;flag&lt;/em&gt; &lt;code&gt;-fsanitize=address&lt;/code&gt; e executado, a ASan entra em ação para apresentar os erros encontrados.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; gcc test.c -fsanitize=address -o test
&amp;gt; ./test hello                                                                                                                                                         hello                                                                                                                                                                                                                                                                                                                                         =================================================================                                                      ==822==ERROR: LeakSanitizer: detected memory leaks                                                                                                                                                                                                                                                                                            Direct leak of 1024 byte(s) in 1 object(s) allocated from:                                                                                                                 #0 0x7f5f09215e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145                                                                  #1 0x5624c33ff1bd in main (/home/senhor/School42/ft_printf/test+0x11bd)                                                                                                #2 0x7f5f08fbbd09 in __libc_start_main ../csu/libc-start.c:308                                                                                                                                                                                                                                                                            SUMMARY: AddressSanitizer: 1024 byte(s) leaked in 1 allocation(s).    

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Referências:
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf"&gt;https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sergioprado.org/identificando-problemas-de-acesso-memoria-com-o-addresssanitizer/"&gt;https://sergioprado.org/identificando-problemas-de-acesso-memoria-com-o-addresssanitizer/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pt.wikipedia.org/wiki/Vazamento_de_mem%C3%B3ria"&gt;https://pt.wikipedia.org/wiki/Vazamento_de_memória&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://girishjoshi.io/post/using-address-sanitizer-with-gcc/"&gt;https://girishjoshi.io/post/using-address-sanitizer-with-gcc/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://azure.microsofts.workers.dev/en-us/cpp/sanitizers/"&gt;https://azure.microsofts.workers.dev/en-us/cpp/sanitizers/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://clang.llvm.org/docs/AddressSanitizer.html"&gt;https://clang.llvm.org/docs/AddressSanitizer.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early"&gt;https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gitbook.ganeshicmc.com/pwning/buffer-overflow-e-a-stack"&gt;https://gitbook.ganeshicmc.com/pwning/buffer-overflow-e-a-stack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Estudos de Bases Numéricas</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Wed, 23 Aug 2023 11:03:38 +0000</pubDate>
      <link>https://dev.to/pliniohr/estudos-de-bases-numericas-4mc5</link>
      <guid>https://dev.to/pliniohr/estudos-de-bases-numericas-4mc5</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Como os números são representados&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Em um primeiro momento precisamos entender como os números são representados. Os números são representados por meio do sistema posicional ou notação posicional.&lt;/p&gt;

&lt;p&gt;Cada número ou dígito tem seu valor em função da posição que ocupa na sequência numérica e pela base (sistema) que faz parte. &lt;/p&gt;

&lt;p&gt;Como escreve os professores Profs. &lt;a href="http://m.sc/"&gt;M.Sc&lt;/a&gt;. Lucio M. Duarte e Ph.D. Avelino Zorzo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;S*istemas numéricos são posicionais, isto é, cada quantidade é representada em uma única forma, mediante uma certa combinação de símbolos, que têm um significado distinto, segundo sua posição.*&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No sistema decimal, como já comentado, cada posição tem um valor intrínseco que&lt;br&gt;
equivale a dez vezes o valor da posição que está imediatamente a sua direita.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fonte: &lt;a href="https://www.inf.pucrs.br/%7Ezorzo/ii/downloads/representacaodedados.pdf"&gt;https://www.inf.pucrs.br/~zorzo/ii/downloads/representacaodedados.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para sabemos o valor de um número, não basta saber o seu valor individual, mas também qual base ele faz parte e qual a sua posição quando está representando em uma sequência de símbolos. &lt;/p&gt;

&lt;p&gt;Vamos partir a explicação do nosso sistema decimal, ou base 10, o qual já estamos acostumados a utilizar. &lt;/p&gt;

&lt;p&gt;A exemplo, o número &lt;code&gt;422&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;O qual pode escrito da seguinte forma:  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;422 = 4x100 + 2x10 + 2x1&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ou da seguinte forma. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;422 = 4x10^2 + 2x10^1 + 2x10^0&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Explicando: &lt;/p&gt;

&lt;p&gt;Para sabermos o valor do &lt;code&gt;4&lt;/code&gt;, que representa &lt;code&gt;400&lt;/code&gt;, temos que saber a sua posição, contando da direita para a esquerda começando com zero. Que nesse caso é &lt;code&gt;2&lt;/code&gt;. Deve observar que consideramos o início da contagem das posições da direita para a esquerda. &lt;/p&gt;

&lt;p&gt;Depois multiplicamos &lt;code&gt;4&lt;/code&gt; pela base, neste caso &lt;code&gt;10&lt;/code&gt;, elevada a sua posição: &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;*4*10^2 = 4*100 = 400&lt;/strong&gt;*&lt;/p&gt;

&lt;p&gt;Para o valor de &lt;code&gt;2&lt;/code&gt; que representa &lt;code&gt;20&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;*2*10^1 = 2*10 = 20&lt;/strong&gt;*&lt;/p&gt;

&lt;p&gt;E para o valor de &lt;code&gt;2&lt;/code&gt; que &lt;code&gt;2&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;*2*10^0 = 2*1 = 2&lt;/strong&gt;*.&lt;/p&gt;

&lt;p&gt;Somamos os resultados: &lt;code&gt;400 + 20 + 2 = 422&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Concluindo. O valor do símbolo depende da posição que ocupa em relação a todo o conjunto que está representando, bem como da base que está sendo utilizada na representação. &lt;/p&gt;

&lt;p&gt;Nesse sentido, podemos obter a partir da seguinte equação de contagem:&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
D\;=\;\sum_{i\;=\;-n\;}^{p-1}\;d_i\;\times\;r^i\;=d_{p-i}\times r^{p-1}+...+d_1\times r^1+d_0\times r^0+d_{-1}\times r^{-1}+...+d_{-n}\times r^{-n}&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;Onde: &lt;/p&gt;

&lt;p&gt;– D : número;&lt;br&gt;
– r : base ou &lt;em&gt;radix&lt;/em&gt;;&lt;br&gt;
– d : dígito (&lt;code&gt;0 ≤ d &amp;lt; r&lt;/code&gt;);&lt;br&gt;
– p : quantidade de dígitos na parte inteira;&lt;br&gt;
– n : quantidade de dígitos na parte fracionária;&lt;/p&gt;

&lt;p&gt;Por fim uma observação importante:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Observa-se que os sistemas não posicionais dificultavam a representação de números&lt;br&gt;
“grandes”, ou seja, era necessário muitos símbolos para isso. Por outro lado, em um sistema&lt;br&gt;
posicional é possível representar números cada vez maiores com os mesmos símbolos. Outra&lt;br&gt;
grande vantagem do sistema de numeração com valor posicional é que as operações (adição,&lt;br&gt;
subtração, multiplicação e divisão) são de execução bem mais simples.&lt;br&gt;
Em um sistema de numeração posicional o número nove, por exemplo, não tem o&lt;br&gt;
mesmo valor quando está colocado na fileira nas unidades, dezenas, centenas e, assim por&lt;br&gt;
diante. Por exemplo, 959 – No sistema de numeração que usamos hoje, 9 na unidade, tem&lt;br&gt;
como valor posicional nove unidades, na centena o 9 tem valor novecentos. Nesse sistema,&lt;br&gt;
o valor de um algarismo depende da posição que ele ocupa no número.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;fonte: &lt;a href="https://repositorio.ufgd.edu.br/jspui/bitstream/prefix/1375/1/KatiuceFernandesRocha.pdf"&gt;https://repositorio.ufgd.edu.br/jspui/bitstream/prefix/1375/1/KatiuceFernandesRocha.pdf&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Mais informações:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pt.wikipedia.org/wiki/Nota%C3%A7%C3%A3o_posicional"&gt;https://pt.wikipedia.org/wiki/Notação_posicional&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://edisciplinas.usp.br/pluginfile.php/4190820/mod_resource/content/5/PCS3115%202018S1%20Sistemas%20de%20Numeracao%20v2.pdf"&gt;https://edisciplinas.usp.br/pluginfile.php/4190820/mod_resource/content/5/PCS3115 2018S1 Sistemas de Numeracao v2.pdf&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  Bases numéricas
&lt;/h2&gt;

&lt;p&gt;Uma base numérica representa uma quantidade de símbolos possíveis que podemos utilizar para representar um número. &lt;/p&gt;

&lt;p&gt;A elas temos a seguinte definição formal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Definição&lt;/strong&gt; (Sistema de numeração de base &lt;code&gt;b&lt;/code&gt;)&lt;strong&gt;.&lt;/strong&gt; &lt;em&gt;Dado um número natural&lt;/em&gt; &lt;code&gt;b&lt;/code&gt;&amp;gt;1 &lt;em&gt;e o conjunto de símbolos&lt;/em&gt; {±,0,1,2,…,&lt;code&gt;b&lt;/code&gt;−1}&lt;em&gt;,&lt;/em&gt; &lt;em&gt;a sequência de símbolos&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
(d_nd_{n-1}..d_1d_0,d_{-1}d_{-2}...)_b&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;&lt;em&gt;representa o número positivo&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
d_n⋅b^n+d_{n-1}⋅b^{n-1}+\cdots+d_0⋅b^0+d_{-1}⋅b^{-1}+d_{-2}⋅b^{-2}+\cdots&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Para representar números negativos usamos o símbolo&lt;/em&gt; − &lt;em&gt;a esquerda&lt;/em&gt; &lt;em&gt;do numeral&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Mais informações: &lt;a href="https://www.ufrgs.br/reamat/CalculoNumerico/livro-py/rdneadm-sistema_de_numeracao_e_mudanca_de_base.html"&gt;https://www.ufrgs.br/reamat/CalculoNumerico/livro-py/rdneadm-sistema_de_numeracao_e_mudanca_de_base.html&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Assim, escolhemos um número &lt;code&gt;b&lt;/code&gt; como base e &lt;code&gt;b&lt;/code&gt; símbolos, um para cada número de &lt;code&gt;0 a b − 1&lt;/code&gt;, chamados de algarismos (dígitos). Multiplicando um destes números (algarismos) pelas potências de &lt;code&gt;b (1, b^2, b^3, etc.)&lt;/code&gt; e somando-os, conseguimos expressar um número em uma determinada base. Por exemplo, &lt;code&gt;1352 = 1 · 10^3 + 3 · 10^2 + 5 · 10^1 + 2 · 10^0&lt;/code&gt;. Esse número, por exemplo, está representado na base decimal, ou seja, &lt;code&gt;b = 10&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Assim, os algarismos em qualquer número dado representa um múltiplo de alguma potência da base, potência essa que depende da posição ocupada pelo algarismo. Como exemplo de sistema posicional temos nosso sistema de numeração posicional decimal indo-arábico. &lt;/p&gt;

&lt;p&gt;Nesse sistema, por exemplo, &lt;code&gt;5&lt;/code&gt; em &lt;code&gt;506&lt;/code&gt; representa &lt;code&gt;5 · 10^2&lt;/code&gt; ou &lt;code&gt;500&lt;/code&gt;. Agora, &lt;code&gt;5&lt;/code&gt; em &lt;code&gt;58&lt;/code&gt; representa &lt;code&gt;5 x 10^1&lt;/code&gt; ou &lt;code&gt;50&lt;/code&gt;. Observe que o zero é importante para indicar a ausência de alguma potência da base.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fonte: &lt;a href="https://repositorio.ufgd.edu.br/jspui/bitstream/prefix/1375/1/KatiuceFernandesRocha.pdf"&gt;https://repositorio.ufgd.edu.br/jspui/bitstream/prefix/1375/1/KatiuceFernandesRocha.pdf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;São várias as bases numéricas, mas aqui apenas trataremos de estudar algumas mais utilizadas no ambiente de programação. Quais são:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Binária;&lt;/li&gt;
&lt;li&gt;Octal;&lt;/li&gt;
&lt;li&gt;Decimal;&lt;/li&gt;
&lt;li&gt;Hexadecimal;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Em seguida falarei um pouco sobre cada um delas. &lt;/p&gt;
&lt;h3&gt;
  
  
  Base Binária
&lt;/h3&gt;

&lt;p&gt;No sistema binário ou base binária temos apenas dois símbolos para compor os números. São: &lt;code&gt;0&lt;/code&gt; e &lt;code&gt;1&lt;/code&gt;.  Por isso é chamado de binário em razão da quantidade de símbolos que fazem parte: dois. &lt;/p&gt;

&lt;p&gt;São incluídos como símbolos pertencentes a determinada base iniciando-se em &lt;code&gt;0&lt;/code&gt; até &lt;code&gt;b - 1&lt;/code&gt;. Conforme explicado, acima, na definição formal de bases numéricas. &lt;/p&gt;

&lt;p&gt;Que neste caso são:&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
{0, 1}&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;Onde cada símbolo ou digito tem o seu valor em função do produto da multiplicação dele por 2 elevado a n-enésima posição. Ou seja, construímos a representação de um número qualquer somando as potências de dois presentes na representação. &lt;/p&gt;

&lt;p&gt;Como temos apenas &lt;code&gt;0&lt;/code&gt; e &lt;code&gt;1&lt;/code&gt; como dígitos disponíveis, quando temos um valor a ser considerado e quando temos zero, dispensa-se a explicação.  &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Posição&lt;/th&gt;
&lt;th&gt;9&lt;/th&gt;
&lt;th&gt;8&lt;/th&gt;
&lt;th&gt;7&lt;/th&gt;
&lt;th&gt;6&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Valor&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Exemplos de representação de números decimais na base binária:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2 = 00010&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 = 00100&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10 = 1010&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;25 = 11001&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;É a base que os sistemas computacionais entendem e operam. Diferente de nós que utilizamos o sistema decimal. Dado que utilizam os seguintes algarismos: 1 bit (para indicar presença de tensão) e 0 bit (para indicar ausência de tensão).&lt;/p&gt;

&lt;p&gt;Toda operação computacional primeiro converte o número para base &lt;code&gt;2&lt;/code&gt;, realiza as operações e depois converte para a base original, qual seja: decimal, hexadecimal ou outra que o usuário esteja utilizando. &lt;/p&gt;
&lt;h3&gt;
  
  
  Base Octal
&lt;/h3&gt;

&lt;p&gt;Base octal ou base 8 (oito). Nesta base temos 8 (oito) algarismos para representar um número qualquer. São:&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
{0, 1, 2, 3, 4, 5, 6, 7}&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;Exemplos de números na base dez e sua representação na base octal:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 = 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10 = 12&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;42 = 52&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;127 = 177&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mais na frente será demonstrado como é feita a conversão acima exemplificada. &lt;/p&gt;
&lt;h3&gt;
  
  
  Base Decimal
&lt;/h3&gt;

&lt;p&gt;A base decimal ou base 10 (dez) é que utilizamos no nosso dia a dia. Ela dispõe de 10 (algarismos) para representar os números. Quais são:&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}&lt;br&gt;
$$&lt;/p&gt;
&lt;h3&gt;
  
  
  Base Hexadecimal
&lt;/h3&gt;

&lt;p&gt;A base hexadecimal ou base 16 (dezesseis) são utilizados dezesseis símbolos, que vão de &lt;code&gt;0&lt;/code&gt; até &lt;code&gt;9&lt;/code&gt; mais as letras &lt;code&gt;A&lt;/code&gt; até &lt;code&gt;F&lt;/code&gt;. No qual as letras são equivalentes no sistema decimal aos valores de &lt;code&gt;10&lt;/code&gt; até &lt;code&gt;15&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F}&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;Exemplos de números na base dez na base hexadecimal:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 = 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10 = A&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;42 = 2A&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;127 = 2F&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Curiosidade:&lt;/strong&gt; Na linguagem Javascript, pode-se obter o valor decimal de número hexadecimal utilizando o prefixo &lt;code&gt;0x&lt;/code&gt; antes do número na base 16.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x7F&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 127&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conversão de decimal para para as demais bases&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Dado um número na base decimal podemos escrevê-lo em qualquer outra base usando sucessivamente a divisão por resto ou Euclidiana. O número que no passo n-ésimo for quociente passa a ser dividendo no passo de ordem n + 1. O processo conclui quando o quociente for zero.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Referências&lt;/em&gt;: LINARES, Juan López; BRUNO-ALFONSO, Alexys; BARBOSA, Grazielle Feliciani. Bases numéricas na olimpíada internacional de matemática. &lt;strong&gt;Revista Professor de Matemática Online&lt;/strong&gt;, v. 7, n. 02, 2019.&lt;/p&gt;

&lt;p&gt;Continuando a explicação. Após chegarmos a momento que o consciente for zero, alinhamos os restos da divisão na ordem inversa que foram encontrados. &lt;/p&gt;

&lt;p&gt;Deve-se atentar que deve utilizar o maior quociente inteiro da divisão.  &lt;/p&gt;

&lt;p&gt;Converter o número &lt;code&gt;42&lt;/code&gt; na base &lt;code&gt;10&lt;/code&gt; para a base &lt;code&gt;2&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Para o cálculo do resto utilizaremos o operador módulo, representado por &lt;code&gt;%&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;42 / 2 = 21       42 % 2 = 0&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;21 / 2 = 10       21 % 2 = 1&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;10 / 2 = 5         10 % 2 = 0&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;5  /  2 = 2          5 % 2 = 1&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2  /  2 = 1          2 % 2 = 0&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;1  /  2 = 0          1 % 2 =  1&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Feitas as divisões sucessivas, basta alinhar os restos na ordem inversa: &lt;code&gt;101010&lt;/code&gt;. Assim temos a representada do número &lt;code&gt;42&lt;/code&gt;  na base &lt;code&gt;10&lt;/code&gt; na base &lt;code&gt;2&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Este mesmo procedimento é para a conversão para qualquer outra base. Basta substituir o dois pela base final desejada. &lt;/p&gt;

&lt;h3&gt;
  
  
  Conversão da parte fracionária
&lt;/h3&gt;

&lt;p&gt;Agora, para conversão de um número fracionário ou de um número com uma parte fracionária separamos a parte inteira da fracionária. Enquanto para a parte inteira realizamos o procedimento acima explicado; utilizando o método das divisões sucessivas. Para o número fracionário ou parte fracionária realizamos multiplicações sucessivas, da parte fracionária, até que o resultado seja apenas inteiros. Ou que repitam, que é quando estaremos diante de uma dizima periódica.&lt;/p&gt;

&lt;p&gt;Por exemplo, converter o número &lt;code&gt;42,75&lt;/code&gt; na base &lt;code&gt;10&lt;/code&gt; para a base &lt;code&gt;2&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;A parte inteira do número já foi feito acima, então descartar-se repetir os mesmo cálculos. Aqui é interessante apenas a parte fracionária. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;0,75 * 2 = 1,5&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;0,50 * 2 = 1&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nesse caso, diferentemente do que fazemos com a parte inteira, vamos posicionando a parte inteira resultante da multiplicação na ordem que foram calculados, ou encontrados.&lt;/p&gt;

&lt;p&gt;No nosso exemplo, tivemos como resultado &lt;code&gt;11&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Desse modo, o &lt;code&gt;42,75&lt;/code&gt; na base &lt;code&gt;10&lt;/code&gt; para a base &lt;code&gt;2&lt;/code&gt; é: &lt;code&gt;101010,11&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conversão das demais bases para decimal&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Para convertemos um número em determinada base para decimal, basta aplicar a definição do que vimos quando escrevi sobre ***********************&lt;strong&gt;&lt;em&gt;bases numéricas&lt;/em&gt;&lt;/strong&gt;*********************** linhas acima. &lt;/p&gt;

&lt;p&gt;Relembrando. Para conseguir o valor do número, na base dez, a partir de determinada base fazemos o seguinte.&lt;/p&gt;

&lt;p&gt;Multiplicamos os dígitos pela base elevada a sua posição. Quando número for fracionário, ou parte fracionária, a posição é negativa. Após somamos os produtos e teremos a representação do número na base dez. &lt;/p&gt;

&lt;p&gt;Algoritmo: &lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
d_n⋅b^n+d_{n-1}⋅b^{n-1}+\cdots+d_0⋅b^0+d_{-1}⋅b^{-1}+d_{-2}⋅b^{-2}+\cdots&lt;br&gt;
$$&lt;/p&gt;

&lt;p&gt;Exemplo para: &lt;code&gt;101010,11&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;$$&lt;br&gt;
\small&lt;br&gt;
x = (101010,11)_2  \newline&lt;br&gt;
x = (1*2^5)+(0*2^4)+(1*2^3)+(0*2^2)+(1*2^1)+(0*2^0)+(1*2^{-1}))+(1*2^{-2}) \newline&lt;br&gt;
x = 32+0+8+0+2+0+0,5+0,25&lt;br&gt;
x = 42,75&lt;br&gt;
$$&lt;/p&gt;
&lt;h2&gt;
  
  
  Prática de programação. Conversão de bases numéricas
&lt;/h2&gt;
&lt;h3&gt;
  
  
  De uma base &lt;em&gt;n&lt;/em&gt; para a base decimal
&lt;/h3&gt;

&lt;p&gt;Agora vou trazer um exemplo de um código que converte um número em determinada base para decimal na linguagem C.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="nf"&gt;value_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="nf"&gt;base_from_to_decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;base_from&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;   &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"42 to b10 = %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_from_to_decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"42"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2A to b10 = %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_from_to_decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"101010 to b10 = %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_from_to_decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"101010"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;   &lt;span class="nf"&gt;value_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'9'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'a'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'f'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sc"&gt;'a'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="sc"&gt;'F'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sc"&gt;'A'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="nf"&gt;base_from_to_decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;base_from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt;   &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;base_from&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;value_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que interessa no código acima são as funções &lt;code&gt;value_of&lt;/code&gt; e &lt;code&gt;base_from_to_decimal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;value_of&lt;/code&gt; devolve o inteiro correspondente ao um caractere na tabela ASCII (American Standard Code for Information Interchange ou ”Código Padrão Americano para o Intercâmbio de Informação”).&lt;/p&gt;

&lt;p&gt;Esse processo de recuperação é necessário pelo fato que a número a ser convertido é passado para a função &lt;code&gt;base_from_to_decimal&lt;/code&gt; como uma cadeia de caracteres, mais comumente conhecido: uma &lt;em&gt;string&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;base_from_to_decimal&lt;/code&gt; recebe dois parâmetros: a cadeia de caracteres que contém a representação do número a ser convertido para decimal e um inteiro indicando qual base ela está organizado. &lt;/p&gt;

&lt;p&gt;No corpo, declaramos e é inicializado uma variável, &lt;code&gt;result&lt;/code&gt;, do tipo inteiro, que será retornada com o valor do número convertido de decimal. &lt;/p&gt;

&lt;p&gt;Em seguida realizamos uma interação sobre a ***&lt;strong&gt;&lt;em&gt;string&lt;/em&gt;&lt;/strong&gt;*** recebida. Para cada caractere recuperemos o seu valor decimal da tabela ASCII com a função &lt;code&gt;value_of&lt;/code&gt;. Esse valor é somado ao produto do valor de &lt;code&gt;result&lt;/code&gt;, a cada interação, multiplicado pela base de origem. &lt;/p&gt;

&lt;p&gt;Uma vez encerrado o *&lt;strong&gt;&lt;em&gt;loop&lt;/em&gt;&lt;/strong&gt;* a variável &lt;code&gt;result&lt;/code&gt; é retornada com a representação do número na base dez. &lt;/p&gt;

&lt;p&gt;O código é uma implementação bem grosseira. Apenas como demonstração do conceito aqui estudado. Observar-se que esse código realiza apenas conversão de números inteiros.&lt;/p&gt;

&lt;h3&gt;
  
  
  Da base decimal para uma base &lt;em&gt;n&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;O código abaixo converte um número decimal para uma outra base desejada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#define MAX_SIZE 32
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="nf"&gt;to_base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;to_base&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;MAX_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MAX_SIZE&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt;  &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;nbr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sing&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;to_base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d to B2: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nbr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicando rapidamente a função &lt;code&gt;main&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Nela é declarada um vetor de caracteres no qual será armazenado a representação do nosso número convertido. Em seguida é declarado a variável &lt;code&gt;nbr&lt;/code&gt; , tipo inteiro, que será utilizada para definir o número que se deseja converter e o inteiro &lt;code&gt;i&lt;/code&gt; que terá a função de definir o início do posicionamento dos caracteres. Pois, caso o número seja negativo, será necessário posicionar o sinal negativo no início do vetor. &lt;/p&gt;

&lt;p&gt;Logo, é feito um verificação se o número é negativo, se sim é realizado o procedimento descrito  acima. &lt;/p&gt;

&lt;p&gt;Feito isso, é realizada uma chamada para a função &lt;code&gt;to_base&lt;/code&gt; que recebe cinco argumentos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;O número a ser convertido, do tipo inteiro: &lt;code&gt;nbr&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;A base desejada, do tipo cadeia de caracteres: &lt;code&gt;base&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;O tamanho da base, do tipo inteiro: &lt;code&gt;len&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Um vetor de caracteres onde será salvo a representação numérica convertida: &lt;code&gt;resulted&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;E um inteiro, que serve com &lt;em&gt;index&lt;/em&gt; para o o vetor: &lt;code&gt;i&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A função &lt;code&gt;to_base&lt;/code&gt; é recursiva. Ela chama a se mesma por quanto o valor de &lt;code&gt;nbr&lt;/code&gt; for diferente de zero. E a cada nova chamada o valor de &lt;code&gt;nbr&lt;/code&gt;é dividido por &lt;code&gt;len&lt;/code&gt;. Lembrando que, a cada nova chamada da função, ela é empilhada na pilha com os valores atuais da chamada. Aqui não vou entrar nos detalhes de como é a execução de uma função recursiva. &lt;/p&gt;

&lt;p&gt;Quando o resultado da divisão for zero as chamadas recursivas se encerram e volta a continuar o fluxo de execução, da função, a partir de cada chamada. &lt;/p&gt;

&lt;p&gt;Outro ponto importante a lembrar: é que devemos alinhar os restos da divisão na ordem inversa que forem encontrados. Nesse caso, devemos salvar o resto da cada divisão a partir do resultado da última chamada da função até a primeira. Enquanto é desempilhada da pilha de chamadas. &lt;/p&gt;

&lt;p&gt;Continuando a explicação da função. &lt;/p&gt;

&lt;p&gt;No laço &lt;code&gt;while&lt;/code&gt; seguinte, recortado do código da função &lt;code&gt;to_base&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resulted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;MAX_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O valor de &lt;code&gt;i&lt;/code&gt; que é incrementado até que seja encontrado um local no vetor &lt;code&gt;resulted&lt;/code&gt; que possa receber o dígito, desde que seja respeitado o tamanho máximo disponível pelo vetor. &lt;/p&gt;

&lt;p&gt;Em seguida, o valor do digito resultante do módulo do valor presente de &lt;code&gt;nbr&lt;/code&gt; por &lt;code&gt;len&lt;/code&gt; é armazenado na vetor que representará o número convertido ao final. A posição é dada pelo valor de &lt;code&gt;i&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Imperar anotar que nos dois exemplos não é implementado uma forma de lidar com números fracionários, mas caso o leitor tenha interesse: &lt;a href="https://www.exploringbinary.com/converting-floating-point-numbers-to-binary-strings-in-c/"&gt;Neste artigo&lt;/a&gt; o autor implementa um algoritmo que converte um número de ponto flutuante para uma ***&lt;strong&gt;&lt;em&gt;string&lt;/em&gt;&lt;/strong&gt;*** que representa o número na base &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>math</category>
      <category>braziliandevs</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>[Estudos de C] Escrevendo uma versão simples do utilitário cat</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Wed, 23 Aug 2023 11:00:50 +0000</pubDate>
      <link>https://dev.to/pliniohr/estudos-de-c-escrevendo-uma-versao-simples-do-utilitario-cat-2mha</link>
      <guid>https://dev.to/pliniohr/estudos-de-c-escrevendo-uma-versao-simples-do-utilitario-cat-2mha</guid>
      <description>&lt;p&gt;O &lt;code&gt;cat&lt;/code&gt; é um utilitário de linha de comando que lê arquivos, seja apenas um ou uma sequência informada, e escreve o seu conteúdo em fluxo de destino. &lt;/p&gt;

&lt;p&gt;O nome &lt;code&gt;cat&lt;/code&gt; é derivado de: &lt;em&gt;(con)&lt;/em&gt;&lt;em&gt;cat&lt;/em&gt;&lt;em&gt;enate files&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Conforme o manual (&lt;code&gt;man cat&lt;/code&gt;) é descrito com duas funções: concatenar arquivos e imprimir o seu conteúdo em um fluxo de saída. &lt;/p&gt;

&lt;p&gt;Utilizamos o &lt;code&gt;cat&lt;/code&gt; da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;OPTION]... &lt;span class="o"&gt;[&lt;/span&gt;FILE]...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa implementação é com fim de tentar a resolução, própria, do Exercício 01, da Piscine 10 de C, da Escola 42. Não participei de nenhuma piscina, apenas encontrei os PDFs relativos no Github e estou tentando fazer os exercícios. &lt;/p&gt;

&lt;p&gt;São as regras a implementação desta versão: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gUwmb3tO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/isukn4quaiek3lu33v8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gUwmb3tO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/isukn4quaiek3lu33v8m.png" alt="Image description" width="493" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como pode se ler das orientações acima, a implementação desta versão tem limitações das funções que poderão ser utilizadas. &lt;/p&gt;

&lt;p&gt;Nesta minha implementação, optei por utilizar apenas as funções: &lt;em&gt;open&lt;/em&gt;, &lt;em&gt;close&lt;/em&gt;, &lt;em&gt;read&lt;/em&gt; e &lt;em&gt;write&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Antes de adentrar diretamente na escrita da versão do &lt;code&gt;cat&lt;/code&gt; , vou estar escrevendo algumas notas de introdutórias. &lt;/p&gt;

&lt;h2&gt;
  
  
  File Descritores
&lt;/h2&gt;

&lt;p&gt;Um ************&lt;strong&gt;&lt;em&gt;File Descritor (FD)&lt;/em&gt;&lt;/strong&gt;************ é um número inteiro único maior que zero que guarda referência para um arquivo aberto pelo sistema operacional. &lt;/p&gt;

&lt;p&gt;Quando pede ao sistema operacional o acesso a determinado arquivo ou fluxo de dados, o ***&lt;strong&gt;&lt;em&gt;kernel&lt;/em&gt;&lt;/strong&gt;*** retorna, um *********&lt;strong&gt;&lt;em&gt;File Descritor&lt;/em&gt;&lt;/strong&gt;********* de um registro na tabela global de registros de arquivos do sistema operacional. &lt;/p&gt;

&lt;p&gt;Por meio dele o processo ou programa pode acessar os dados constantes no arquivo, ou fluxo referenciado pelo FD. Observa-se que o pedido de acesso tenha sido acatado com sucesso. &lt;/p&gt;

&lt;p&gt;Em sistemas baseados em Unix e Linux os primeiros FD referem aos fluxos &lt;em&gt;stdin&lt;/em&gt;, &lt;em&gt;stdout&lt;/em&gt; e &lt;em&gt;stderr&lt;/em&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Nome&lt;/th&gt;
&lt;th&gt;File Descriptor&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;th&gt;Abreviatura&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard input&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;O fluxo de dados padrão para entrada, por exemplo, em um pipeline de comando. No terminal, o padrão é a entrada do teclado do usuário.&lt;/td&gt;
&lt;td&gt;stdin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standard output&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;O fluxo de dados padrão para saída, por exemplo, quando um comando imprime texto. No terminal, o padrão é a tela do usuário.&lt;/td&gt;
&lt;td&gt;stdout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Standard error&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;O fluxo de dados padrão para a saída relacionada à ocorrência de um erro. No terminal, o padrão é a tela do usuário.&lt;/td&gt;
&lt;td&gt;stderr&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Os valores dos FD acima descritos podem serem acessados indicando diretamente os seus valores ou por meio de constantes presentes nas bibliotecas &lt;code&gt;&amp;lt;unistd.h&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;stdio.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;STDIN_FILENO&lt;/td&gt;
&lt;td&gt;stdin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;STDOUT_FILENO&lt;/td&gt;
&lt;td&gt;stdout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;STDOUT_FILENO&lt;/td&gt;
&lt;td&gt;stderr&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Outra questão referente aos FD é a possibilidade de redirecionar os fluxos de dados entre diferentes FD por meio do *&lt;strong&gt;&lt;em&gt;pipe&lt;/em&gt;&lt;/strong&gt;*. Mas esse tópico tratarei em outro momento.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://www.computerhope.com/jargon/f/file-descriptor.htm"&gt;https://www.computerhope.com/jargon/f/file-descriptor.htm&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Função &lt;code&gt;open()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;open()&lt;/code&gt; permite a realização de conexão entre um arquivo e um FD.  Por meio dessa função, o programa tem acesso ao FD de um arquivo informado como parâmetro na chamada da função. &lt;/p&gt;

&lt;p&gt;A função tem o seguinte protótipo: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;int open(const char *pathname, int flags);&lt;br&gt;
 int open(const char *pathname, int flags, mode_t mode);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E é disponibilizada pela biblioteca &lt;code&gt;&amp;lt;fcntl.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O primeiro argumento, &lt;em&gt;path&lt;/em&gt;, é pelo qual passamos o caminho do caminho ou fluxo de dados que queremos acessar/abrir. &lt;/p&gt;

&lt;p&gt;O segundo argumento é o tipo de acesso que desejamos(leitura, escrita, leitura e escrita, etc). Esse passamos informando a respectiva, quis são constantes definidas no cabeçalho &lt;code&gt;&amp;lt;fcntl.h&amp;gt;&lt;/code&gt;. Exemplos de algumas **&lt;strong&gt;&lt;em&gt;flags&lt;/em&gt;&lt;/strong&gt;** definidas e mais utilizadas. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;Descrição&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;O_EXEC:&lt;/td&gt;
&lt;td&gt;Abre o arquivo para execução, apenas. Não se aplica a diretórios.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O_RDONLY&lt;/td&gt;
&lt;td&gt;Apenas leitura.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O_RDWR&lt;/td&gt;
&lt;td&gt;Abre o arquivo para leitura e escrita.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O_RDWR&lt;/td&gt;
&lt;td&gt;Abre um diretório para pesquisa, apenas. Não se aplica a não diretórios.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O_WRONLY&lt;/td&gt;
&lt;td&gt;Abre o arquivo apenas para a escrita.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;O terceiro argumento, facultativo, é utilizado quando estamos criando um novo arquivo. Pois, é por meio dele que definimos as permissões iniciais do arquivo criado. &lt;/p&gt;

&lt;p&gt;***************&lt;strong&gt;&lt;em&gt;Retorno:&lt;/em&gt;&lt;/strong&gt;*************** O retorno da chamada da função &lt;code&gt;open()&lt;/code&gt; é um número inteiro positivo que representa FD do respectivo arquivo ou fluxo de dados requerido a ser aberto. Caso contrário, a função retorna &lt;code&gt;-1&lt;/code&gt; e define o tipo de erro que ocorreu. &lt;/p&gt;

&lt;p&gt;O código abaixo é a implementação de utilização da função open() que cria, se não existir um arquivo e salva nele que o usuário digitar no &lt;code&gt;stdin&lt;/code&gt;, por enquanto o programa estiver em execução.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define MAX_BUF 1024
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt;    &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;bytes_writes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Arquivo de destino não definido.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;O_WRONLY&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_CREAT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_TRUNC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;S_IRUSR&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;S_IWUSR&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro ao abrir o arquivo!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDIN_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAX_BUF&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;bytes_writes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_writes&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error ao escrever no arquivo&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro na leitura do STDIN&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   

    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código ficou um pouco longo, mas bom que aproveito como exemplo para as explicações abaixo, sobre as demais funções. &lt;/p&gt;

&lt;p&gt;Para mais informações: &lt;code&gt;man 2 open&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html"&gt;https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Open_(system_call)"&gt;https://en.wikipedia.org/wiki/Open_(system_call)&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Função &lt;code&gt;close()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;close()&lt;/code&gt; fecha um FD aberto e referenciado. A chamamos quando precisamos fechar um arquivo ou fluxo de dados abertos. Fazemos isso passamos o arquivo ou fonte de dados como parâmetro, no qual será terminado a conexão com o FD referente. &lt;/p&gt;

&lt;p&gt;A função tem o seguinte protótipo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;int close(int fd);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;E é disponibilizada pela biblioteca &lt;code&gt;&amp;lt;unistd.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A função retorna 0 no caso de sucesso ou -1, em caso tenha ocorrido algum erro. &lt;/p&gt;

&lt;p&gt;Como pose se ver no código anteriormente exposto, a chamamos para fechar o FD do arquivo aberto antes do retorno final da função &lt;code&gt;main&lt;/code&gt;().&lt;/p&gt;

&lt;h2&gt;
  
  
  Função &lt;code&gt;read()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;read()&lt;/code&gt; lê uma certa quantidade de &lt;em&gt;bytes&lt;/em&gt; a partir de um FD e os salva em um &lt;em&gt;buffer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Ela tem o seguinte protótipo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ssize_t read(int fd, void *buf, size_t count);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O primeiro argumento é a indicação do FD no qual será feita a leitura. O segundo é o do &lt;em&gt;buffer&lt;/em&gt; que será salvo os dados lidos e o terceiro é a quantidade de **&lt;strong&gt;&lt;em&gt;bytes&lt;/em&gt;&lt;/strong&gt;** a serem lidos/transferidos.&lt;/p&gt;

&lt;p&gt;E é disponibilizada pela biblioteca &lt;code&gt;&amp;lt;unistd.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Quanto ao retorno: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cada chamada retorna uma contagem do número de bytes transferidos. Na leitura, o número de bytes retornados pode ser menor que o número solicitado.&lt;br&gt;
Um valor de retorno de zero bytes implica o fim do arquivo, e -1 indica algum tipo de erro.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Referências: RITCHIE, Dennis M. et al. The C programming language. &lt;strong&gt;Bell Sys. Tech. J&lt;/strong&gt;, v. 57, n. 6, p. 1991-2019, 1978.&lt;/p&gt;

&lt;p&gt;Como pode ser observado no código recortado do exposto acima, a função &lt;code&gt;read()&lt;/code&gt; é chamada no contexto de um &lt;em&gt;loop&lt;/em&gt; &lt;code&gt;while&lt;/code&gt;. Por enquanto o valor retornado for maior que zero, os dados lidos, por quantidade definida: a vez, são salvos no na variável &lt;code&gt;buf&lt;/code&gt; e valor da quantidade de &lt;em&gt;bytes&lt;/em&gt; lidos são salvos na variável &lt;code&gt;bytes_reads&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Após a execução, é feita uma verificação se ocorreu algum erro na leitura.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STDIN_FILENO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAX_BUF&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;bytes_writes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_writes&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error ao escrever no arquivo&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Erro na leitura do STDIN&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Função &lt;code&gt;write()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;write()&lt;/code&gt; escreve uma quantidade &lt;code&gt;n&lt;/code&gt; de &lt;em&gt;bytes&lt;/em&gt; provenientes de um buffer em um FD informado. &lt;/p&gt;

&lt;p&gt;Ela tem o seguinte protótipo:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ssize_t write(int fd, const void *buf, size_t count);&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;O primeiro argumento é o FD onde serão escritos os dados, o segundo é do ***&lt;strong&gt;&lt;em&gt;buffer&lt;/em&gt;&lt;/strong&gt;*** no qual serão provenientes e o terceiro é quantidade de **&lt;strong&gt;&lt;em&gt;bytes&lt;/em&gt;&lt;/strong&gt;** que serão escritos por vez.&lt;/p&gt;

&lt;p&gt;A função é disponibilizada pela biblioteca &lt;code&gt;&amp;lt;unistd.h&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Quanto ao retorno: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Para gravação, o valor de retorno é o número de bytes gravados. Ocorreu um erro se esse número não for igual ao número solicitado.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Referências: RITCHIE, Dennis M. et al. The C programming language. &lt;strong&gt;Bell Sys. Tech. J&lt;/strong&gt;, v. 57, n. 6, p. 1991-2019, 1978.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementação de uma versão simples do utilitário cat
&lt;/h2&gt;

&lt;p&gt;Escrita as breves notas acima, agora é vez de escrever sobre a implementação do utilitário &lt;code&gt;cat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nas primeiras linhas são escritas as inclusões das bibliotecas necessárias, a definição da constante referente à quantidade de ***&lt;strong&gt;&lt;em&gt;bytes&lt;/em&gt;&lt;/strong&gt;*** que serão lidos e escritos por vez e o protótipo das funções.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define MAX_BUF 1024
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="nf"&gt;ft_cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="nf"&gt;clear_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida tem o corpo da função &lt;code&gt;main()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;STDIN_FILENO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ft_cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;O_RDONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error opening the file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;ft_cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nela é declarada duas variáveis do tipo inteiro: &lt;code&gt;i&lt;/code&gt; e &lt;code&gt;fd&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Em seguida é verificado se foi informado arquivos para serem lidos ou não. Caso não tenham sido informados pelo usuário, o variável &lt;code&gt;fd&lt;/code&gt; recebe o FD referente ao &lt;code&gt;stdin&lt;/code&gt;, por meio da constante &lt;code&gt;STDIN_FILENO&lt;/code&gt;. Após, é chamada a &lt;code&gt;ft_cat(fd)&lt;/code&gt; passando o respectivo &lt;code&gt;fd&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Por outro lado, na situação do usuário tenha informado um ou mais arquivos; é atribuído o valor 1 para a variável &lt;code&gt;i&lt;/code&gt; e dado início ao loop, que será executado por enquanto &lt;code&gt;i&lt;/code&gt; for menor que o valor da variável &lt;code&gt;argc&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Para cada interação do &lt;em&gt;loop&lt;/em&gt;: Um arquivo é aberto por meio da função &lt;code&gt;open()&lt;/code&gt; e o seu respectivo FD é salvo na variável &lt;code&gt;fd&lt;/code&gt;; é feita uma verificação de erro e, se estiver tudo &lt;em&gt;ok&lt;/em&gt;, a função &lt;code&gt;ft_cat()&lt;/code&gt; é chamada tedndo o FD atual como parâmetro.&lt;/p&gt;

&lt;p&gt;Por fim, as últimas linhas de execução do loop é: fechar o arquivo após a execução da função &lt;code&gt;ft_cat()&lt;/code&gt; e o incremento da variável &lt;code&gt;i&lt;/code&gt; para acessar o próximo arquivo, se houver.  &lt;/p&gt;

&lt;p&gt;Antes de passar para a explicação da função f&lt;code&gt;t_cat()&lt;/code&gt;; apenas anotar aqui sobre a função &lt;code&gt;clear_buf()&lt;/code&gt;. Que tem a tarefa de limpar a memória de alguma &lt;em&gt;array&lt;/em&gt; recebida como parâmetro. &lt;br&gt;
Assim, evita que haja restos de dados no &lt;em&gt;buffer&lt;/em&gt;, principalmente quando estamos o utilizando no contexto do &lt;em&gt;loop&lt;/em&gt; e leitura e escrita.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="nf"&gt;clear_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;MAX_BUF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, as notas para função &lt;code&gt;ft_cat()&lt;/code&gt;. Segue o código da respectiva.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;    &lt;span class="nf"&gt;ft_cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;     &lt;span class="n"&gt;bytes_writes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt;    &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MAX_BUF&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;bytes_writes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;clear_buf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAX_BUF&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;bytes_writes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_writes&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;bytes_reads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error reading the file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes_reads&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Error reading the file&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ela recebe como parâmetro um inteiro que representa um FD de de onde os dados serão lidos. A escolha é pela opção, ao invés de receber o caminho de arquivo a ser lido, é pela possibilidade do FD referir tanto para arquivos, como também para outras fontes de da dados: tais como o &lt;code&gt;stdin&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;De início são declaradas três variáveis: duas do tipo inteiro e uma cadeia de caráteres com tamanho definido pela constante &lt;code&gt;MAX_BUF&lt;/code&gt;.  As variáveis &lt;code&gt;bytes_reads&lt;/code&gt; e &lt;code&gt;bytes_writes&lt;/code&gt; , como pelo nome dá para saber, serão onde armazenaremos os retornos das funções &lt;code&gt;read()&lt;/code&gt; e &lt;code&gt;write()&lt;/code&gt;. E a função &lt;code&gt;buf[]&lt;/code&gt; será onde salvaremos os dados lidos e a serem, posteriormente, escritos no &lt;code&gt;stdout&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Em seguida, são atribuídas as variáveis valores zero, com fim de evitar que haja dados remanescentes da memórias. &lt;/p&gt;

&lt;p&gt;A atividade de leitura e escrita é feita no contexto de um *&lt;strong&gt;&lt;em&gt;loop&lt;/em&gt;&lt;/strong&gt;* &lt;code&gt;while&lt;/code&gt;*&lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt;*&lt;/p&gt;

&lt;p&gt;O *&lt;strong&gt;&lt;em&gt;loop&lt;/em&gt;&lt;/strong&gt;* é executado por enquanto o retorno da chamada da função &lt;code&gt;read()&lt;/code&gt; for maior que zero. Na chamada da dessa função passamos, como parâmetro o FD atual da chamada da função &lt;code&gt;ft_cat()&lt;/code&gt; , o &lt;code&gt;buf&lt;/code&gt; onde os dados serão salvos e a quantidade de **&lt;strong&gt;&lt;em&gt;bytes&lt;/em&gt;&lt;/strong&gt;** que serão lidos por vez. &lt;/p&gt;

&lt;p&gt;No corpo do *&lt;strong&gt;&lt;em&gt;loop&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;, adicionamos o caractere de terminação na última posição do &lt;code&gt;buf&lt;/code&gt;. Após é feita a chamada da função &lt;code&gt;write()&lt;/code&gt; para escrever no &lt;code&gt;stdout&lt;/code&gt; os dados presentes no &lt;code&gt;buf&lt;/code&gt;.  Um verificação de erro é feita para checar se quantidade de *&lt;/em&gt;&lt;strong&gt;&lt;em&gt;bytes&lt;/em&gt;&lt;/strong&gt;** escritos é igual a quantidade a ser escrita. Caso haja alguma diferença, é disparado um erro. &lt;/p&gt;

&lt;p&gt;Por fim, encerrada a execução do &lt;code&gt;while&lt;/code&gt;, outra verificação de erro é feita relativa à chamada da função &lt;code&gt;read()&lt;/code&gt; . &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Bem, está foi uma implementação simples do utilitário &lt;code&gt;cat&lt;/code&gt;. Observando a proposta do desafio que apresentou restrições de recursos, o intuito com esta atividade é aprender a utilização das funções mais básicas de manipulação de entradas e saídas de dados na linguagem C. &lt;/p&gt;

&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://twobithistory.org/2018/11/12/cat.html"&gt;https://twobithistory.org/2018/11/12/cat.html&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cat_(Unix)"&gt;https://en.wikipedia.org/wiki/Cat_(Unix)&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://history-computer.com/understanding-cat-command-in-linux-with-examples/"&gt;https://history-computer.com/understanding-cat-command-in-linux-with-examples/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://austinedger.medium.com/unix-commands-lets-build-cat-59b8a91b9708"&gt;https://austinedger.medium.com/unix-commands-lets-build-cat-59b8a91b9708&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>braziliandevs</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>O que é o “Hoisting”?</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Sun, 24 Apr 2022 12:31:56 +0000</pubDate>
      <link>https://dev.to/pliniohr/o-que-e-o-hoisting-1ojm</link>
      <guid>https://dev.to/pliniohr/o-que-e-o-hoisting-1ojm</guid>
      <description>&lt;p&gt;Continuando os escritos pontuais da linguagem JavaScript, hoje vou escrever sobre o “&lt;em&gt;Hoisting&lt;/em&gt;”. &lt;/p&gt;

&lt;p&gt;Antes de continuar é importante avisar da necessidade de conhecer o conceito de escopos global e local. &lt;/p&gt;

&lt;p&gt;Na literatura é comum dizer que o &lt;em&gt;Hositing&lt;/em&gt; é um processo no qual as declarações das variáveis e das funções são movidas para o topo do código durante o processo de compilação/interpretação. A imagem a seguir tentar mostrar como seria sob essa visão:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---g0y5t6j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnxwfhgmy58i876etf0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---g0y5t6j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnxwfhgmy58i876etf0p.png" alt="Image description" width="558" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Na verdade, não é bem assim que ocorre, trata-se apenas de uma maneira didática de compreender o processo. &lt;/p&gt;

&lt;p&gt;De acordo com o MDN, “&lt;em&gt;as declarações de variável e função são colocadas na memória durante a fase de compilação, mas permanecem exatamente onde você as digitou no seu código.&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;Ou seja, todas as variáveis e funções com escopo global são alocadas na memória, sem que sejam retiradas das suas posições no código. &lt;/p&gt;

&lt;p&gt;É como se o compilador/interpretador mapeasse todas as declarações das funções e variáveis.&lt;/p&gt;

&lt;p&gt;O levantamento como dizemos acima não ocorre, como disse, é uma maneira didática de compreender o processo. &lt;/p&gt;

&lt;p&gt;Impera salientar que ocorre apenas com as funções e variáveis com escopo global. Declarações com escopo local não sofrem o “&lt;em&gt;Hoisting&lt;/em&gt;”. &lt;/p&gt;

&lt;p&gt;Vamos para um exemplo de código para ver suas implicações práticas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja que, apesar que a variável ‘a’ tenha sido declarada após o primeiro ‘console.log()’, o resultado na tela foi ‘&lt;em&gt;undefined&lt;/em&gt;’, ou seja, para ela apenas não foi definido um valor. &lt;/p&gt;

&lt;p&gt;Outro exemplo com ‘&lt;em&gt;let&lt;/em&gt;’:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ReferenceError: a is not defined&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora quando declaramos a variável por meio do ‘&lt;em&gt;let&lt;/em&gt;’ é retornado um erro de referência. É acusado que a variável não foi definida. &lt;/p&gt;

&lt;p&gt;Isso acontece em razão do escopo local de ‘&lt;em&gt;let&lt;/em&gt;’, assim, não sofre o &lt;em&gt;Hoisting&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Essa é a diferença, por meio do processo de &lt;em&gt;Hoisting&lt;/em&gt;, mesmo que a declaração seja posterior, o  compilador/interpretador já a conhece, e apenas devolve que não foi inicializado nenhum valor para ela. &lt;/p&gt;

&lt;p&gt;Por outro lado, quando a declaração tem natureza de escopo local. A sua chamada antes da declaração devolve um erro de referência: acusa-se que a variável ou função não foi declarada.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Diferenças entre var, let, e const na linguagem Javascript</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Sun, 03 Apr 2022 15:42:58 +0000</pubDate>
      <link>https://dev.to/pliniohr/diferencas-entre-var-let-e-const-na-linguagem-javascript-48k4</link>
      <guid>https://dev.to/pliniohr/diferencas-entre-var-let-e-const-na-linguagem-javascript-48k4</guid>
      <description>&lt;p&gt;No post anterior eu expliquei sobre o conceito de escopos na linguagem Javascript. Neste trarei breves notas sobre a diferença na forma como declaramos variáveis no Javascript. &lt;/p&gt;

&lt;p&gt;Qual é a diferença de declarar uma variável como &lt;em&gt;var&lt;/em&gt;, &lt;em&gt;let&lt;/em&gt; ou &lt;em&gt;const.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Quem já programa na linguagem a um bom tempo, a regra era iniciar uma variável com &lt;em&gt;var.&lt;/em&gt; Porém, após o ES2015 (ES6), novas formar surgiram, quais sejam: &lt;em&gt;let&lt;/em&gt; e &lt;em&gt;const.&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Variáveis declaradas com &lt;em&gt;var&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Um aspecto importante quando utilizamos &lt;em&gt;var&lt;/em&gt; é que ele tem escopo global e local (&lt;a href="https://pliniorb.hashnode.dev/diferencas-entre-escopos-no-javascript"&gt;aqui&lt;/a&gt;). Como vimos quando estava falando de escopo, é possível acessar uma variável inicializada fora do escopo que a esta invocando. &lt;/p&gt;

&lt;p&gt;Olha o exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Heliot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;pequi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Heliot&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;pequi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, quando chamamos a função &lt;em&gt;pequi()&lt;/em&gt;, ela consegue acessar o conteúdo da variável &lt;em&gt;nome&lt;/em&gt; e exibir o seu conteúdo. Isto se dá pela razão de possuir o escopo global, ou seja, ela pode ser utilizada em várias partes do nosso código.&lt;/p&gt;

&lt;p&gt;Impera anotar acerca da utilização de &lt;em&gt;var&lt;/em&gt; é o &lt;em&gt;hoisting&lt;/em&gt; realizado pela linguagem. Contudo, este assunto eu tratarei no próximo texto. &lt;/p&gt;

&lt;p&gt;Outro aspecto importante da utilização de &lt;em&gt;var&lt;/em&gt; é possibilidade de alterar o conteúdo da variável.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Heliot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;pequi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Larissa&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Larissa&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;pequi&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quando chamamos a função &lt;em&gt;pequi()&lt;/em&gt;, alteramos o valor da variável sem nenhum erro. Dado o seu escopo global de acessibilidade de leitura e modificação.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Variáveis declaradas com &lt;em&gt;let&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Let&lt;/em&gt; está sendo a forma preferida de declarar variáveis. Se diferencia de &lt;em&gt;var&lt;/em&gt; em razão do seu escopo ser de bloco e não global. &lt;/p&gt;

&lt;p&gt;O que é um bloco? Um bloco é um trecho de código iniciado e fechado por chaves “{}”. O que estiver nesse contexto é um bloco especifico. &lt;/p&gt;

&lt;p&gt;Quando iniciamos uma variável com &lt;em&gt;let&lt;/em&gt; em um bloco, sua acessibilidade se é limitada a este bloco. Vejamos um exemplo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ola&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Olá para todos!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ola&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Olá para todos!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ola&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ReferenceError: ola is not defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Veja que quando tentamos tentar acessar o conteúdo de &lt;em&gt;ola&lt;/em&gt; fora do bloco é retornado um erro de referência. &lt;/p&gt;

&lt;p&gt;Isso não acontece quando utilizamos &lt;em&gt;var&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Olha outro exemplo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ola&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Olá para todos!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ola&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Olá para todos!&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ola&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Olá para todos!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Já nesse exemplo foi possível acessar o conteúdo de &lt;em&gt;ola&lt;/em&gt;. Isto se dá pelo &lt;em&gt;hoisting,&lt;/em&gt; que explicarei no próximo texto. &lt;/p&gt;

&lt;p&gt;Está limitação de acessibilidade é a principal diferença entre declara com &lt;em&gt;var&lt;/em&gt; ou com &lt;em&gt;let.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Quando a possibilidade de sofrer alterações, &lt;em&gt;let&lt;/em&gt; permite que sejam realizadas. Veja:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Variáveis declaradas com &lt;em&gt;const&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;A caraterística marcante da utilização de &lt;em&gt;const&lt;/em&gt; é a sua imutabilidade. Quando declaramos variável com &lt;em&gt;const&lt;/em&gt; ela não poderá ser alterar ou redeclarada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;// TypeError: Assignment to constant variable.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, quando tentamos modificar o valor de &lt;em&gt;a&lt;/em&gt;, é retornado um erro de tipo, que impede a alteração da variável já declarada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Neste texto eu trouxe breves notas da diferença entre a utilização de &lt;em&gt;var&lt;/em&gt;, &lt;em&gt;let&lt;/em&gt; e &lt;em&gt;const.&lt;/em&gt; Sendo essas últimas introduzidas pelo ES2015 (ES6). &lt;/p&gt;

&lt;p&gt;Conhecer suas diferenças é importante na escrita diárias dos nossos códigos, para que sejam mais eficientes e com menos chances de provocarem &lt;em&gt;bugs.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Diferenças entre escopos no JavaScript</title>
      <dc:creator>Plínio Ribeiro</dc:creator>
      <pubDate>Fri, 01 Apr 2022 23:46:10 +0000</pubDate>
      <link>https://dev.to/pliniohr/diferencas-entre-escopos-no-javascript-3190</link>
      <guid>https://dev.to/pliniohr/diferencas-entre-escopos-no-javascript-3190</guid>
      <description>&lt;p&gt;Quando programamos em qualquer linguagem é importante entender conceitos da linguagem.  Neste texto vou trazer de forma breve o conceito de escopos na linguagem Javascript. &lt;/p&gt;

&lt;h3&gt;
  
  
  O que são escopos?
&lt;/h3&gt;

&lt;p&gt;Escopos diz respeito aos limites que permitem que uma variável pode ser acessada dentro do código. Ou seja, quem poderá acessar o seu conteúdo para ler ou alterar. &lt;/p&gt;

&lt;p&gt;No Javascript temos dois escopos: o escopo global e o escopo local. &lt;/p&gt;

&lt;p&gt;Grosso modo, o escopo global é relativo a todo o código, tem a sua acessibilidade a todo o fluxo de código, incluindo quando dentro de alguma função.&lt;/p&gt;

&lt;p&gt;Enquanto o escopo local é aquele declarando dentro de uma função. O limite de sua acessibilidade se restringe ao contexto “{}” da função no qual foi declarado. &lt;/p&gt;

&lt;p&gt;Vejamos um exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Charles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;obterIdade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Charles&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ReferenceError: idade is not defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A variável &lt;em&gt;nome&lt;/em&gt; está no escopo global e a variável &lt;em&gt;idade&lt;/em&gt; está no escopo local da função “&lt;em&gt;obterIdade&lt;/em&gt;”. &lt;/p&gt;

&lt;p&gt;Quando tentamos exibir o conteúdo delas, &lt;em&gt;nome&lt;/em&gt; é exibida normalmente, porém, para &lt;em&gt;idade,&lt;/em&gt; é retornando um erro de referência. Acusa-se que &lt;em&gt;idade&lt;/em&gt; não foi definida. &lt;/p&gt;

&lt;p&gt;Este erro acontece porque a variável &lt;em&gt;idade&lt;/em&gt; foi definida no escopo local da função “&lt;em&gt;obterIdade&lt;/em&gt;”, nesse contexto ela só pode ser acessada dentro do domínio local dessa função. É uma limitação à acessibilidade da variável em ralação ao código.&lt;/p&gt;

&lt;p&gt;Vejamos um outro exemplo, em que observamos a acessibilidade de uma variável declarada no escopo local por uma função.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Charles&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;obterIdade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;idade&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Charles&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idade&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 25&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;obterIdade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima é chamada a função &lt;em&gt;“obterIdade”&lt;/em&gt; para que seja exibido o conteúdo das variáveis &lt;em&gt;nome&lt;/em&gt; e &lt;em&gt;idade.&lt;/em&gt; Nesse exemplo, a variável &lt;em&gt;nome&lt;/em&gt; é impresso mesmo que declarada fora do escopo da função em que se encontra. &lt;/p&gt;

&lt;p&gt;Isso acontece, porque ela foi declarada no escopo local, que permite que a variável seja acessada quando no âmbito do escopo global ou local de alguma função. &lt;/p&gt;

&lt;p&gt;Assim, quando dizemos que a variável está declarada no escopo global, significa que sua acessibilidade é para todo o código. E quando referimos ao escopo local, é que ela só acessível no contexto da função que está localizada.  &lt;/p&gt;

&lt;p&gt;Compreender o conceito de escopos é importante, pois permite tenhamos conhecimento da capacidade de acesso, mutabilidade e o controle sobre código que estamos escrevendo.&lt;/p&gt;

&lt;p&gt;Nota que aqui me restringi apenas a tratar sobre escopos na linguagem Javascript, não me adentrei na explicação de &lt;em&gt;var&lt;/em&gt;, &lt;em&gt;let&lt;/em&gt; e &lt;em&gt;const&lt;/em&gt;. Em outro momento explicarei as diferenças entre essas formas de declarar uma variável, bem como o processo de &lt;em&gt;hoisting&lt;/em&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
