Manipulando funções

Ver Todos os Exercícios

Teoria

Introdução

Fala aí, aqui é o Guga do Responde Aí! Tudo bem com você?

No tópico anterior nós conversamos um pouco sobre as funções, hoje nós iremos aprender como implementá-las na linguagem C.

Protótipo de uma função

Nós já sabemos como criar uma função, mas a pergunta que eu tenho para nós respondermos agora é a seguinte:

Onde nós criamos uma função?

A resposta é bem simples, nós criamos uma função fora da main(). Bom, agora nós podemos ser bem mais específicos e a nova pergunta que surge é:

Antes ou depois da função main?

A resposta para essa pergunta também é muito simples, tanto faz se criamos antes ou depois. A grande diferença entre os dois métodos é a aparição de um carinha chamado protótipo de função.

O protótipo de uma função surge quando nós criamos uma função depois da função principal (main), uma vez que a função principal não tem conhecimento daquilo que ocorre depois do seu encerramento. Então, o protótipo de função é uma forma de avisar o programa que existe uma função e quais são os parâmetros dela para que durante a execução da função principal não existam erros caso ela seja invocada (considere invocar como utilizar a função).

Então, vamos deixar as coisas visuais:

Nesse trecho de código nós temos uma função saudações criada depois da função main. Porém, na função main há uma invocação de saudacoes (linha 05).

Esse é o problemão que nós falamos ali em cima! Pois, o programa ainda não conhece saudacoes no momento de sua invocação.

É para que isso não aconteça que nós utilizamos o protótipo de uma função, olha como ele funciona:

Nesse caso, antes do programa entrar na função main nós já falamos para ele que existe uma outra função chamada saudacoes. Dessa forma, ele já sabe o nome, tipo e parâmetros de saudacoes e já sabe exatamente o que fazer quando essa função for invocada.

Para nós memorizarmos direitinho, essa é a forma geral de declarar uma função através de seu protótipo:

E se eu não quiser usar o protótipo, como eu faço para criar uma função antes da main()? Nesse caso, você declarará a função através de sua definição, dessa forma:

E tudo funcionará certinho.

Funções sem retorno

Você notou alguma coisa estranha na função saudacoes?

Caso não tenha percebido, o tipo dela é void. Isso significa que ela é uma função sem retorno, ou seja, o seu processamento não envolve devolver algum tipo de resultado para o escopo que a invocou.

Invocando uma função

Nós falamos e falamos de invocações e até agora a única coisa que vem em nossas cabeças é algo mais ou menos parecido com isso:

Invocar ou chamar uma função nada mais é do que a utilizar. Para isso, existem algumas coisas que precisamos nos atentar:

  • Se a função tem retorno, um resultado deve ser esperado;
  • Se a função tem parâmetros não nulos, valores devem ser passados.

Beleza, agora que temos essas informações, vamos criar uma função:

Prontinho, agora temos uma função que realiza a divisão de dois números passados como parâmetro.

Agora vamos para as perguntas!

  • A função tem retorno? Sim, então um resultado deve ser esperado.
  • A função tem parâmetros não nulos? Sim (2 parâmetros), então valores devem ser passados.

Cuidando dessas coisas, agora temos sua invocação:

Onde, resultado é a variável que receberá o retorno da função, v1 será o valor primeiro parâmetro e 5 será o segundo parâmetro (linha 09).

De forma geral, uma chamada de função é feita da seguinte forma:

Parâmetros são cópias

Outra coisa muito importante a se dizer é que quando passamos uma variável como parâmetro de uma função, apenas o seu valor é copiado.

O que isso quer dizer?

Que não adianta você manipular uma variável passada como cópia, pois o valor presente no seu escopo original ainda será o mesmo.

Observe esse programa:

Que teve como saída:

Pronto, está comprovado que não houve alterações na variável original.

Agora que nós já estamos craques em funções, vamos fazer alguns exercícios de fixação!

Funções sem retorno

Invocando uma função

Parâmetros são cópias

Exercícios Resolvidos

Exercício Resolvido #1

