Mudanças entre as edições de "Funções - Programação 1 - Engenharia"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
Linha 284: Linha 284:
 
   float area_retang (float lado1 , float lado2)
 
   float area_retang (float lado1 , float lado2)
 
</syntaxhighlight>
 
</syntaxhighlight>
<!--
+
 
 
{{collapse top | Solução - Exercício 01}}
 
{{collapse top | Solução - Exercício 01}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
Linha 319: Linha 319:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
-->
+
 
 
A função recebe os lados de um retângulo e retorna a área do mesmo.
 
A função recebe os lados de um retângulo e retorna a área do mesmo.
 
</li>
 
</li>
Linha 327: Linha 327:
 
A função recebe o raio de um círculo e retorna a área da mesma.
 
A função recebe o raio de um círculo e retorna a área da mesma.
 
</li>
 
</li>
<!--
+
 
 
{{collapse top | Solução - Exercício 02}}<syntaxhighlight lang=c>
 
{{collapse top | Solução - Exercício 02}}<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
Linha 349: Linha 349:
 
}</syntaxhighlight>
 
}</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
-->
+
 
 
<li> Elaborar um programa contendo uma função da forma:  
 
<li> Elaborar um programa contendo uma função da forma:  
 
<code>float dif_area_circ (float raio1, float raio2)</syntaxhighlight>
 
<code>float dif_area_circ (float raio1, float raio2)</syntaxhighlight>
Linha 395: Linha 395:
 
</syntaxhighlight>{{collapse bottom}}
 
</syntaxhighlight>{{collapse bottom}}
  
-->
+
 
 
</li>
 
</li>
 
<li> Elaborar uma função que recebe dois números inteiros. A função retorna a soma de todos os números entre eles (inclusive).
 
<li> Elaborar uma função que recebe dois números inteiros. A função retorna a soma de todos os números entre eles (inclusive).
  
<!--
+
 
 
{{collapse top | Solução - Exercício 04}}<syntaxhighlight lang=c>
 
{{collapse top | Solução - Exercício 04}}<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
Linha 434: Linha 434:
 
}
 
}
 
</syntaxhighlight>{{collapse bottom}}
 
</syntaxhighlight>{{collapse bottom}}
-->
+
 
 
</li>
 
</li>
  
Linha 454: Linha 454:
  
 
</li>
 
</li>
<!--
+
 
 
{{collapse top | Solução - Exercício 05}}<syntaxhighlight lang=c>
 
{{collapse top | Solução - Exercício 05}}<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
Linha 482: Linha 482:
 
}
 
}
 
</syntaxhighlight>{{collapse bottom}}
 
</syntaxhighlight>{{collapse bottom}}
-->
+
 
 
<li>
 
<li>
 
Faça uma função para entrar com dois números inteiros pelo teclado e retornar a soma dos fatoriais destes números. Reutilize a função anterior.
 
Faça uma função para entrar com dois números inteiros pelo teclado e retornar a soma dos fatoriais destes números. Reutilize a função anterior.
 
</li>
 
</li>
<!--
+
 
 
{{collapse top | Solução - Exercício 06}}<syntaxhighlight lang=c>
 
{{collapse top | Solução - Exercício 06}}<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
Linha 514: Linha 514:
 
}
 
}
 
</syntaxhighlight>{{collapse bottom}}
 
</syntaxhighlight>{{collapse bottom}}
-->
+
 
 
<li>
 
<li>
 
Faça uma função para calcular o módulo de um número complexo passado na forma retangular. O protótipo da função tem o seguinte aspecto:
 
Faça uma função para calcular o módulo de um número complexo passado na forma retangular. O protótipo da função tem o seguinte aspecto:
 
<code>float mod_complexo(float x, float y)</syntaxhighlight>
 
<code>float mod_complexo(float x, float y)</syntaxhighlight>
 
</li>
 
</li>
<!--
+
 
 
{{collapse top | Solução - Exercício 07}}<syntaxhighlight lang=c>
 
{{collapse top | Solução - Exercício 07}}<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
Linha 544: Linha 544:
 
}
 
}
 
</syntaxhighlight>{{collapse bottom}}
 
</syntaxhighlight>{{collapse bottom}}
-->
+
 
 
<!--
 
<!--
 
<li>
 
<li>

Edição das 14h14min de 26 de abril de 2019

FUNÇÕES no C

Programa C: Um conjunto de funções

Um programa em C basicamente é um conjunto de funções. 
Uma função pode ser vista como um subprograma para o qual podemos repassar 
dados de entrada através de parâmetros e receber os resultados através 
do retorno da função.

Normalmente, um programa bem comportado em C possui pelo menos uma função: a função main(). Esta função é chamada no início da execução do programa. A primeira instrução da função main() é a primeira instrução executada pelo programa (pelo menos do ponto de vista do programador). Da mesma forma, a última instrução desta função é a última instrução a ser chamada.

Um programa normalmente vai apresentar um conjunto de funções. Por exemplo:

#include <stdio.h>

