AULA 13 - Microcontroladores - Técnico: mudanças entre as edições

De IFSC
Ir para navegação Ir para pesquisar
imported>Fargoud
(Criou página com '=FUNÇÕES= Uma função é uma unidade de código de programa autônoma projetada para cumprir uma tarefa particular. Funções permitem grandes tarela, fas de computação...')
 
imported>Fargoud
Linha 1: Linha 1:
=FUNÇÕES=
=FUNÇÕES=


Uma função é uma unidade de código de programa autônoma projetada para cumprir uma tarefa particular.


Uma função é uma unidade de código de programa autônoma projetada para cumprir uma tarefa particular. Funções permitem grandes tarela, fas de computação em tarefas menores e permitem às pessoas trabalharem sobre o que outras já fizeram, ao invés de partir do nada.
Funções permitem que grandes tarefas de computação sejam quebradas em tarefas menores e permitem às pessoas trabalharem sobre o que outras já fizeram, ao invés de partir do nada.
A linguagem C em si, não possui funções pré-definidas. Todas as funções utilizadas em C foram projetadas pelos próprios usuários e algumas mais usadas já foram incorporadas às bibliotecas de alguns compiladores. Um exemplo de função em C é printf(), que realiza saídas dos programas sem que o usuário precise preocupar-se como isto é feito, pois alguém já fez isto e vendeu sua idéia aos outros usuários.
 
A principal razão da existência de funções é impedir que o programador tenha de escrever o mesmo código repetidas vezes.  
A linguagem C em si, não possui funções pré-definidas.  
  As funções em C são utilizadas como funções (retornam valores; podem ser chamadas de dentro de uma expressão e não recebem parâmetros) e subrotinas ( não retornam valores; são chamadas por um comando CALL e recebem parâmetros) das outras linguagens. No entanto, não pode haver aninhamento de uma função dentro de outras funções. Cada bloco de um programa em C é uma e somente uma função.
 
Sintaxe:
Todas as funções utilizadas em C foram projetadas pelos próprios usuários e algumas mais usadas já foram incorporadas às bibliotecas de alguns compiladores.  
 
Um exemplo de função em C é ''printf()'', que realiza saídas dos programas sem que o usuário precise preocupar-se como isto é feito, pois alguém já fez isto e vendeu sua ideia aos outros usuários.
 
A principal razão da existência de funções é impedir que o programador tenha de escrever o mesmo código repetidas vezes.
 
   
As funções em C são utilizadas como '''funções''' (retornam valores; podem ser chamadas de dentro de uma expressão e não recebem parâmetros) e como '''subrotinas''' ( não retornam valores; são chamadas por um comando CALL e recebem parâmetros) das outras linguagens.  
 
No entanto, não pode haver aninhamento de uma função dentro de outras funções.  
 
Cada bloco de um programa em C é uma e somente uma função.
 
==Sintaxe:==
            
            
         tipo  nome_da_função(declaração de parâmetros formais)
         tipo  nome_da_função(declaração de parâmetros formais)
Linha 14: Linha 28:


Onde:
Onde:
tipo - tipo do valor de retorno da função. Se uma função não retornar nenhum valor deve-se usar o tipo "void", pois, por default, as funções em C/C++ retornam um inteiro. Ex: "void main(void)".
* tipo - tipo do valor de retorno da função. Se uma função não retornar nenhum valor deve-se usar o tipo "void", pois, por default, as funções em C/C++ retornam um inteiro. Ex: "void main(void)".
nome_da_função - nome da função. Como qualquer identificador em C, o nome não pode ser uma palavra reservada da linguagem (a não ser no caso da função main()), pode ser composto por letras, números e o caractere de sublinhado ( também chamado underscore: "_"), mas deve iniciar com uma letra ou com o underscore.
* nome_da_função - nome da função. Como qualquer identificador em C, o nome não pode ser uma palavra reservada da linguagem (a não ser no caso da função main()), pode ser composto por letras, números e o caractere de sublinhado ( também chamado underscore: "_"), mas deve iniciar com uma letra ou com o underscore.
declaração de parâmetros formais - neste campo são declarados os parâmetros que a função recebe. Se a função não receber nenhum parâmetro, em alguns compiladores exige-se a utilização de "void", em outros, basta a omissão (quando então os parâmetros são assumidos como inteiros). Os nomes dos parâmetros devem ser separados por vírgulas. Ex: " int sqrt(x, y)".
* declaração de parâmetros formais - neste campo são declarados os parâmetros que a função recebe. Se a função não receber nenhum parâmetro, em alguns compiladores exige-se a utilização de "void", em outros, basta a omissão (quando então os parâmetros são assumidos como inteiros). Os nomes dos parâmetros devem ser separados por vírgulas. Ex: " int sqrt(x, y)".
Em alguns compiladores (como é o caso do Turbo C),  a declaração das variáveis utilizadas na função deve, obrigatoriamente, preceder quaisquer comandos da função. Deve vir logo depois do caractere de abre-chaves ("{"). Existem outros compiladores que aceitam esta declaração em qualquer linha da função, desde que precedendo a utilização das mesmas.
 
comandos - Além dos comandos do corpo da função, este bloco pode conter o comando return que  finaliza a execução da função e retorna o valor para a expressão que a chamou. Caso não haja "return", este será assumido quando o compilador encontrar o caractere de fecha-chaves ("}") e o valor retornado será indefinido.
Em alguns compiladores,  a declaração das variáveis utilizadas na função deve, obrigatoriamente, preceder quaisquer comandos da função.  
 
Deve vir logo depois do caractere de abre-chaves ("{").  
 
Existem outros compiladores que aceitam esta declaração em qualquer linha da função, desde que precedendo a utilização das mesmas.
 
* comandos - Além dos comandos do corpo da função, este bloco pode conter o comando return que  finaliza a execução da função e retorna o valor para a expressão que a chamou. Caso não haja "return", este será assumido quando o compilador encontrar o caractere de fecha-chaves ("}") e o valor retornado será indefinido.


Ex:
Ex:
Linha 27: Linha 47:
     }   
     }   


Exercício:  
===Exercício: ===
Escreva a função que recebe, calcula e devolve a média de 4 valores.
Escreva a função que recebe, calcula e devolve a média de 4 valores.


Linha 33: Linha 53:
==CHAMADA DA FUNÇÃO==
==CHAMADA DA FUNÇÃO==


Vimos até agora, como é a sintaxe da execução do corpo de uma função chamada em um expressão. Mas qual é a sintaxe da chamada de uma função? Seja numa expressão, ou não, a sintaxe é:
Vimos até agora, como é a sintaxe da execução do corpo de uma função chamada em um expressão.  
 
Mas qual é a sintaxe da chamada de uma função? Seja numa expressão, ou não, a sintaxe é:


         nome_da_função(argumentos);
         nome_da_função(argumentos);


Na chamada de função em C não se utiliza CALL. Note que o que diferencia a chamada de uma função, da declaração da mesma é a utilização do ponto-e-vírgula (";"). Os argumentos são valores passados para a função. Quando não houver argumentos a serem passados, deixa-se este espaço em branco.
Na chamada de função em C não se utiliza CALL.  
Ex:
 
   somaum(5)                                             ® Retorna o valor 6
Note que o que diferencia a chamada de uma função, da declaração da mesma é a utilização do ponto-e-vírgula (";").  
   maior = acha_num_maior(4,7,2,5);               ® Retorna o valor 7 para a variável maior.
 
Os argumentos são valores passados para a função.  
 
Quando não houver argumentos a serem passados, deixa-se este espaço em branco.
 
'''Ex:'''
   somaum(5)                                     -> Retorna o valor 6
   maior = acha_num_maior(4,7,2,5);             -> Retorna o valor 7 para a variável maior.




Linha 46: Linha 75:


Argumento é o valor passado para uma função.
Argumento é o valor passado para uma função.
Parâmetro (Formal) é a variável que recebe valor do argumento.
Parâmetro (Formal) é a variável que recebe valor do argumento.
Ex:
 
'''Ex:'''
   #include <stdio.h>
   #include <stdio.h>
mult(int,int);
  mult(int,int); //protótipo da função mult()
void main(void)
  //corpo da função main():
    {  int a=4, b=5;
  void main(void)
        printf(" O valor da multiplicação de %d por %d é  %d\n", a, b, mult(a,b));  
  {  int a=4, b=5;
   }
      printf(" O valor da multiplicação de %d por %d é  %d\n", a, b, mult(a,b));  
  }
  //corpo da função mult():
  mult(int x, int y)
  {  int resultado;
      resultado = x * y;
      return resultado;
  }   
    
Normalmente, C utiliza passagem de parâmetros "por valor" para funções.
 
Isto é, os argumentos recebem cópias dos valores das variáveis na expressão.
 
Temos isto ilustrado no exemplo acima.
 
Quando a função ''mult()'', recebe os argumentos a e b, na verdade apenas cópias dos valores de a e b são enviados para a função ''mult()''.
 
Em resumo, as variáveis a e b não tem seus valores modificados após terem sido utilizadas como argumentos de uma função.
 
 
Se deseja-se que a própria variável seja passada para a função que vai modificar seu valor utilizamos a passagem '''"por referência"'''.
 
Neste caso, o argumento recebe o endereço de memória da variável e a função chamada modifica o conteúdo deste endereço diretamente.
 
Para passar valores por referência, utiliza-se os operadores "&"  e "*":


    mult(int x, int y)
  &  - " o endereço de "  - endereço da variável
    { int resultado;
*  - " no endereço de" - o que está contido no endereço da variável.
        resultado = x * y;
        return resultado;
    }   
 
Normalmente, C utiliza passagem de parâmetros "por valor" para funções. Isto é, os argumentos recebem cópias dos valores das variáveis na expressão. Temos isto ilustrado no exemplo acima. Quando a função mult(), recebe os argumentos a e b, na verdade apenas cópias dos valores de a e b são enviados para a função mult(). Em resumo, as variáveis a e b não tem seus valores modificados após terem sido utilizadas como argumentos de uma função.
Se deseja-se que a própria variável seja passada para a função que vai modificar seu valor utilizamos a passagem "por referência". Neste caso, o argumento recebe o endereço de memória da variável e a função chamada modifica o conteúdo deste endereço diretamente. Para passar valores por referência, utiliza-se os operadores "&"  e "*":
&  - " o endereço de "  - endereço da variável
*  - " no endereço de" - o que está contido no endereço da variável.


Ex:
'''Ex:'''
   int saida = 5;
   int saida = 5;
      ...
  ...
      incrementa(&saida);
  incrementa(&saida);
      ...
  ...
      incrementa(int *numentra)        /* numentra contém o endereço e não o valor de saida  */
  incrementa(int *numentra)        /* numentra contém o endereço e não o valor de saida  */
/* conteúdo do endereço numentra é do tipo int */
  /* conteúdo do endereço numentra é do tipo int */
      {  (* numentra)++;              /* incrementa o conteúdo de numentra  */
  {  (* numentra)++;              /* incrementa o conteúdo de numentra  */
        return;
      return;
      }                                       ® No final da função incrementa(), saida tem o valor 6  
  }                                 -> No final da função incrementa(), saida tem o valor 6  


==VALORES DE RETORNO==
==VALORES DE RETORNO==


Quando o tipo de valor de retorno da função não é especificado, por default a função vai retornar um valor inteiro.
Quando o tipo de valor de retorno da função não é especificado, por default a função vai retornar um valor inteiro.
Quando a função deve retornar um tipo que não o int, é necessário declarar-se o mesmo.
Quando a função deve retornar um tipo que não o int, é necessário declarar-se o mesmo.
Quando a função não retorna nada, no caso de compiladores C ANSI, o tipo deve ser void.
Quando a função não retorna nada, no caso de compiladores C ANSI, o tipo deve ser void.