Faça um programa leia a idade de um nadador e chame um procedimento que receba essa idade por parâmetro com o objetivo de retornar a categoria desse nadador de acordo com a tabela abaixo:

Passo 1

Vamos começar o desenvolvimento desse programa pelo seu escopo.

Para facilitar, nós criamos um tipo enumerado chamado c a t e g o r i a s e o redefinimos através do comando typedef para c a t . Além disso, também falamos para o programa que teremos uma função chamada c l a s s i f i c a N a d a d o r com retorno do tipo c a t que espera como parâmetro um número inteiro n (linha 10).

E é claro que não podemos nos esquecer da declaração da função principal!

Passo 2

Agora que já temos o escopo do programa, podemos definir o procedimento c l a s s i f i c a N a d a d o r que será chamado na função main.

Esse procedimento consiste em utilizar comandos condicionais para verificar a categoria do nadador. Ou seja, caso uma das condições seja verdadeira, uma variável n a d a d o r receberá a constante enumerada da respectiva categoria daquela idade e será retornada.

Passo 3

Para finalizarmos esse programa, já que temos as estruturas que atuam fora da função principal prontas, basta codificarmos agora os comandos da função main.

Basicamente o que nós temos que fazer é ler uma idade n (linha 09) que será enviada como parâmetro na chamada pela função c l a s s i f i c a N a d a d o r , essa por sua vez será responsável por inicializar a variável x do tipo enumerado c a t com o seu retorno (linha 11).

Tendo em mãos a variável x armazenando a constante enumerada da respectiva categoria do nadador, basta utilizarmos uma estrutura switch para comparar o valor de x com cada uma das constantes presentes no tipo enumerado c a t e g o r i a s com o objetivo de realizar a impressão da categoria correta do nadador no caso em que a comparação de igualdade é verdadeira.

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #2

Faça uma função que receba por parâmetro a altura e o sexo de uma pessoa e retorne o peso ideal dela. O cálculo do peso ideal pode ser feito da seguinte forma:

  • Fórmula do peso ideal para homens:
  • 72,7 * a l t u r a - 58

  • Fórmula do peso ideal para mulheres:

62,1 * a l t u r a - 44,7

Passo 1

A primeira coisa que nós temos que fazer é definir o escopo do nosso programa.

Para isso, além de declararmos a função principal, também informamos ao programa que teremos uma função chamada p e s o I d e a l que terá um retorno do tipo float e espera como parâmetros uma altura h e um caractere s e x o .

Passo 2

Com o escopo principal definido, nós podemos agora definir a função p e s o I d e a l que será chamada no código principal.

A lógica dela consiste em apenas utilizar o comando condicional if para verificar se o caractere s e x o recebido é masculino (igual ao caractere “M”). Caso seja igual, uma variável local da função chamada p I d e a l irá receber a fórmula do peso ideal masculino utilizando a altura h , que também foi passada como parâmetro da função, caso contrário p I d e a l receberá a fórmula do peso ideal feminino uma vez que o caractere inserido não foi o “M”. Por fim, basta retornarmos a variável local p I d e a l .

Passo 3

Agora que já temos a função definida, podemos criar o código que irá utilizá-la.

Ele consiste em requisitar a leitura dos dados de altura e sexo para o usuário através dos comandos scanf() (linhas 10 e 11). Após isso, inicializa a variável p e s o com o retorno gerado na execução da função p e s o I d e a l com os parâmetros a l t u r a e s e x o (linha 13). Por fim, imprime o peso ideal (que agora está armazenado na variável p e s o ) com duas casas decimais e uma quebra de linha.

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #3

Fazer uma função que calcula a enésima potência de uma variável real x : f x ,   n = x n .

Passo 1

A melhor coisa que nós podemos fazer para começar é definir o escopo da função principal e o cabeçalho de outras funções que iremos utilizar nesse programa.

No caso desse exercício, além da função principal, iremos utilizar uma função chamada p o t e n c i a que tem um retorno do tipo int e espera como parâmetros duas entradas: uma base e um expoente (ambos inteiros).

Passo 2