func4()
{
    printf("Esta é a função func4()\n");
}

func3()
{
    printf("Esta é a função func3()\n");
    func4();
}

func2()
{
    printf("Esta é a função func2()\n");
}

func1()
{
    printf("Esta é a função func1()\n");
    func2();
    func3();
}

main()
{
    printf("Esta é a primeira instrução da função main()\n");
    func1();
    printf("Esta é a última instrução da função main()\n");
}

A sequência de chamada de funções pode ser ilustrada da forma:

FuncChamadaFuncoes.png

EXERCÍCIO: Compile e execute o programa acima. Verifique a ordem de impressão das mensagens e compare com as chamadas das funções.

NOTA: Uma função pode ser chamada várias vezes no programa. 
É O REAPROVEITAMENTO DE CÓDIGO...

Passando parâmetros e recebendo valores de retorno

Uma função normalmente resolve um determinado problema para um determinado conjunto de dados e produz uma saída. Estes dados podem ser passados como parâmetros e a saída pode ser retornada pela função.

Exemplo: Uma função media_nums() que retorna a média de 3 números reais passados como parâmetros

#include <stdio.h>

float media_nums(float num1, float num2, float num3)
{
  float media_local;

  media_local = (num1 + num2 + num3)/3;
  return media_local;
}

main()
{
  float media, aux1, aux2, aux3;

  printf("\nEntre com numero 1: ");  
  scanf ("%f",&aux1);

  printf("\nEntre com numero 2: ");  
  scanf ("%f",&aux2);

  printf("\nEntre com numero 3: ");  
  scanf ("%f",&aux3);

  media = media_nums(aux1, aux2, aux3);
  printf ("\nmedia dos 3 numeros é %f\n", media);
}

ADS29002-PassagemParametrosC.png

Deve ser observado que:

  • após o nome da função, entre parênteses, são fornecidos os três parâmetros com os seus respectivos tipos. Os valores (conteúdos das variáveis) aux1, aux2 e aux3 são copiados para as variáveis num1, num2 e num3 da função media_nums().
  • a função media_nums() retorna um valor do tipo float (informado antes do nome da função) que é o valor da variável media_local. Este valor é copiado para a variável media da função main()
  • as variáveis num1, num2 e num3 bem como a variável media_local possuem escopo LOCAL, ou seja, são "vistas" somente pela função media_nums();
  • as variáveis media, aux1, aux2 e aux3 também possuem escopo LOCAL, ou seja são "vistas" somente pela função main();

NOTE que o formato de declaração de uma função é

 tipo_retorno nome_funcao( lista_de_parametros )
 {
   declaracao_variaveis_locais

   instruções
 }

Por enquanto, assumiremos que variáveis devem ser somente declaradas no início da função. Existem situações que poderemos relaxar esta afirmação.

Um pouco mais sobre parâmetros

O termo argumento ou parâmetro real (atual) é usado para referenciar os valores que estão sendo passados na CHAMADA da função. Os parâmetros formais referem-se aos parâmetros listados na função. É comum, no entanto, usar os termos argumentos e parâmetros como sinônimos e identificados pelo contexto em que estão sendo usados.

A passagem de parâmetros POR VALOR diz respeito a copiar o valor do argumento na CHAMADA da função para a variável associada ao parâmetro na função. Mais tarde falaremos na passagem de parâmetro POR REFERÊNCIA. Por ora, usaremos a passagem POR VALOR.

Os parâmetros passados na CHAMADA de uma função não são necessariamente variáveis. Eles podem ser uma expressão qualquer (uma expressão SEMPRE resulta em um VALOR).

Exemplo de chamadas para a função media_nums():

main()
{
  float media, x,y,z;

  x = 5.7;
  y = 9.8;

  /* exemplo de chamada 1 */  
  media = media_nums(4.8,x,y*3);

  /* exemplo de chamada 2 */ 
  media = media_nums (x+y,y*y+5,(x+y)/2);
}

Deve ser observado que:

  • na chamada 1 do exemplo, os parâmetros são uma CONSTANTE, o valor de x, e o valor de y*3. Note que o compilador deve gerar código para resolver estas expressões antes de INVOCAR a função!.
  • na chamada 2 aparecem expressões ainda mais complexas. Todas elas devem ser resolvidas antes da função ser INVOCADA.

Variáveis GLOBAIS e variáveis LOCAIS

Se variáveis são declaradas dentro de uma função, então a visibilidade (ESCOPO) destas variáveis é LOCAL. Nenhuma outra função tem acesso a estas variáveis.

Uma variável pode ser GLOBAL, ou seja, declarada FORA das funções. Neste caso a variável é VISTA por todas as funções. Seja o exemplo anterior modiificado:

#include <stdio.h>

float media; /* Variável GLOBAL */

void media_nums(float num1, float num2, float num3)
{
  media = (num1 + num2 + num3)/3;
  return;
}