==ESCOPO DE VARIÁVEIS==
==ESCOPO DE VARIÁVEIS==


Um programa em C é um conjunto de uma ou mais funções, sendo que uma destas funções é a principal (main()), que será a primeira a ser executada. Como saber a que função pertence determinada variável, como seu valor muda de função para função e em qual(is) função(ões) ela existe?
Um programa em C é um conjunto de uma ou mais funções, sendo que uma destas funções é a principal (main()), que será a primeira a ser executada.  
 
Como saber a que função pertence determinada variável, como seu valor muda de função para função e em qual(is) função(ões) ela existe?


===Variáveis Locais ou Automáticas===
===Variáveis Locais ou Automáticas===


São todas as variáveis declaradas dentro de uma função. Como só existem enquanto a função estiver sendo executada, são criadas quando tal função é chamada e destruídas quando termina a execução desta. Parâmetros formais são variáveis locais.
São todas as variáveis declaradas dentro de uma função.  
 
Como só existem enquanto a função estiver sendo executada, são criadas quando tal função é chamada e destruídas quando termina a execução desta.  
 
Parâmetros formais são sempre variáveis locais.
 
Somente podem ser referenciadas pela função onde foram declaradas e seus valores se perdem entre chamadas da função.
Somente podem ser referenciadas pela função onde foram declaradas e seus valores se perdem entre chamadas da função.
Ex:
 
 
'''Ex:'''
       void func1(void)
       void func1(void)
       {  int x;              ® O x da func1() e o x da func2() são duas variáveis diferentes, armaze-
       {  int x;              ® O x da func1() e o x da func2() são duas variáveis diferentes, armaze-
Linha 97: Linha 155:
       void func2(void)        apesar do mesmo nome.
       void func2(void)        apesar do mesmo nome.
       { int x;                   
       { int x;                   
         x = -199;      }  
         x = -199;      }  
Uma variável local deve ser declarada no início da função (antes de qualquer comando), por motivos de clareza e organização do código e porque alguns compiladores assim o exigem. Existem compiladores, no entanto, que permitem que a declaração seja feita em qualquer ponto do corpo da função, desde que antes da utilização da variável.
 
Uma variável local deve ser declarada no início da função (antes de qualquer comando), por motivos de clareza e organização do código e porque alguns compiladores assim o exigem.  
 
Existem compiladores, no entanto, que permitem que a declaração seja feita em qualquer ponto do corpo da função, desde que antes da utilização da variável.


===Variáveis Globais===
===Variáveis Globais===


São variáveis declaradas e/ou definidas fora de qualquer função do programa. Podem ser acessadas por qualquer função do arquivo e seus valores existem durante toda a execução do programa. Também por motivos de clareza convenciona-se declará-las no início do programa, após os comandos do pré-processador e das declarações de protótipos de funções.
São variáveis declaradas e/ou definidas fora de qualquer função do programa.  
Ex:
 
Podem ser acessadas por qualquer função do arquivo e seus valores existem durante toda a execução do programa.  
 
Também por motivos de clareza convenciona-se declará-las no início do programa, após os comandos do pré-processador e das declarações de protótipos de funções.
 
 
'''Ex:'''
     ...
     ...
       int conta;                /* conta é global  */
       int conta;                /* conta é global  */
Linha 120: Linha 188:
===Variáveis externas===
===Variáveis externas===
                  
                  
Um programa em C pode ser composto  por um ou mais arquivos-fonte, compilados separadamente e posteriormente linkados, gerando um arquivo executável. Como as várias funções do programa estarão distribuídas pelos arquivos-fonte, variáveis globais de um arquivo não serão reconhecidas por outro, a menos que estas variáveis sejam declaradas como externas. A variável externa deve ser definida em somente um dos arquivos-fonte e em quaisquer outros arquivos deve ser referenciada mediante a declaração com a seguinte sintaxe:
Um programa em C pode ser composto  por um ou mais arquivos-fonte, compilados separadamente e posteriormente linkados, gerando um arquivo executável.  
 
Como as várias funções do programa estarão distribuídas pelos arquivos-fonte, variáveis globais de um arquivo não serão reconhecidas por outro, a menos que estas variáveis sejam declaradas como externas.  
 
A variável externa deve ser definida em somente um dos arquivos-fonte e em quaisquer outros arquivos deve ser referenciada mediante a declaração com a seguinte sintaxe:


     extern  tipo_var  nome_var;
     extern  tipo_var  nome_var;


onde tipo_var é o tipo da variável e nome_var, o nome desta.
onde tipo_var é o tipo da variável e nome_var, o nome desta.
Ex:
 
              Arquivo 1                                          Arquivo 2
'''Ex:'''
           int x, y;                                                           extern int x, y;
          '''Arquivo 1'''                                         '''Arquivo 2'''
             char ch;                                                             extern char ch;
           int x, y;                                               extern int x, y;
             void main(void)                                                 func23()
             char ch;                                               extern char ch;
             { ...  }                                                                 {  x = y/10;
             void main(void)                                       func23()
             func1()                                                               }
             { ...  }                                               {  x = y/10;
             {    x = 123;                                                       func24()
             func1()                                                     }
             ...    }                                                               {  y = 10; }  
             {    x = 123;                                         func24()
             ...    }                                               {  y = 10; }  


===Variáveis Estáticas===
===Variáveis Estáticas===


São variáveis reconhecidas e permanentes apenas dentro dos arquivos-fonte ou funções onde foram declaradas. Uma variável estática mantém seus valores entre chamadas da função o que é muito útil quando se quer escrever funções generalizadas (sem o uso de variáveis globais) e biblioteca de funções. A sintaxe é:
São variáveis reconhecidas e permanentes apenas dentro dos arquivos-fonte ou funções onde foram declaradas.  
 
Uma variável estática mantém seus valores entre chamadas da função o que é muito útil quando se quer escrever funções generalizadas (sem o uso de variáveis globais) e biblioteca de funções.  
 
A sintaxe é:


             static tipo_var  nome_var;
             static tipo_var  nome_var;


onde tipo_var é o tipo da variável e nome_var, o nome desta.
onde tipo_var é o tipo da variável e nome_var, o nome desta.
Ex:
Ex:
           static int rand(void)
           static int rand(void)
Linha 164: Linha 242:
===Variáveis Registradores===
===Variáveis Registradores===


Uma variável declarada com o modificador register indica ao compilador para utilizar um registrador da CPU, ao invés de alocar memória para a variável. Variáveis armazenadas em registradores são acessadas muito mais rápido que as armazenadas em memória, o que aumenta muito a velocidade de processamento. Se o número de variáveis designadas como register exceder o número disponível de registradores da máquina, então o excesso será tratado como variáveis automáticas.
Uma variável declarada com o modificador register indica ao compilador para utilizar um registrador da CPU, ao invés de alocar memória para a variável.  
 
Variáveis armazenadas em registradores são acessadas muito mais rápido que as armazenadas em memória, o que aumenta muito a velocidade de processamento.  
 
Se o número de variáveis designadas como register exceder o número disponível de registradores da máquina, então o excesso será tratado como variáveis automáticas.
 
 
Variáveis registradores não podem ser globais e geralmente aplicam-se aos tipos int e char.
Variáveis registradores não podem ser globais e geralmente aplicam-se aos tipos int e char.
Obs: Existem programadores que costumam colocar variáveis contadoras em registradores, para tornar o processamento o mais rápido possível.
Obs: Existem programadores que costumam colocar variáveis contadoras em registradores, para tornar o processamento o mais rápido possível.
Ex:


/************************************************/
// Este programa mostra a diferença que uma variável register
// pode fazer na velocidade de execucao de um programa
/************************************************/
#include <stdio.h>
#include <time.h>
unsigned int i;  // variável não-register
unsigned int delay;


void main(void)
'''Ex:'''
{  register unsigned int j;
 
/************************************************/
// Este programa mostra a diferença que uma variável register
// pode fazer na velocidade de execucao de um programa
/************************************************/
#include <stdio.h>
#include <time.h>
unsigned int i;  // variável não-register
unsigned int delay;
void main(void)
{  register unsigned int j;
     long t;
     long t;
     t = time('\0');
     t = time('\0');
Linha 185: Linha 272:
       for(i = 0; i< 64000; i++) ;
       for(i = 0; i< 64000; i++) ;
     printf("tempo de loop não register: %d \n", time('\0')-t);
     printf("tempo de loop não register: %d \n", time('\0')-t);
  getch( );
    getch( );
     t = time('\0');
     t = time('\0');
     for(delay = 0; delay < 50000; delay++)
     for(delay = 0; delay < 50000; delay++)

Edição das 15h58min de 16 de novembro de 2016

FUNÇÕES

Uma função é uma unidade de código de programa autônoma projetada para cumprir uma tarefa particular.

Funções permitem que grandes tarefas de computação sejam quebradas em tarefas menores e permitem às pessoas trabalharem sobre o que outras já fizeram, ao invés de partir do nada.

A linguagem C em si, não possui funções pré-definidas.

Todas as funções utilizadas em C foram projetadas pelos próprios usuários e algumas mais usadas já foram incorporadas às bibliotecas de alguns compiladores.

Um exemplo de função em C é printf(), que realiza saídas dos programas sem que o usuário precise preocupar-se como isto é feito, pois alguém já fez isto e vendeu sua ideia aos outros usuários.

A principal razão da existência de funções é impedir que o programador tenha de escrever o mesmo código repetidas vezes.


As funções em C são utilizadas como funções (retornam valores; podem ser chamadas de dentro de uma expressão e não recebem parâmetros) e como subrotinas ( não retornam valores; são chamadas por um comando CALL e recebem parâmetros) das outras linguagens.

No entanto, não pode haver aninhamento de uma função dentro de outras funções.

Cada bloco de um programa em C é uma e somente uma função.

Sintaxe:

        tipo  nome_da_função(declaração de parâmetros formais)
        {     declaração de variáveis
               comandos
        }

Onde:

  • tipo - tipo do valor de retorno da função. Se uma função não retornar nenhum valor deve-se usar o tipo "void", pois, por default, as funções em C/C++ retornam um inteiro. Ex: "void main(void)".
  • nome_da_função - nome da função. Como qualquer identificador em C, o nome não pode ser uma palavra reservada da linguagem (a não ser no caso da função main()), pode ser composto por letras, números e o caractere de sublinhado ( também chamado underscore: "_"), mas deve iniciar com uma letra ou com o underscore.
  • declaração de parâmetros formais - neste campo são declarados os parâmetros que a função recebe. Se a função não receber nenhum parâmetro, em alguns compiladores exige-se a utilização de "void", em outros, basta a omissão (quando então os parâmetros são assumidos como inteiros). Os nomes dos parâmetros devem ser separados por vírgulas. Ex: " int sqrt(x, y)".

Em alguns compiladores, a declaração das variáveis utilizadas na função deve, obrigatoriamente, preceder quaisquer comandos da função.

Deve vir logo depois do caractere de abre-chaves ("{").

Existem outros compiladores que aceitam esta declaração em qualquer linha da função, desde que precedendo a utilização das mesmas.

  • comandos - Além dos comandos do corpo da função, este bloco pode conter o comando return que finaliza a execução da função e retorna o valor para a expressão que a chamou. Caso não haja "return", este será assumido quando o compilador encontrar o caractere de fecha-chaves ("}") e o valor retornado será indefinido.

Ex:

    somaum ( int  numentra)
    { int numsai;
       numsai = numentra + 1;
       return numsai;
    }  

Exercício:

Escreva a função que recebe, calcula e devolve a média de 4 valores.


CHAMADA DA FUNÇÃO

Vimos até agora, como é a sintaxe da execução do corpo de uma função chamada em um expressão.

Mas qual é a sintaxe da chamada de uma função? Seja numa expressão, ou não, a sintaxe é:

       nome_da_função(argumentos);

Na chamada de função em C não se utiliza CALL.

Note que o que diferencia a chamada de uma função, da declaração da mesma é a utilização do ponto-e-vírgula (";").

Os argumentos são valores passados para a função.

Quando não houver argumentos a serem passados, deixa-se este espaço em branco.

Ex:

  somaum(5)                                     -> Retorna o valor 6
  maior = acha_num_maior(4,7,2,5);              -> Retorna o valor 7 para a variável maior.


PARÂMETROS E ARGUMENTOS

Argumento é o valor passado para uma função.

Parâmetro (Formal) é a variável que recebe valor do argumento.

Ex:

  #include <stdio.h>
  mult(int,int);  //protótipo da função mult()
  //corpo da função main():
  void main(void)
  {   int a=4, b=5;
      printf(" O valor da multiplicação de %d por %d é  %d\n", a, b, mult(a,b)); 
  }
  //corpo da função mult():
  mult(int x, int y) 
  {  int resultado;
     resultado = x * y;
     return resultado;
  }     
 

Normalmente, C utiliza passagem de parâmetros "por valor" para funções.

Isto é, os argumentos recebem cópias dos valores das variáveis na expressão.

Temos isto ilustrado no exemplo acima.

Quando a função mult(), recebe os argumentos a e b, na verdade apenas cópias dos valores de a e b são enviados para a função mult().

Em resumo, as variáveis a e b não tem seus valores modificados após terem sido utilizadas como argumentos de uma função.


Se deseja-se que a própria variável seja passada para a função que vai modificar seu valor utilizamos a passagem "por referência".

Neste caso, o argumento recebe o endereço de memória da variável e a função chamada modifica o conteúdo deste endereço diretamente.

Para passar valores por referência, utiliza-se os operadores "&" e "*":

&  - " o endereço de "  - endereço da variável
*   - " no endereço de" - o que está contido no endereço da variável.

Ex:

  int saida = 5;
  ...
  incrementa(&saida);
  ...
  incrementa(int *numentra)        /* numentra contém o endereço e não o valor de saida  */
 /* conteúdo do endereço numentra é do tipo int */
 {  (* numentra)++;               /* incrementa o conteúdo de numentra  */
     return;
 }                                  -> No final da função incrementa(), saida tem o valor 6 

VALORES DE RETORNO

Quando o tipo de valor de retorno da função não é especificado, por default a função vai retornar um valor inteiro.

Quando a função deve retornar um tipo que não o int, é necessário declarar-se o mesmo.

Quando a função não retorna nada, no caso de compiladores C ANSI, o tipo deve ser void.

ESCOPO DE VARIÁVEIS

Um programa em C é um conjunto de uma ou mais funções, sendo que uma destas funções é a principal (main()), que será a primeira a ser executada.

Como saber a que função pertence determinada variável, como seu valor muda de função para função e em qual(is) função(ões) ela existe?

Variáveis Locais ou Automáticas

São todas as variáveis declaradas dentro de uma função.

Como só existem enquanto a função estiver sendo executada, são criadas quando tal função é chamada e destruídas quando termina a execução desta.

Parâmetros formais são sempre variáveis locais.

Somente podem ser referenciadas pela função onde foram declaradas e seus valores se perdem entre chamadas da função.


Ex:

     void func1(void)
      {  int x;               ® O x da func1() e o x da func2() são duas variáveis diferentes, armaze-
          x = 10; }               nadas em posições de memória diferentes, com conteúdos diferentes,
      void func2(void)        apesar do mesmo nome.
      { int x;                   
        x = -199;       }   


Uma variável local deve ser declarada no início da função (antes de qualquer comando), por motivos de clareza e organização do código e porque alguns compiladores assim o exigem.

Existem compiladores, no entanto, que permitem que a declaração seja feita em qualquer ponto do corpo da função, desde que antes da utilização da variável.

Variáveis Globais

São variáveis declaradas e/ou definidas fora de qualquer função do programa.

Podem ser acessadas por qualquer função do arquivo e seus valores existem durante toda a execução do programa.

Também por motivos de clareza convenciona-se declará-las no início do programa, após os comandos do pré-processador e das declarações de protótipos de funções.


Ex:

   ...
     int conta;                /* conta é global  */
     void main(void)
     {    conta = mul(10,123);
     ...  }
    func1()
    { int temp;
      temp = conta;
    ...   }
    func2()
    {   int conta;
        conta = 10;      /* esta conta é local   */
    ...   }     

Variáveis externas

Um programa em C pode ser composto por um ou mais arquivos-fonte, compilados separadamente e posteriormente linkados, gerando um arquivo executável.

Como as várias funções do programa estarão distribuídas pelos arquivos-fonte, variáveis globais de um arquivo não serão reconhecidas por outro, a menos que estas variáveis sejam declaradas como externas.

A variável externa deve ser definida em somente um dos arquivos-fonte e em quaisquer outros arquivos deve ser referenciada mediante a declaração com a seguinte sintaxe:

    extern  tipo_var  nome_var;

onde tipo_var é o tipo da variável e nome_var, o nome desta.

Ex:

          Arquivo 1                                          Arquivo 2
          int x, y;                                                extern int x, y;
            char ch;                                               extern char ch;
            void main(void)                                        func23()
            { ...  }                                               {   x = y/10;
            func1()                                                     }
            {     x = 123;                                         func24()
            ...    }                                               {  y = 10; } 

Variáveis Estáticas

São variáveis reconhecidas e permanentes apenas dentro dos arquivos-fonte ou funções onde foram declaradas.

Uma variável estática mantém seus valores entre chamadas da função o que é muito útil quando se quer escrever funções generalizadas (sem o uso de variáveis globais) e biblioteca de funções.

A sintaxe é:

            static tipo_var  nome_var;

onde tipo_var é o tipo da variável e nome_var, o nome desta.

Ex:

          static int rand(void)
            {     static int semente = 1;
                  semente = (semente * 25173+ 13849)%65536;     /* formula magica  */
                  return (semente);
             }    
             ...
             void main(void)
             {    int c;
                  for(c=1; c<=5; c++)
                       printf("Número randômico: %d \n", rand());
             }
A saída deste programa será:
              Número randômico:  -26514
              Número randômico:  -4449
              Número randômico:  20196
              Número randômico:  -20531
              Número randômico:  3882

Variáveis Registradores

Uma variável declarada com o modificador register indica ao compilador para utilizar um registrador da CPU, ao invés de alocar memória para a variável.

Variáveis armazenadas em registradores são acessadas muito mais rápido que as armazenadas em memória, o que aumenta muito a velocidade de processamento.

Se o número de variáveis designadas como register exceder o número disponível de registradores da máquina, então o excesso será tratado como variáveis automáticas.


Variáveis registradores não podem ser globais e geralmente aplicam-se aos tipos int e char.


Obs: Existem programadores que costumam colocar variáveis contadoras em registradores, para tornar o processamento o mais rápido possível.


Ex:

/************************************************/
// Este programa mostra a diferença que uma variável register 
// pode fazer na velocidade de execucao de um programa
/************************************************/
#include <stdio.h>
#include <time.h>
unsigned int i;   // variável não-register
unsigned int delay;
void main(void)
{   register unsigned int j;
   long t;
   t = time('\0');
   for(delay = 0;delay < 50000; delay++)
      for(i = 0; i< 64000; i++) ;
   printf("tempo de loop não register: %d \n", time('\0')-t);
   getch( );
   t = time('\0');
   for(delay = 0; delay < 50000; delay++)
      for(j=0; j< 64000; j++) ;
   printf("tempo do loop register: %d \n", time('\0')-t);

}