Agora que já temos uma visão geral do nosso programa, podemos iniciar a definição da função que realizará o cálculo da potência.

A lógica desse código é bastante simples, nós simplesmente declaramos uma variável local r e s e utilizamos uma estrutura de repetição for para atualizá-la a cada loop. Ou seja, a variável r e s é inicializada com o valor 1 e dentro do laço de repetição será atualizada com o seu valor multiplicado pelo conteúdo da variável b a s e passado como parâmetro e x p vezes. Ao término da execução do laço de repetição teremos a seguinte relação: r e s = b a s e e x p .

Passo 3

Com a função p o t e n c i a definida, podemos agora criar o código principal do programa.

Nesse código, nós basicamente realizamos a leitura da base e do expoente da potência que será calculada através de comandos scanf() (linhas 09 e 10). Em seguida, chamamos a função p o t e n c i a passando como parâmetro as variáveis n e e x p o e n t e anteriormente lidas, para que a variável p o t seja inicializada com o valor retornado pela função p o t e n c i a (resultado da potência entre as variáveis n e e x p o e n t e ). Por fim, simplesmente imprimimos a variável p o t com uma quebra de linha.

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #4

Escreva uma função que receba dois números e retorne o menor deles.

Passo 1

Iniciaremos a criação do nosso programa com uma visão geral, para isso vamos definir o escopo da função principal e o cabeçalho da função de comparação dos dois números.

Nesse caso, a função de comparação vai se chamar c o m p a r a , terá um retorno do tipo float e esperará dois números como parâmetros.

Passo 2

Agora que já temos uma visão geral do programa, podemos definir o código da função c o m p a r a .

A lógica desse código é simplesmente utilizar o comando condicional if para verificar se n 1 é maior que n 2 (ambos recebidos como parâmetros). Caso a condição seja verdadeira, n 2 é retornado, já que o mesmo é o menor número entre os dois, caso contrário o número que deve ser retornado é n 1 .

Passo 3

Por fim, agora que já temos a função c o m p a r a definida podemos criar o código principal do nosso programa.

Onde simplesmente realizamos a leitura dos números e os armazenamos nas variáveis n 1 e n 2 (linhas 09 e 10) e posteriormente chamamos a função c o m p a r a , passando n 1 e n 2 como parâmetros, para que o menor número (retorno da função) seja atribuído a variável m e n o r e a mesma seja impressa na tela seguida de uma quebra de linha.

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #5

Crie um programa que receba um número do usuário e imprima na tela a tabuada de 0 a 10 desse mesmo número. Utilize uma função para o cálculo da tabuada.

Passo 1

Começaremos o nosso programa tendo uma visão geral daquilo que será feito.

Para isso declaramos o escopo principal e o cabeçalho da função que será responsável pela impressão da tabuada chamada t a b u a d a . Como não se trata de uma função de retorno de valor, o tipo do seu retorno deve ser void e ela espera como parâmetro um único número inteiro n .

Passo 2

Conhecendo os elementos que compõem o nosso programa, podemos agora definir a função t a b u a d a .

Que basicamente consiste em utilizar um laço de repetição for para realizar sucessivas multiplicações entre n (passada como parâmetro) e a variável contadora i (inicializada em 0) durante 10 loops, que totalizam a tabuada de 0 a 10 de n .

Passo 3

Por último, agora que já temos a função t a b u a d a definida, podemos codificar o código principal.

Que simplesmente consiste em ler um número n inserido pelo usuário através do comando scanf() e em seguida chamar a função t a b u a d a (passando esse mesmo número n como parâmetro).

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #6

Escreva um procedimento que receba 3 valores reais x , y e z que representam os lados de um triângulo e retorne qual é o tipo do triângulo formado observando as seguintes definições:

  • Triângulo equilátero: os comprimentos dos três lados são iguais.
  • Triângulo isósceles: os comprimentos de dois dos lados são iguais.
  • Triângulo escaleno: os comprimentos dos três lados são diferentes.

Passo 1

Vamos começar o nosso programa definindo o escopo principal e o cabeçalho da função que utilizaremos para verificar o tipo do triângulo de acordo com seus lados.

