sábado, 12 de dezembro de 2009

Dividir para conquistar! Parte II (local x global)

Continuando o que começamos aqui, hoje, como prometido, vamos falar sobre o 'comportamento' das variáveis quando usamos modularidade.

Vamos brincar de esconde-esconde?
Existe um conceito em C chamado de escopo. Já procurei uma definição literal para a esta palavra e não encontrei. Então como costumo fazer, vamos à pratica.


#include "stdio.h"
#include "stdlib.h"
 
int b = 5;
 
int main(){
 int a, c;
 
 a = 6;
 c = a + b;
 printf("\na = %d, b = %d e c = %d.\n",a,b,c);
 {
    int a, c;
 
    a = 15;
    c = a + b;
    printf("\na = %d, b = %d e c = %d.\n",a,b,c);
    b = c;
 }
 c = a + b;
 b = 2 * a;
 printf("\na = %d, b = %d e c = %d.\n",a,b,c);
 system("pause");
}


Observe o código acima. Aliás, não só observe, fique curioso e coloque ele para rodar no seu micro. Já colocou? Viu a saída?
Vamos entender.
A princípio só vemos declarações de variáveis e atribuições. Mas na linha 12 vemos algo diferente (que acredito não ser comum em códigos fonte profissionais, mas funciona rsrs). Como sabemos, as {} separam um bloco de comandos, geralmente estes blocos estão ligados a instruções de decisão e repetição (if, while, for), e também a funções; mas elas também funcionam sozinhas, como mostrado neste código.
Observe os comandos das linhas 7 e 13, e das linhas 10 e 16. São os mesmos comandos, só as variáveis envolvidas que são diferentes, apesar de terem os mesmos nomes.
Como já vimos, aqui, os nomes das variáveis são 'etiquetas' (rótulos) que identificam endereços de memória. Apesar de estarem usando a mesma 'etiqueta', os endereços das variáveis declaradas nas linhas 7 e 13 são diferentes. O C não se confunde por causa das {}.
Quando são feitas as operações dentro das {}, são usadas as variáveis declaradas dentro das {}. Assim o valor da variável a que é impresso no printf da linha 11 é um, e o da linha 17 outro. O valor de a impresso pelo printf na linha 21 é o mesmo impresso pelo printf da linha 11, pois é a mesma variável. A atribuição da linha 15 não altera o seu valor, já que ela altera outra variável, que por acaso (neste caso, propositalmente) tem o mesmo nome. Dizemos que as duas variáveis tem escopo diferente.
Quando se trata de funções, dizemos que a variável declarada entre as {} do bloco de comandos de uma função é uma variável local da função. Ela fica 'escondida' dentro das {}, e para todas as outras funções é como se ela nem existisse.
Lembra do que já falamos sobre funções. Uma função é uma 'caixa preta', não precisamos saber como ela faz as coisas, apenas os parâmetros que ela precisa e o retorno que fornece (isto quando ela precisa de parâmetros e dá algum retorno). Ela pode usar uma série de variáveis, mas não precisamos tomar conhecimento da existência delas.
Em oposição a isto, existe um tipo de variável chamada de global. Temos um exemplo de uma variável assim na linha 4 do nosso código exemplo acima: é a variável b.
Ela é declarada e inicializada fora de qualquer bloco, fora até mesmo da função main. Observe que utilizamos o valor de b para fazer a operação de soma da linha 10, e usamos este mesmo valor na soma da linha 16, que está dentro das {}.
Por ser global, esta variável é 'vista' por qualquer parte do programa (funções, inclusive), e também pode ser alterada em qualquer parte do programa.
Fazemos uma alteraçao no valor da variável b na linha 18, que está dentro das {}, e este novo valor de b é usado na soma que é realizada na linha 20, fora das {}, e depois alterado na linha 21.
Até o próximo post.

Um comentário:

  1. olá, em primeiro lugar, parabéns por ter um blogo tão útil e informativo!!!
    preciso de sua ajuda! como faço para criar uma função que preencha e some vetores?

    ou não tem como fazer isso com função?
    abraço!!!

    ResponderExcluir