main()
{
  float aux1, aux2, aux3; /* Variáveis LOCAIS */

  printf("\nEntre com numero 1: ");  
  scanf ("%f",&aux1);

  printf("\nEntre com numero 2: ");  
  scanf ("%f",&aux2);

  printf("\nEntre com numero 3: ");  
  scanf ("%f",&aux3);

  media_nums(aux1, aux2, aux3);
  printf ("\nmedia dos 3 numeros é %f\n", media);
}

Neste exemplo, a variável media é declarada como GLOBAL. Ela é MODIFICADA diretamente pela função media_nums() e impressa pela função main()

NOTE que como a função media_nums() não retorna valor então declaramos 
seu tipo de retorno como void que significa aqui NADA ou VAZIO. 
NOTE também que MESMO que a função retorne um valor, não é obrigatório colocá-la
no lado direito do sinal de atribuição.

Na realidade, uma função pode ser chamada dentro de qualquer expressão. Por exemplo, para o caso em que a função media_nums() retorna um valor, ela poderia ser usada como:

#include <stdio.h>

float media_nums(float num1, float num2, float num3)
{
  float media_local;

  media_local = (num1 + num2 + num3)/3;
  return media_local;
}

main()
{
  float media, aux1, aux2, aux3;
  printf("\nEntre com numero 1: ");  
  scanf ("%f",&aux1);

  printf("\nEntre com numero 2: ");  
  scanf ("%f",&aux2);

  printf("\nEntre com numero 3: ");  
  scanf ("%f",&aux3);

  media = media_nums(aux1, aux2, aux3);
  printf ("\nmedia dos 3 numeros multiplicada por 10 é %f\n", 10*media_nums(aux1, aux2, aux3));
}

Um parênteses sobre nome de variáveis

Um nome de variável pode conter letras, dígitos e o underscore(sublinhado). Ela DEVE iniciar com um underscore ou uma letra. Letras maúsculas e minúsculas podem ser usadas e são distinguidas (o C é CASE SENSITIVE)

Variáveis LOCAIS e GLOBAIS podem ter o mesmo nome. A variável LOCAL terá preferência no uso.

Exercício: Execute o programa abaixo e verifique as saídas.

#include <stdio.h>

int i=1;          /* GLOBAL  */

func()
{
    int i=100;     /* LOCAL */
    i=i+1;          /* incrementa LOCAL */
    printf( "Valor de i = %d na função func()\n", i );
}
   
main()
{
    i=i+1;          /* incrementa GLOBAL  */
    func();
    printf( "Valor de i = %d \n", i );
}


 NOTA: não é recomendado o uso de variáveis com o mesmo nome.

Iniciando variáveis na declaração

Tanto as variáveis LOCAIS como as GLOBAIS podem ser inicializadas na declaração.

Exemplo:

int alfa=1;

main()
{
  float beta=1.5;

  printf("Valor de alfa = %d e valor de beta = %f\n", alfa, beta);
}
 NOTA: variáveis LOCAIS não são iniciadas automaticamente: cabe ao programador iniciá-la corretamente.
 NOTA: variáveis GLOBAIS são iniciadas automaticamente com zero. 
       Mas mantenha-se informado sobre o sistema que está trabalhando...
       Em sistemas embarcados pode não ser verdade!

Exercícios

  1. Elaborar um programa contendo uma função da forma: float area_retang (float lado1 , float lado2) </syntaxhighlight>
    Solução - Exercício 01
    #include <stdio.h>
    
    /* Função de Cálculo da Aŕea de um retângulo */
    /* Parâmetros de entrada: lados do retângulo */
    /* retorno: valor da área */
    float area_retang(float lado1, float lado2)
    {
      float area;
    
      area = lado1 *lado2;
      return area;
    }
    
    main()
    {
      float area;
      float l1, l2;
    
      /* entrada de dados */
      printf("entre com lado 1\n");
      scanf ("%f", &l1);
    
      printf("entre com lado 2\n");
      scanf ("%f", &l2);
    
      /* chamada da função */
      area = area_retang(l1,l2);
      
      printf("valor da area do retanguloa = %0.2f\n", area);
    }
    

    A função recebe os lados de um retângulo e retorna a área do mesmo.

  2. Elaborar um programa contendo uma função da forma: float area_circ (float raio)</syntaxhighlight> A função recebe o raio de um círculo e retorna a área da mesma.
  3. Solução - Exercício 02
    #include <stdio.h>
      
    float area_circ(float raio)
    { 
      float area;/* Variáveis LOCAIS */
      area = (raio*raio)*3.1415;
      return area;
    }
     
    main()
    {
      float aux1, area; /* Variáveis LOCAIS */
     
      printf("Entre com o raio\n");  
      scanf ("%f",&aux1);
     
      area = area_circ(aux1);
      printf ("A area do circulo é %f\n", area);
    }
    
  4. Elaborar um programa contendo uma função da forma: float dif_area_circ (float raio1, float raio2)</syntaxhighlight> A função recebe o raio de dois círculos e retorna a diferença da área entre eles. Reaproveitar o exercício anterior.