Passo 2

Agora que já temos uma visão geral dos elementos que irão compor o nosso programa, podemos definir a função v e r i f i c a T r i a n g u l o .

O seu código é bastante simples, basicamente o que nós temos que fazer é utilizar o comando condicional if para compararmos os lados do triângulo recebidos como parâmetros. Ou seja, se a condição que todos os lados são iguais for verdadeira, devemos imprimir que o triângulo é equilátero, por outro lado se a condição que todos os lados são diferentes for verdadeira, devemos imprimir que o triângulo é escaleno. Por fim, se nenhuma das condições anteriores for verdadeira, estamos no caso em que pelo menos dois lados são iguais e por esse motivo o bloco else deve ser a impressão de que o triângulo é isósceles.

Passo 3

Agora que já temos a função v e r i f i c a T r i a n g u l o definida, podemos codificar o código principal que será responsável por chamá-la.

A responsabilidade do código principal nesse programa é simplesmente requisitar os dados de entrada ao usuário (linha 09) e em seguida passá-los como parâmetro para a função v e r i f i c a T r i a n g u l o em sua chamada (linha 11).

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #7

Escreva um programa em C que leia 5 valores inteiros e imprima para cada um deles o seu correspondente absoluto. Para obter o valor absoluto de um número n utilize a função abaixo:

Passo 1

A primeira coisa que nós temos que fazer é analisar a função a b s o l u t o para entendermos como a mesma funciona antes de utilizá-la. Sendo assim, com uma breve analise, conseguimos descobrir que ela para funcionar precisa receber como parâmetro um número inteiro n . Além disso, tem como resultado o retorno de um número inteiro.

Passo 2

Agora que já sabemos como utilizar a função a b s o l u t o , podemos escrever o código principal do nosso programa.

Basicamente o que nós fazemos é utilizar uma estrutura de repetição for para ler um número n e em seguida imprimirmos o retorno da chamada da função a b s o l u t o passando esse número n como parâmetro. Dada que a condição de execução do laço é i menor que 5 e i (que é a variável contadora) é incrementada em uma unidade a cada loop, essa sequência será executada 5 vezes. Logo, teremos os valores absolutos dos 5 números que serão lidos sendo impressos.

Resposta

Ei, a resposta está no passo a passo :)

Exercício Resolvido #8

Observe o seguinte trecho de código:

Esse programa deve ser capaz de ler 10 números inteiros, ordená-los e em seguida imprimi-los em ordem. Sabendo que nenhuma alteração deve ser feita dentro da função main, faça a implementação da função o r d e n a V e t o r . Lembre-se que a função i m p r i m e V e t o r é definida da seguinte forma:

Passo 1

A primeira coisa que nós temos que fazer para conseguirmos implementarmos de maneira correta a função o r d e n a V e t o r é observarmos com ela é utilizada na main.

Então, vamos focar nessa imagem do enunciado por enquanto:

Nela, nós conseguimos perceber que um vetor v de 10 posições está sendo preenchido e passado como parâmetro em uma chamada da função o r d e n a V e t o r .

Também conseguimos perceber que logo após a chamada dessa função, o programa é encerrado. Ou seja, a função o r d e n a V e t o r também é responsável por chamar a função de impressão i m p r i m e V e t o r .

Passo 2

Depois dessa super análise nós já estamos prontinhos para definirmos a função o r d e n a V e t o r .

E por increça que parível a sacada dela é bem simples, depois de utilizarmos algum algoritmo de ordenação para ordenarmos os elementos do vetor, nesse caso utilizamos dois laços de repetição para comparar cada elemento e trocá-los de lugar (linhas 05 a 16), nós simplesmente temos que chamar a função i m p r i m e V e t o r passando o vetor v ordenado como parâmetro (linha 18).

Resposta

Em poucas palavras esse programa funciona assim: preenchemos um vetor v de 10 posições na main, chamamos a função o r d e n a V e t o r para ordená-lo e após isso chamar outra função para imprimi-lo, função essa chamada i m p r i m e V e t o r .