Prévia do material em texto
FUNÇÕES E
PASSAGEM DE
PARÂMETROS
Aula 1
FUNÇÕES
Funções
Estudante, esta videoaula foi preparada especialmente para você.
Nela, você irá aprender conteúdos importantes para a sua formação
profissional. Vamos assisti-la?
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 1/72
Ponto de Partida
Olá! Até este ponto você já estudou praticamente todos os conceitos
fundamentais de algoritmos e linguagem de programação, como os
tipos de dados, variáveis, constantes, operadores e expressões,
estruturas de controle, estruturas homogêneas e heterogêneas,
além de ponteiros. Agora vamos prosseguir um pouco mais em
nossos estudos e introduzir os conceitos de procedimentos e
funções!
Você foi recrutado por um laboratório de pesquisa que presta
serviços terceirizados para colaborar com vários profissionais. Seu
primeiro projeto será com o departamento de engenheiros civis. Eles
receberam uma solicitação da construtora local para calcular e
determinar qual guindaste deve ser utilizado em uma determinada
construção para erguer as colunas de concreto armado. Eles têm à
disposição três tipos de guindastes: G1, G2 e G3. A seleção do
guindaste a ser usado depende do peso da peça que será levantada
pelo equipamento, o qual é calculado pela fórmula P = VR, em que
P representa o peso da coluna, V é o volume e R é a constante
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 2/72
utilizada, que é igual a 25 kN/m3. As diretrizes para a escolha do
guindaste estão especificadas na Tabela 1.
Tabela 1 | Regras para escolha do guindaste.
Para automatizar o processo com base nas medidas da coluna
(base, largura e altura), como o programa determinará e informará
aos engenheiros o guindaste que deve ser utilizado?
Para cumprir sua missão, você irá aprender sobre a distinção entre
procedimentos e funções, bem como a criação e utilização desses
conceitos. Agora vamos lá, preste muita atenção e tenha um
excelente estudo!
Vamos Começar!
Conceitos e definição de funções
Até este ponto, você já desenvolveu vários algoritmos na linguagem
C, correto? Nos programas que criou, mesmo sem ter um
conhecimento formal sobre funções, você já as utilizou! Por
exemplo, printf() e scanf() são funções incluídas nas bibliotecas da
linguagem C que você utiliza desde o início. Mas antes mesmo
Regra Guindaste
Peso 1500 Kg G3
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 3/72
destas funções você já empregou uma função muito importante!
Observe o código apresentado no Quadro 1, que exibe uma
mensagem na tela. Na linha 2 temos o comando “int main()”. Esse
comando define uma função denominada "main" que retorna um
valor inteiro, neste caso, zero. Parece complexo? Fique tranquilo!
Vamos compreender adequadamente como construir e operar esse
recurso fundamental.
Quadro 1 | Exemplo de programa em C.
A concepção de desenvolver programas com conjuntos de
funcionalidades deriva de uma estratégia de design de algoritmos
conhecida como "dividir para conquistar". O conceito é direto: ao
enfrentar um problema, é recomendado dividi-lo em problemas
menores, facilitando assim sua resolução e organização. Essa
técnica compreende três etapas (Figura 1):
1. Dividir: fragmentar um problema em subproblemas menores.
"Resolver problemas de menor escala, em vez de um problema
único e grande, é, do ponto de vista computacional,
teoricamente mais simples".
2. Conquistar: utilizar uma sequência de instruções separadas
para resolver cada subproblema.
3. Combinar: integrar a solução de cada subproblema para obter
a solução completa do problema original.
1:
2:
3:
4:
5:
#include
int main(){
printf("Hello World!",altura[0]);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 4/72
Figura 1 | Resumo da técnica dividir para conquistar.
Em linguagem C, uma função é essencialmente um fragmento de
código autônomo incorporado em um programa maior, designado
para desempenhar uma tarefa específica com relativa
independência do restante do código. Uma das vantagens
fundamentais das funções é a capacidade de serem executadas
repetidamente, o que proporciona a reutilização eficiente do código.
Em vez de repetir várias vezes um conjunto de comandos para
realizar uma determinada operação, é possível simplesmente
chamar a função responsável por essa tarefa em múltiplas ocasiões.
Essa prática, que também pode ser chamada de modularização, não
só economiza espaço e torna o código mais conciso, mas também
viabiliza ajustes ágeis no código associado a essa tarefa específica.
A organização do código em várias funções também desempenha
um papel crucial na manutenção da clareza e limpeza do programa.
Ao dividir o código em partes menores, cada uma focada em uma
tarefa específica, a complexidade geral do programa é reduzida,
tornando o código mais legível e compreensível. Esse método de
divisão modular não apenas facilita a compreensão do
funcionamento do programa, mas também simplifica o processo de
identificação e correção de possíveis erros ou problemas no código.
A Figura 2 ilustra esta ideia de que as funções são blocos de
construção que permitem a divisão dos programas em partes
menores (Segmentar uma tarefa grande de computação em várias
tarefas menores).
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 5/72
Figura 2 | Ilustração de um programa sendo
dividido em funções.
Sintaxe de funções: parâmetros e retorno
Agora que sabemos a motivação por trás do conceito de função,
como criá-la? Para isso, utilizamos a seguinte sintaxe:
Cada declaração de função possui uma série de parâmetros, alguns
dos quais são fundamentais, enquanto outros são opcionais. Vamos
examinar cada um deles:
Tipo de retorno: este parâmetro é obrigatório e indica o tipo de
valor que a função retornará. Pode ser um valor inteiro (int),
decimal (float ou double), caractere (char) ou outro tipo de
dado. No caso de uma sub-rotina que executa um processo
sem retornar um valor específico, utiliza-se o parâmetro void.
Nesse contexto de função sem tipo de retorno (void), a função
é denominada de procedimento e o uso do void pode ser
omitido.
()
{
(não obrigatório)
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 6/72
Nome: outro parâmetro obrigatório que especifica o
identificador da função. Funciona de maneira similar ao nome
de uma pessoa, em que é necessário chamá-la pelo nome para
interagir. É importante ressaltar que o nome não deve conter
acentos, caracteres especiais ou espaços, seguindo as
mesmas regras aplicadas a nomes de variáveis.
Parênteses após o nome: é um parâmetro obrigatório que
acompanha o nome da função ou procedimento. Por exemplo,
temos as expressões main(), printf() e somar().
Parâmetros: este campo é opcional, e contém valores que
podem ser passados para a função, sobre os quais a função
deve operar. Os parâmetros das funções atuam de maneira
análoga às variáveis das funções matemáticas. Por exemplo:
imagine a função matemática f(x) = x + 2. Quando calculamos
f(3), nós substituímos o valor de x por 3, resultando em f(3) = 3
+ 2 = 5. Desta forma, o 3 é um parâmetro da função f, e o
função o utiliza para realizar seu cálculo (processamento). Este
campo será estudado em detalhes mais à frente.
Comandos da função: são obrigatórios, pois uma função só
faz sentido se houver um conjunto de comandos que ela possa
executar.
Retorno: quandohttps://integrada.minhabiblioteca.com.br/reader/books/9788595152090/epubcfi/6/34[%3Bvnd.vst.idref%3DB9788535291063000092]!/4/2/4/4[B9788535291063000092]/1:5[n%C3%A7%C3%B5%2Ces]
https://pt.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/recursion
FUNÇÕES E PASSAGEM DE
PARÂMETROS
Videoaula de Encerramento
Estudante, esta videoaula foi preparada especialmente para você.
Nela, você irá aprender conteúdos importantes para a sua formação
profissional. Vamos assisti-la?
Ponto de Chegada
Olá, estudante! Para desenvolver a competência desta Unidade, que
é “Conhecer os métodos de funções, recursividade, passagem de
dados e parâmetros em algoritmos”, você deve explorar conceitos
fundamentais em programação, concentrando seus estudos em
funções e passagem de parâmetros em linguagem C. Comece por
compreender a sintaxe de procedimentos e funções. Aqui,
aprenderemos como organizar blocos de código para realizar tarefas
específicas, tornando o programa mais modular e fácil de manter.
Entenderemos como declarar, chamar e definir procedimentos e
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 62/72
funções, e como estas estruturas contribuem para a modularização
do código.
Além disso, estude sobre o escopo de uma função e a distinção
entre variáveis globais e locais. Compreender o escopo é crucial
para evitar conflitos entre variáveis e garantir que elas sejam
acessíveis somente onde necessário. Isso não apenas promove a
clareza do código, mas também evita potenciais erros decorrentes
de variáveis com nomes idênticos em contextos diferentes.
Ao avançar nos estudos, é importante compreender a passagem de
parâmetros, que são conceitos fundamentais para a comunicação
eficiente entre funções. Explore tanto a passagem por valor quanto a
passagem por referência, entendendo suas implicações no
comportamento do programa. Isso proporcionará uma compreensão
mais profunda de como os dados são transmitidos e manipulados
em diferentes contextos.
Finalmente, estudo à fundo as funções recursivas! Entenda o que
são e como utilizá-las para resolver problemas que podem ser
decompostos em subproblemas semelhantes. A recursividade,
quando aplicada corretamente, pode simplificar a lógica do código e
oferecer soluções elegantes para desafios complexos.
Compreendendo esses tópicos essenciais, você terá dominado os
conceitos, os recursos e as ferramentas fundamentais voltadas para
o desenvolvimento de softwares!
É Hora de Praticar!
Realize a implementação de um sistema bancário simples em
linguagem C, em que cada cliente possui uma conta com saldo.
Desenvolva funções que realizem operações bancárias básicas,
como depósito, saque e transferência, utilizando conceitos
avançados de passagem de parâmetros.
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 63/72
Definição da Estrutura: declare uma estrutura chamada Conta
que contenha informações como número da conta, nome do
titular e saldo.
Função para Depósito: crie uma função chamada
realizarDeposito que permita ao cliente realizar um depósito em
sua conta. A função deve receber como parâmetros a estrutura
da conta e o valor a ser depositado.
Função para Saque: implemente a função realizarSaque que
permita ao cliente fazer um saque de sua conta. A função deve
validar se há saldo suficiente antes de efetuar o saque.
Função para Transferência: desenvolva a função
realizarTransferencia que permita transferir um valor de uma
conta para outra. A função deve receber as estruturas de
ambas as contas e o valor a ser transferido.
Apresentação de Resultados: no programa principal (main),
crie duas instâncias da estrutura Conta para representar duas
contas diferentes. Solicite ao usuário que realize operações
como depósito, saque e transferência entre as contas. Utilize
as funções desenvolvidas para efetuar as operações e
apresente o saldo final das contas após cada transação.
Tratamento de Erros: implemente mecanismos de tratamento
de erros, como a verificação de saldo insuficiente durante
saques e transferências, e mensagens explicativas para o
usuário.
Reflita
Como a escolha entre usar um procedimento ou uma função
pode afetar a estrutura e o fluxo do seu código?
Como a escolha entre passagem por valor e por referência
pode impactar a eficiência e o comportamento de um
programa?
Em que situações as funções recursivas podem ser mais
vantajosas do que soluções iterativas?
Resolução do estudo de caso
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 64/72
O código a seguir apresenta uma sugestão de resultado para o
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 65/72
problema:
#include
struct Conta {
int numero;
char titular[50];
float saldo;
};
void realizarDeposito(struct Conta *conta, float valor) {
conta->saldo += valor;
}
int realizarSaque(struct Conta *conta, float valor) {
if (conta->saldo >= valor) {
conta->saldo -= valor;
return 1; // Saque bem-sucedido
} else {
printf("Saldo insuficiente para realizar o saque.\n");
return 0; // Saque mal-sucedido
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 66/72
}
int realizarTransferencia(struct Conta *origem, struct Conta
*destino, float valor) {
if (realizarSaque(origem, valor)) {
realizarDeposito(destino, valor);
return 1; // Transferência bem-sucedida
} else {
printf("Transferência mal-sucedida.\n");
return 0; // Transferência mal-sucedida
}
}
int main() {
// Criação de duas instâncias da estrutura Conta
struct Conta contas[2] = {{1, "Cliente1", 1000.0},{2, "Cliente2",
500.0}};
int op, cc, cc2;
float valor = 0;
do{
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 67/72
printf("\n BOLSOFURADO BANK \n\n");
printf(" Saldo Conta 1: R$%.2f\n", contas[0].saldo);
printf(" Saldo Conta 2: R$%.2f\n\n", contas[1].saldo);
printf(" 1 - Deposito\n");
printf(" 2 - Saque\n");
printf(" 3 - Transferencia\n");
printf(" 4 - Sair\n");
printf("\n Escolha uma opção: ");
scanf("%d", &op);
switch (op)
{
case 1:
printf("\n Qual a conta para deposito? ");
scanf("%d", &cc);
printf(" Qual o valor? ");
scanf("%f", &valor);
realizarDeposito(&contas[cc-1], valor);
break;
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 68/72
case 2:
printf("\n Qual a conta para saque? ");
scanf("%d", &cc);
printf(" Qual o valor? ");
scanf("%f", &valor);
realizarSaque(&contas[cc-1], valor);
break;
case 3:
printf("\n Qual a conta de origem? ");
scanf("%d", &cc);
printf(" Qual a conta de destino? ");
scanf("%d", &cc2);
printf(" Qual o valor? ");
scanf("%f", &valor);
realizarTransferencia(&contas[cc-1], &contas[cc2-1], valor);
break;
default:
break;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 69/72
Não há uma respostacorreta. Inclusive, fica o desafio para
implementar em cada opção os mecanismos de tratamento de erros,
como a verificação de saldo insuficiente durante saques e
transferências, e mensagens explicativas para o usuário.
Dê o play!
Assimile
O infográfico a seguir ilustra e identifica os conceitos vistos nesta
unidade.
} while(opo tipo de retorno é void, esse parâmetro não
precisa ser utilizado. No entanto, quando não é void, torna-se
obrigatório. É importante que o valor retornado seja compatível
com o tipo de retorno, pois, em algumas linguagens, um erro de
compilação pode resultar se isso não for respeitado, enquanto
em outras pode resultar em um valor impreciso. O valor de
retorno pode ser qualquer expressão que seja legítima de se
colocar no lado direito de uma atribuição (=), por exemplo: o
valor de uma variável; uma constante numérica ou caractere;
ou uma expressão aritmética. Não é possível ter mais de um
retorno em uma função, isto é, somente um valor ou variável
pode ser retornado. E é importante ressaltar que a instrução
return também encerra a execução da função (O programador
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 7/72
deve usar esse comando somente quando não houver mais
nada a fazer dentro da função).
Veja agora um exemplo de função em C no Quadro 2.
Quadro 2 | Exemplo de função em C.
No exemplo apresentado no Quadro 2, a função principal, chamada
main(), é um elemento essencial em muitas linguagens de
programação, como C, Java e C#. Ela atua como o ponto de partida
da execução do programa, definindo a rotina principal que deve ser
executada. Antes do main(), temos a definição da funcão somar().
Em C, é comum criar as funções (também conhecidas como sub-
rotinas) antes da função main() para facilitar o desenvolvimento e a
leitura do código. A função somar() começa na linha 2 e termina na
linha 4, delimitada por chaves. Vamos examinar os parâmetros
nesse caso específico:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
#include
int somar(){
return 2 + 3;
}
int main(){
int resultado = 0;
resultado = somar();
printf("O resultado da função é = %d", resultado);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 8/72
Tipo de retorno: a função foi especificada para retornar um
valor inteiro (int).
Nome: o nome da função é somar.
Comandos da função: nessa função, a soma de dois valores é
retornada em um único comando: return 2 + 3. É importante
notar que cada programador tem a liberdade de criar funções
de acordo com suas preferências. Por exemplo, os comandos
poderiam ter sido escritos da seguinte forma, conforme o
Quadro 3:
Vamos agora analisar o Quadro 3, que apresenta um exemplo de
função com parâmetros.
Quadro 3 | Exemplo de função com parâmetros.
A função do Quadro 3 realiza a soma de dois números inteiros
passados como parâmetros, x e y, e estas duas variáveis são
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
int somar(int x, int y){
int s = 0;
s = x + y;
return s;
}
int main(){
int resultado = somar(4, 5);
printf("O resultado da função é = %d", resultado);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 9/72
utilizados dentro da função para realizar a soma, armazenar em s, e
retornar seu valor. Quando a função é chamada no main() (linha 7),
passamos os valores 4 e 5, que serão atribuídos aos par6ametros x
e y, respectivamente. Portanto, o resultado retornado pela função
será 9 (x + y = 4 + 5).
Siga em Frente...
O uso de funções na linguagem C
Você pode ter observado que uma função tem a capacidade de
retornar valores de diferentes tipos primitivos, como inteiros, reais e
caracteres. No entanto, surge a questão sobre a possibilidade de
retornar um vetor. E a resposta é afirmativa! Para alcançar esse
resultado devemos utilizar os ponteiros!
É importante destacar que não é possível criar funções com uma
sintaxe direta como "int[10] calcular()", onde "int[10]" indica que a
função retorna um vetor com 10 posições. O único meio de retornar
um vetor é através de um ponteiro. Como um ponteiro é um tipo
especial de variável que armazena endereços de memória,
podemos empregar essa abordagem para retornar o endereço de
um vetor. Dessa forma, a função que invocou terá acesso ao vetor
que foi calculado internamente.
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 10/72
Assim, a sintaxe apropriada para essa função é a seguinte:
Observa-se que mesmo ao retornar o nome do vetor, ainda há a
inclusão do tipo primitivo no retorno da função, que é acompanhado
por um asterisco indicando o retorno de um ponteiro, ou seja, um
endereço.
Para ilustrar o uso desse método, vamos implementar uma função
que cria um vetor de cinco posições, preenche-o com valores
aleatórios, imprime esses valores e, em seguida, transmite o vetor
para o chamador da função. A implementação dessa função é
exibida no Quadro 4.
Na linha 14, um ponteiro do tipo inteiro é criado, indicando que ele
apontará para um local que contém um número inteiro. Na linha 15,
uma variável de controle de loop é criada. A função
gerarRandomico() é invocada na linha 16, direcionando a execução
para a linha 3, em que é especificado que a função retornará um
endereço para valores inteiros (int*). Um vetor de números inteiros
com cinco posições é criado na linha 4 e é declarado estático, o que
significa que o valor do vetor não será alterado entre diferentes
chamadas da função.
Um loop é estabelecido na linha 6 para percorrer as cinco posições
do vetor. Em cada posição, um valor aleatório é gerado usando a
função rand() na linha 7, e esse valor é impresso na linha 9 para
futuras comparações. O vetor agora preenchido é retornado pela
* (){
vetor[tamanho];
vetor;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 11/72
função na linha 11, armazenando o endereço obtido no ponteiro p do
programa principal. Outro loop é criado na linha 17 para percorrer o
vetor acessado por seu endereço. Na linha 18, para acessar o
conteúdo do vetor, o comando *(p + i) é utilizado. É importante
lembrar que o ponteiro retorna o endereço da primeira posição do
vetor, por isso é adicionado o valor de i para acessar as próximas
posições.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
#include
#include
int* gerarRandomico(){
static int r[10];
int a;
for(a = 0; a13/72
Armazene o resultado da função na variável criada.
Compare o valor armazenado com a primeira condição para
verificar se o guindaste a ser utilizado é o G1. Se for o caso,
imprima uma mensagem para o usuário.
Crie uma estrutura condicional encadeada com a primeira,
comparando o valor armazenado com a terceira condição, para
determinar se o guindaste a ser utilizado é o G3. Em caso
afirmativo, exiba uma mensagem para o usuário.
Adicione um bloco "senão" ao final, pois se o peso não
corresponder a nenhuma das condições anteriores, o guindaste
a ser utilizado será o G2. Nesse caso, também emita uma
mensagem para o usuário.
Crie uma função para calcular o peso antes da função main().
Declare três variáveis para armazenar os valores da base,
altura e comprimento.
Solicite ao usuário que insira os valores e armazene-os nas
variáveis criadas.
Calcule o peso da coluna usando a fórmula fornecida pelos
engenheiros.
1:
2:
3:
4:
5:
6:
7:
8:
9:
#include
int calcularPeso() {
float b, c, h = 0;
printf("\n Digite o valor da base: ");
scanf("%f", &b);
printf("\n Digite o valor da altura: ");
scanf("%f", &h);
printf("\n Digite o valor do comprimento: ");
scanf("%f", &c);
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 14/72
Quadro 5 | Código de resolução.
Lembrando que não há uma única resposta correta. Há vários
caminhos para se chegar no mesmo resultado! Modifique e tente
otimizar ao máximo os seus programas.
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
return (int) (b * h * c * 25); // o (int) é chamado de “cast” e é
usado para garantir que o valor resultante será inteiro (se não o for,
ele o converte)
}
int main() {
float peso;
peso = calcularPeso();
if (peso 1500) {
printf("\n O guindaste de modelo G3 deve ser usado");
} else {
printf("\n O guindaste de modelo G2 deve ser usado");
}
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 15/72
Saiba Mais
Para entender melhor o conceito de funções e procedimentos em C,
sugerimos a leitura do Capítulo 5 - Funções e Procedimentos, do
livro Linguagem C, disponível na Biblioteca Virtual.
DAMAS, L. Linguagem C. 10. ed. Rio de Janeiro: LTC, 2023. cap. 5,
p. 104-128.
Também sugerimos a leitura do Capítulo 9 - Funções, do livro
Linguagem C: Completa e Descomplicada, disponível na Biblioteca
Virtual, para complementar os estudos sobre funções em C.
BACKES, A. Linguagem C: completa e descomplicada. 2. ed. Rio
de Janeiro: LTC, 2023. cap. 9, p. 158-193.
Para auxiliar no desenvolvimento de programas na linguagem C,
uma ótima prática é verificar a documentação da linguagem para
entender em detalhes os principais tipos de funções e elementos
utilizados. Para isso, sugerimos a constante consulta da seguinte
documentação sempre que achar necessário. Nela você encontra
todas as bibliotecas utilizadas na linguagem e como utilizar suas
principais funções: Referência da Linguagem C.
Referências Bibliográficas
BACKES, A. Linguagem C: completa e descomplicada. 2. ed. Rio
de Janeiro: LTC, 2023. cap. 4, p. 67-87.
DAMAS, L. Linguagem C. 10. ed. Rio de Janeiro: LTC, 2023. cap. 3,
p. 51-79.
PIVA JUNIOR, D. Algoritmos e programação de computadores.
2. ed. Rio de Janeiro: Elsevier, 2019.
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 16/72
https://integrada.minhabiblioteca.com.br/reader/books/9788521632474/epubcfi/6/30[%3Bvnd.vst.idref%3Dchapter05]!/4
https://integrada.minhabiblioteca.com.br/reader/books/9788595152090/epubcfi/6/34[%3Bvnd.vst.idref%3DB9788535291063000092]!/4/2/4/4[B9788535291063000092]/1:5[n%C3%A7%C3%B5%2Ces]
https://integrada.minhabiblioteca.com.br/reader/books/9788595152090/epubcfi/6/34[%3Bvnd.vst.idref%3DB9788535291063000092]!/4/2/4/4[B9788535291063000092]/1:5[n%C3%A7%C3%B5%2Ces]
https://cplusplus.com/reference/
Aula 2
PASSAGEM DE
PARÂMETROS POR VALOR
Passagem de parâmetros por valor
Estudante, esta videoaula foi preparada especialmente para você.
Nela, você irá aprender conteúdos importantes para a sua formação
profissional. Vamos assisti-la?
Ponto de Partida
Olá! Vamos prosseguir nossos estudos sobre procedimentos e
funções conhecendo um pouco mais sobre como trabalhar com os
parâmetros de uma função!
Continuando seu trabalho no laboratório de pesquisa multidisciplinar,
agora é hora de colaborar com o núcleo de química. Em uma reação
química, a relação entre os reagentes é crucial para determinar o
resultado. Dados dois componentes químicos, A e B, sua mistura
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 17/72
resultará em um terceiro composto C (A + B -> C). O núcleo de
química solicitou uma otimização das condições em uma reação
específica denominada "proteção". Para alcançar essa otimização, é
necessário variar as condições do experimento, isto é, utilizando
diferentes massas dos compostos. Um mol do composto A possui
uma massa de 321,43 g, enquanto um mol de B tem uma massa de
150,72 g. É necessário criar uma função que facilite o cálculo dos
produtos químicos. Dessa forma, a partir de diferentes combinações
de massa, seu programa deverá calcular a massa final do composto.
Além do cálculo, o programa deve exibir os resultados das
combinações apresentadas na Tabela 1, uma vez que esses valores
servem como referência para os químicos.
Tabela 1 | Regras para escolha do guindaste.
Para cumprir sua missão, você aprenderá sobre o escopo de
variáveis e a passagem de parâmetros por valor! Agora vamos lá,
preste muita atenção e tenha um excelente estudo!
Vamos Começar!
Escopo de variáveis
Quantidade de
mol de A
Quantidade de
mol de B
Quantidade de
mol de C
1,2 1,0 ?
1,4 1,0 ?
1,0 1,6 ?
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 18/72
Já sabemos que as variáveis servem para armazenar
temporariamente dados na memória. Porém, o local em que elas
são definidas no código de um programa determina o seu alcance e
a sua visibilidade. O código apresentado no Quadro 1 ilustra esse
conceito.
Quadro 1 | Exemplo de escopo de variáveis em C.
Neste exemplo, existem duas variáveis chamadas "x". Isso, no
entanto, não causará nenhum problema, pois apesar de
compartilharem o mesmo nome, elas são definidas em locais
diferentes: uma está dentro da função main() e a outra dentro da
função testar(). Assim, cada função possui seu próprio espaço de
memória independente. Na memória, as variáveis são identificadas
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
#include
int testar(){
int x = 10;
return x;
}
int main(){
int x = 20;
printf("\n Valor de x na funcao main() = %d", x);
printf("\n Valor de x na funcao testar() = %d", testar());
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 19/72
por seus endereços, o que implica que, mesmo com o mesmo
nome, seus endereços são únicos.
Desta forma podemos definir o escopo de uma variável como a
extensão do seu alcance no local no qual o recurso está definido,
permitindo que ele seja acessível em várias partes do código do
programa. O escopo é classificado em duas categorias, local ou
global. No caso do Quadro 1, ambas as variáveis são locais, o que
significa que elas existem e são acessíveis apenas dentro do corpo
da função em que foram definidas. Para criar uma variável global, é
necessáriodeclará-la fora de qualquer função, tornando-a visível
para todas as funções do programa. Por convenção, optamos por
declará-las logo após a inclusão das bibliotecas.
No Quadro 2, é apresentado um exemplo de declaração de uma
variável global na linha 2, logo após a inclusão da biblioteca padrão
. É importante observar que na função principal não há
nenhuma variável definida com o nome "x", no entanto, é possível
imprimir o valor da variável global “x” na linha 7, uma vez que o valor
é acessado globalmente. Na linha 8, é exibido o valor da variável
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 20/72
global que foi modificado pela função "dobrar()", que retorna o
dobro do valor.
Quadro 2 | Exemplo de variável global em C.
Uso de variáveis globais
O uso de variáveis globais permite otimizar a alocação de memória,
já que, em muitos casos, o desenvolvedor não necessita criar
variáveis locais. No entanto, é fundamental ter cautela ao utilizar
essa técnica, uma vez que as variáveis locais são criadas e
destruídas ao final da função, enquanto as variáveis globais
permanecem na memória durante todo o período de execução do
programa.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
#include
int x = 10;
int dobrar(){
return 2 * x;
}
int main(){
printf("\n Valor de x global = %d", x);
printf("\n Valor de x global alterado na função dobrar() = %d",
dobrar());
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 21/72
Vamos considerar um exemplo prático que demonstra a utilização do
escopo global de uma variável. No Quadro 3 temos um programa
que calcula a média entre duas temperaturas distintas e que possui
a declaração de duas variáveis globais na linha 2. É importante
lembrar que o programa começa sempre pela função principal, cuja
execução tem início na linha 6. Na linha 7, o usuário é solicitado a
digitar duas temperaturas, que são armazenadas dentro das
variáveis globais criadas. Na linha 9, a função "calcularMedia()" é
chamada para realizar o cálculo da média usando os valores das
variáveis globais. Neste exemplo, fica evidente a utilidade dessa
abordagem de programação, já que as variáveis são usadas em
diferentes funções, otimizando o uso da memória, uma vez que não
é necessário criar mais variáveis locais em cada uma das funções.
Quadro 3 | Exemplo prático de variável global em C.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
#include
float t1, t2;
float calcularMedia(){
return (t1 + t2) / 2;
}
int main(){
printf("\n Digite as duas temperaturas: ");
scanf("%f %f", &t1, &t2);
printf("\n A temperatura média = %.2f", calcularMedia());
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 22/72
Nós já vimos que é viável criar variáveis com o mesmo nome em
diferentes funções, visto que o escopo delas é local. Entretanto, e se
houver uma variável global e uma local com o mesmo nome, como
no exemplo a seguir?
Qual valor será impresso na variável "x"? A variável local sempre
substituirá o valor da global, e, nesse caso, o valor -1 será impresso
na função principal.
Mas e se você precisar acessar o valor de uma variável global
dentro de uma função que possui uma variável local com o mesmo
nome? Neste caso, é necessário utilizar a instrução "extern". No
Quadro 4, é possível observar como usar variáveis globais e locais
com o mesmo nome na linguagem C. Note que foi preciso criar uma
variável chamada "b", com um bloco de instruções (linhas 6 – 9),
que atribui o valor "externo" de "x" à nova variável. A criação do
bloco é necessário para separar o trecho de código do restante da
int x = 10;
int main(){
int x = -1;
printf("\n Valor de x = %d", x);
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 23/72
função main(), indicando que ali, a variável “x” utilizada é a global
(extern int x).
Quadro 4 | Exemplo de acesso a uma variável global com extern em
C.
Siga em Frente...
Passagem de parâmetros por valor
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
#include
int x = 10;
int main(){
int x = -1;
int b;
{
extern int x;
b = x;
}
printf(“\n Valor de x = %d”, x);
printf(“\n Valor de b (x global) = %d”, b);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 24/72
Vamos relembrar que, ao criar funções em linguagens de
programação, usamos a seguinte estrutura básica:
Todos os elementos dessa estrutura já foram apresentados
detalhadamente até aqui, exceto os tipos de parâmetros que uma
função pode receber. Portanto, neste momento, vamos nos
concentrar em compreender esse recurso fundamental.
Ao definir uma função, podemos também especificar que ela
receberá informações do chamador (ou seja, “de quem” a invocou).
Por exemplo, ao criar uma função para calcular a média, é possível
estabelecer que o chamador (“quem chama”) deve fornecer os
valores sobre os quais o cálculo será realizado.
Na sintaxe de criação de uma função que recebe parâmetros, é
fundamental especificar o tipo de valor que será recebido. Uma
função pode receber parâmetros na forma de valor ou referência. Ao
passar parâmetros por valores, a função cria automaticamente
variáveis locais para armazenar esses valores e, após a conclusão
da função, essas variáveis são liberadas. A Figura 1 apresenta uma
ilustração do processo de passagem de parâmetros por valor em
uma função.
()
{
(opcional)
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 25/72
Figura 1 | Processo de passagem de parâmetros por
valor.
No Quadro 5, é apresentado um exemplo de definição e chamada
de função com passagem de valores. Na linha 2, a função "somar()"
é definida para receber dois valores inteiros. Internamente, as
variáveis locais "a" e "b" são criadas para armazenar esses valores
até o término da função. Na linha 7, a função "somar" é
invocada/chamada, passando os dois valores inteiros que a função
espera receber, e o resultado do cálculo é armazenado na variável
"res".
Quadro 5 | Exemplo de passagem de parâmetros por valor.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
#include
int somar(int a, int b){
return a + b;
}
int main(){
int re;
res = somar(10, 15);
printf("\n Resultado da soma = %d", res);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 26/72
A técnica de passagem de parâmetros para uma função é
amplamente utilizada em todas as linguagens de programação. Ao
chamar uma função que espera receber parâmetros, a omissão de
qualquer argumento esperado resultará em um erro de compilação.
Quando usamos variáveis como argumentos na passagem de
parâmetros por valores, as variáveis originais não são modificadas,
uma vez que uma cópia dos valores armazenados é fornecida à
função. Para entender claramente essa definição, consideremos o
código apresentado no Quadro 6. A execução do programa começa
na linha 9, na função principal, em que são criadas duas variáveis,
"n1" e "n2". Na linha 13, o comando determina a impressão dos
valores das variáveis. Em seguida, na linha 14, a função "testar()" é
invocada, passando as duas variáveis como parâmetros. Nesse
momento, uma cópia de cada variável é criada na memória para o
uso da função.Dentro da função, o valor das cópias das variáveis é
alterado e impresso, porém essa alteração é local, ou seja, é
realizada apenas nas cópias dos valores e não afetará os valores
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 27/72
iniciais das variáveis criadas na função principal. Na linha 16, os
valores são impressos novamente após a chamada da função.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
#include
int testar(int n1, int n2){
n1 = -1;
n2 = -2;
printf("\n\n Valores dentro da função testar(): ");
printf("\n n1 = %d e n2 = %d", n1, n2);
return 0;
}
int main(){
int n1 = 10;
int n2 = 20;
printf("\n\n Valores antes de chamar a função: ");
printf("\n n1 = %d e n2 = %d", n1, n2);
testar(n1, n2);
printf("\n\n Valores depois de chamar a função: ");
printf("\n n1 = %d e n2 = %d", n1, n2);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 28/72
Quadro 6 | Exemplo de passagem de parâmetros por valor.
A seguir, a Figura 2 apresenta o resultado deste programa.
Figura 2 | Resultado do programa do Quadro 6.
Vamos Exercitar?
Prezado estudante, é hora de aplicar todo o conhecimento adquirido
até aqui! Para implementar a solução para a equipe de química, é
possível criar uma função que tome como entrada a quantidade em
mol dos componentes A e B e retorne a massa da reação.
O passo inicial consiste em criar a função de cálculo da massa. Ela
pode ser definida da seguinte maneira:
Dentro dessa função, os valores de referência devem ser exibidos
de acordo com a Tabela 1. A massa deve ser calculada e o resultado
deve ser retornado.
Em seguida, é necessário criar a função principal, na qual o usuário
será solicitado a fornecer as quantidades dos elementos A e B. Uma
vez que os valores forem obtidos, a função “calcularMassa()” deve
ser chamada e os valores devem ser passados como argumentos.
float calcularMassa(float quantidadeA, float quantidadeB)
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 29/72
O resultado da função deve ser armazenado em uma variável, da
seguinte maneira:
Por último, a massa da reação deve ser exibida.
resultado = calcularMassa(quantidadeA, quantidadeB)
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 30/72
O Quadro 7 apresenta uma sugestão de resolução da situação.
Quadro 7 | Código de resolução.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
#include
float calcularMassa(float a, float b){
const float mA = 321.43;
const float mB = 150.72;
printf("\n mol A : mol B ");
printf("\n 1,2 : 1,0 \t= %f",1.2*mA + 1*mB);
printf("\n 1,4 : 1,0 \t= %f",1.4*mA + 1*mB);
printf("\n 1,6 : 1,0 \t= %f",1*mA + 1.6*mB);
return (a * mA ) + (b * mB);
}
int main(){
float a = 0, b = 0, resultado = 0;
printf("\n Digite as massas dos elementos A e B: ");
scanf("%f %f",&a,&b);
resultado = calcularMassa(a,b);
printf("\n\n Massa final do composto = %.2f g/mol",resultado);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 31/72
Lembrando que não há uma única resposta correta. Há vários
caminhos para se chegar no mesmo resultado! Modifique e tente
otimizar ao máximo os seus programas.
Saiba Mais
Para entender melhor o conceito de funções e parâmetros em C,
sugerimos a leitura do Capítulo 5 funções e Procedimentos, do livro
Linguagem C, disponível na Biblioteca Virtual.
DAMAS, L. Linguagem C. 10. ed. Rio de Janeiro: LTC, 2023. cap. 5,
p. 104-128.
Também recomendamos a leitura do Capítulo 9 - PAssagem de
Parâmetors, do mesmo livro, Linguagem C, disponível na Biblioteca
Virtual. Ele traz um estudo mais detalhado sobre passagem de
parâmetros em C.
DAMAS, L. Linguagem C. 10. ed. Rio de Janeiro: LTC, 2023. cap. 9,
p. 203-227.
Sugerimos a leitura do Capítulo 9 - Funções do livro Linguagem C:
Completa e Descomplicada, disponível na Biblioteca Virtual, para
complementar os estudos sobre funções e parâmetros em C.
BACKES, A. Linguagem C: completa e descomplicada. 2. ed. Rio
de Janeiro: LTC, 2023. cap. 9, p. 158-193.
Referências Bibliográficas
BACKES, A. Linguagem C: completa e descomplicada. 2. ed. Rio
de Janeiro: LTC, 2023. cap. 4, p. 67-87.
DAMAS, L. Linguagem C. 10. ed. Rio de Janeiro: LTC, 2023. cap. 3,
p. 51-79.
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 32/72
https://integrada.minhabiblioteca.com.br/reader/books/9788521632474/epubcfi/6/30[%3Bvnd.vst.idref%3Dchapter05]!/4
https://integrada.minhabiblioteca.com.br/reader/books/9788521632474/epubcfi/6/30[%3Bvnd.vst.idref%3Dchapter05]!/4
https://integrada.minhabiblioteca.com.br/reader/books/9788595152090/epubcfi/6/34[%3Bvnd.vst.idref%3DB9788535291063000092]!/4/2/4/4[B9788535291063000092]/1:5[n%C3%A7%C3%B5%2Ces]
https://integrada.minhabiblioteca.com.br/reader/books/9788595152090/epubcfi/6/34[%3Bvnd.vst.idref%3DB9788535291063000092]!/4/2/4/4[B9788535291063000092]/1:5[n%C3%A7%C3%B5%2Ces]
PIVA JUNIOR, D. Algoritmos e programação de computadores.
2. ed. Rio de Janeiro: Elsevier, 2019.
Aula 3
PASSAGEM DE
PARÂMETROS POR
REFERÊNCIA
Passagem de parâmetros por
referência
Estudante, esta videoaula foi preparada especialmente para você.
Nela, você irá aprender conteúdos importantes para a sua formação
profissional. Vamos assisti-la?
Ponto de Partida
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 33/72
Olá! Vamos prosseguir nossos estudos sobre procedimentos e
funções conhecendo um pouco mais sobre como trabalhar com
passagem de parâmetros por referência!
Vamos considerar que você tem um amigo que possui loja que
vende diferentes tipos de produtos, e ele te pediu uma ajuda! Seu
amigo precisa de um programa em C para calcular o preço total de
uma compra, levando em consideração os preços unitários e as
quantidades de cada item adquirido. O programa deve usar funções
para calcular o preço total e passar parâmetros por referência para
garantir a atualização correta das variáveis.
Para cumprir sua missão, você irá aprender sobre a passagem de
parâmetros por referência! Agora vamos lá, preste muita atenção e
tenha um excelente estudo!
Vamos Começar!
Passagem por referência com ponteiros
O uso de funções que passam parâmetros por referência está
intimamente relacionado aos conceitos de ponteiros e endereços de
memória. A abordagem dessa técnica é semelhante à passagem por
valor, na qual a função é definida para receber determinados
parâmetros, e o chamador deve fornecer esses argumentos. No
entanto, o comportamento e o resultado diferem. Na passagem por
referência, não é criada uma cópia dos argumentos passados; em
vez disso, o endereço da variável é passado e a função manipula
diretamente os valores armazenados lá.
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 34/72
Para utilizar essa abordagem, precisamos dos operadores * e &. Na
definição da função, os parâmetros a serem recebidos devem ser
declarados com *, por exemplo:
E ao chamar a função, os parâmetros devem ser passados com &,
por exemplo:
No exemplo apresentado no Quadro 1, temos uma função que
passa variáveis por referência. Com a passagem por referência, os
valores das variáveis são modificados. Nas linhas 3 e 4, o asterisco
éusado para acessar o conteúdo armazenado dentro do endereço
int testar(int* parametro1, int* parametro2)
resultado = testar(&n1, &n2)
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 35/72
apontado, pois se usássemos apenas n1 e n2, estaríamos
acessando os endereços que eles apontam.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
#include
int testar(int* n1, int* n2) {
*n1 = -1; // é necessário usar * para acessar o conteúdo
*n2 = -2;
printf("\n\n Valores dentro da função testar(): ");
printf("\n n1 = %d e n2 = %d", *n1, *n2);
return 0;
}
int main() {
int n1 = 10;
int n2 = 20;
printf("\n\n Valores antes de chamar a função: ");
printf("\n n1 = %d e n2 = %d", n1, n2);
testar(&n1, &n2);
printf("\n\n Valores depois de chamar a função: ");
printf("\n n1 = %d e n2 = %d", n1, n2);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 36/72
Quadro 1 | Exemplo de passagem de parâmetros por referência.
Neste exemplo, a função testar() recebe dois argumentos que são
ponteiros para inteiros. Dentro da função, os valores apontados por
esses ponteiros são alterados para -1 e -2, respectivamente. A
seguir, a Figura 1 apresenta o resultado deste programa, ilustrando
como os valores das variáveis mudam antes e depois da chamada
da função testar.
Figura 1 | Resultado do programa do Quadro 1.
A passagem de parâmetros por referência possui várias vantagens e
desvantagens que afetam a eficiência e o desempenho de um
programa. Uma das principais vantagens é a capacidade de
transmitir uma grande quantidade de dados para outras partes do
programa. Em vez de fazer cópias dos dados e transmitir essas
cópias, é possível passar apenas um ponteiro para esses dados, o
que economiza tempo, processamento e memória. Além disso, essa
abordagem permite a alteração de uma variável ou um objeto
externo a uma função, o que possibilita que uma função gere vários
valores de saída.
Por outro lado, a passagem por referência pode comprometer a
segurança, já que a função chamada pode corromper os dados do
chamador. Assim, é essencial ter cuidado ao utilizar a passagem por
referência para garantir que os dados não sejam modificados
indevidamente por funções chamadas.
Passagem de vetores e matrizes
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 37/72
Agora, vamos compreender como passar um vetor para uma função,
para que possamos preencher e imprimir o conteúdo armazenado
em um vetor, evitando a repetição de trechos de código. Na
linguagem C, a passagem de um vetor é sempre realizada
implicitamente por referência. Isso implica que, mesmo sem o uso
dos operadores "*" e "&", quando uma função que recebe um vetor é
invocada, o que é realmente passado é o endereço da primeira
posição do vetor.
Na definição da função, os vetores a serem recebidos devem ser
declarados com colchetes, sem especificar o tamanho, por exemplo:
Ou ainda, você pode especificar os parâmetros da função como
ponteiros:
Ao chamar a função, independente da forma escolhida para definir
os vetores nos parâmetros, estes devem ser passados como se
fossem variáveis simples, por exemplo:
Para ilustrar esse conceito, é apresentado um programa no Quadro
2, iniciando na linha 15. Na linha 18, a função “inserir()” é chamada,
passando o vetor "numeros" como parâmetro. Deliberadamente, a
função é definida na linha 2, recebendo um vetor chamado "a", para
demonstrar que o nome da variável na função não precisa ser o
int testar1(int v1[ ], int v2[ ])
int testar2(int *v1, int *v2)
resultado1 = testar1(n1, n2);
resultado2 = testar2(n1, n2);
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 38/72
mesmo usado na chamada. Geralmente, é uma boa prática de
programação utilizar o mesmo nome. Na função “inserir()”, é
solicitado ao usuário digitar os valores que serão armazenados no
vetor "numeros" por referência. Após a conclusão dessa função, a
execução continua na linha 18 e depois na 19, na qual a função
“imprimir()” é invocada, passando o vetor "numeros" como
argumento. Mais uma vez, é definida uma função na linha 9 com o
nome de vetor diferente para enfatizar que não é necessário ser o
mesmo nome. Nessa função, o vetor é percorrido e o dobro de cada
valor é impresso. O resultado desse programa é ilustrado na Figura
2.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
#include
void inserir(int a[]){
int i=0;
for(i=0; i" em função de ser um
ponteiro.
void testeMatriz(int mat[3][3])
testeMatriz(m); //onde m é uma matriz
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 41/72
O Quadro 3 mostra um exemplo de como passar uma struct por
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 42/72
referência.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
#include
struct Pessoa {
char nome[50];
int idade;
};
void modificarPessoa(struct Pessoa *p) {
p->idade = 30;
}
int main() {
struct Pessoa pessoa1;
strcpy(pessoa1.nome, "João");
pessoa1.idade = 25;
modificarPessoa(&pessoa1);printf("Nome: %s\n", pessoa1.nome);
printf("Idade: %d\n", pessoa1.idade);
return 0;
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 43/72
Quadro 3 | Exemplo de passagem de struct por referência.
Neste exemplo, a função “modificarPessoa” recebe um ponteiro
para uma estrutura “struct Pessoa” como parâmetro. Dentro da
função, o valor do membro "idade" é modificado para 30. A estrutura
é passada para a função usando o operador de referência "&" na
chamada da função. A impressão dos valores da estrutura após a
modificação mostra que a estrutura original foi de fato alterada
dentro da função.
Vamos Exercitar?
Prezado estudante, é hora de aplicar todo o conhecimento adquirido
até aqui! Para implementar a solução para a loja do seu amigo você
21: }
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 44/72
precisará trabalhar com a passagem de parâmetros por referência!
O Quadro 4 apresenta uma sugestão de resolução da situação.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
#include
void calcularPrecoTotal(float precoUnitario[], int quantidade[], int
numItens, float *precoTotal) {
*precoTotal = 0;
for (int i = 0; ide uma função recursiva não difere
significativamente das funções convencionais, pois requer um tipo
de retorno, o nome da função, parênteses e parâmetros, quando
necessário. A diferença está no conteúdo da função, pois ela é
invocada dentro de si mesma. No trecho de código abaixo temos a
construção da função, bem como o seu chamado, primeiro na
função principal e, em seguida, dentro dela mesma.
Apesar da semelhança na estrutura entre funções recursivas e não
recursivas, o comportamento entre elas difere significativamente, e o
uso impróprio dessa técnica pode levar a problemas de consumo
funcaoRecursiva(){
// comandos
funcaoRecursiva(); // chamando a si própria
// comandos
}
void main(){
// comandos
funcaoRecursiva();
// comandos
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 50/72
excessivo de memória, frequentemente resultando em falhas na
aplicação e no sistema. Para uma compreensão mais completa do
processo, é importante destacar alguns pontos-chave:
A função recursiva chama a si mesma repetidamente até que
um ponto de parada seja alcançado. Esse ponto pode ser
definido por meio de uma estrutura condicional ou por um valor
fornecido pelo usuário.
Dentro do corpo de uma função, existem variáveis e comandos
que são armazenados na memória de trabalho. No caso de
uma função recursiva, os recursos (variáveis e comandos) são
alocados em locais distintos da memória, resultando na criação
de novas instâncias a cada chamada da função. Portanto, é
crucial definir um ponto de parada adequado.
As variáveis geradas em cada instância da função na memória
são independentes. Assim, mesmo que as variáveis possuam
os mesmos nomes, cada uma possui seu próprio endereço de
memória, garantindo que a alteração de valores em uma não
afete as outras.
Para facilitar a compreensão desse mecanismo, observe a Figura 1.
A instância 1 representa a primeira chamada da função
“funcaoRecursiva()”, que, por sua vez, contém um comando que
invoca a si mesma. Nesse ponto, uma segunda instância da função
é criada na memória de trabalho. Conforme a função continua a se
chamar recursivamente, novos espaços de memória são alocados,
cada um contendo suas próprias variáveis e comandos. No entanto,
quando uma determinada condição de parada é atingida dentro da
terceira instância, a função deixa de ser chamada e passa a retornar
valores para as instâncias anteriores.
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 51/72
Figura 1 | Mecanismo de uma função recursiva na memória.
Quando a função recursiva atinge o ponto de parada, cada
execução subsequente passa a devolver seus resultados à
execução anterior. No exemplo da Figura 2, a execução três retorna
à execução dois, que por sua vez retorna à execução um. É
importante notar que, caso o ponto de parada não fosse
especificado na última chamada, a função se instanciaria
continuamente, resultando em um estouro de memória.
Toda função recursiva necessita obrigatoriamente de uma instância
que determine o encerramento das chamadas subsequentes,
denominada caso base. Este representa o cenário mais simples
que leva à interrupção do processo.
Refletindo sobre isso, é obrigatório para qualquer função recursiva
ter um critério de parada bem definido. A instância que satisfaz esse
critério é conhecida como caso base. Um programador que
erroneamente implementa o critério de parada pode ocasionar um
erro apenas na aplicação dessa função específica, ou tal erro pode
impactar outras partes do sistema.
Como funciona a recursividade
Para ilustrar como funciona uma função recursiva, considere a
implementação de uma função recursiva que calcula a soma dos
antecessores de um número inteiro positivo inserido pelo usuário.
Por exemplo, se o usuário inserir 5, o programa deve calcular a
soma 5 + 4 + 3 + 2 + 1 + 0. Neste caso, o critério de parada é
alcançado quando o parâmetro de soma atinge o valor zero,
significando que todos os números anteriores já foram considerados
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 52/72
para o cálculo. A implementação da função pode ser visualizada no
Quadro 1, seguida pela explicação.
Quadro 1 | Exemplo de função recursiva.
A execução do programa no Quadro 1 tem início na linha 9, pela
função principal. Ao chegar na linha 13, a função “somar()” é
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
#include
int somar(int valor) {
if (valor != 0) { // Critério de parada
return valor + somar(valor - 1); // Chamada recursiva
} else {
return valor;
}
}
int main() {
int n, resultado;
printf("\nDigite um numero inteiro positivo: ");
scanf("%d", &n);
resultado = somar(n); // Fazendo a primeira chamada da função
printf("\nResultado da soma = %d", resultado);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 53/72
chamada, recebendo como argumento um número inteiro inserido
pelo usuário. Nesse ponto, a execução se desloca para a linha 2,
onde a função é definida. Nota-se que a função é configurada para
retornar e receber valores inteiros. Na linha 3, é utilizado um
condicional como critério de parada. Se o valor for diferente (!=) de
zero, a execução segue para a linha 4, na qual a função é chamada
novamente, desta vez com o parâmetro sendo o valor reduzido em
1. Quando o valor atinge zero, as instâncias começam a retornar o
valor para a instância que as chamou.
Para ilustrar, a Figura 2 demonstra o processo na memória de
trabalho da função “somar()”. Neste exemplo, o usuário inseriu o
valor 2, resultando na invocação da função “somar(2)” pela função
main(). A primeira instância é criada com o parâmetro 2. Como o
valor é diferente de zero nessa instância, o critério de parada não é
satisfeito, e a função se chama a si mesma, criando a segunda
instância com o parâmetro 1.
Figura 2 | Exemplo da função somar() do Quadro 1.
Observa-se que, na primeira instância, o valor a ser retornado é 2 +
?, pois o resultado da função ainda não é conhecido. Na segunda
instância, o valor também difere de zero, levando à chamada
recursiva com o parâmetro zero (valor - 1). Nesse ponto, o retorno é
1 + ?, pois o resultado da função ainda não é determinado. Na
terceira instância, o critério de parada é alcançado, e a função
retorna zero. Este valor é utilizado pela instância anterior, que, ao
somar 1 + 0, retorna seu resultado para a instância 1, que por sua
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 54/72
vez soma 2 + 1 e retorna o valor à função principal, encerrando o
ciclo de recursividade.
Quadro 1 | Exemplo de função recursiva.
Vamos agora analisar o exemplo clássico da recursividade: o cálculo
do fatorial! O fatorial de um número N é obtido por meio de
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
#include
int somar(int valor) {
if (valor != 0) { // Critério de parada
return valor + somar(valor - 1); // Chamada recursiva
} else {
return valor;
}
}
int main() {
int n, resultado;
printf("\nDigite um numero inteiro positivo: ");
scanf("%d", &n);
resultado = somar(n); // Fazendo a primeira chamada da função
printf("\nResultado da soma = %d", resultado);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 55/72
multiplicações sucessivas até que N seja igual a 1, representado
como N! = N * (N-1) * (N-2) * ... * 2 * 1. Por exemplo,5! = 5*4*3*2*1
= 120. A seguir está o código, no Quadro 2, que implementa essa
solução utilizando uma função recursiva, seguido pela explicação.
Quadro 2 | Cálculo do fatorial com uma função recursiva.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
#include
int fatorial(int valor) {
if (valor > 0) { // Critério de parada
return valor * fatorial(valor - 1); // Chamada recursiva
} else {
return 1;
}
}
int main() {
int n, resultado;
printf("\nDigite um numero inteiro positivo: ");
scanf("%d", &n);
resultado = fatorial(n);
printf("\nResultado do fatorial = %d", resultado);
return 0;
}
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 56/72
A execução do código no Quadro 2 inicia pela função main(), que
solicita um número ao usuário e, na linha 13, invoca a função
“fatorial()”, passando o valor digitado como parâmetro. Dentro da
função “fatorial()”, enquanto o valor for maior que 0, a função
chama a si mesma, criando novas instâncias na memória,
passando, a cada vez, o valor decrementado de 1. Quando o valor
chega a 0, a função retorna 1 e este valor é retornado à
multiplicação dos valores encontrados em cada instância. Isso
porque 0! é o caso mais básico, o qual nós sabemos que é igual a 1
sem fazer qualquer tipo de conta, ou seja, o caso base!
Para uma melhor compreensão, a Figura 3 ilustra as instâncias
quando o usuário digita o número 2. Os resultados só são obtidos
quando a função atinge o caso base e, então, inicia o processo de
"devolução" do resultado para a instância anterior.
Figura 3 | Exemplo da função fatorial() do Quadro 2.
Siga em Frente...
Cuidados na implementação da
recursividade
Agora, uma pergunta para você: Daria para refazer o programa do
Quadro 1 sem recursividade, apenas com um laço simples? Sim!
Uma das principais dúvidas entre os programadores está justamente
na escolha entre o uso de recursividade e as estruturas de
repetição. No caso da função “somar()” apresentada no Quadro 1,
23/11/24, 13:47 Funções e Passagem de Parâmetros
https://alexandria-html-published.platosedu.io/c4476d40-9b4d-4e54-b006-e3db9f2cedc9/v1/index.html 57/72
seria possível substituí-la por uma estrutura de repetição, como
exemplificado a seguir:
De fato, a substituição é viável. A técnica de recursividade pode ser
empregada para substituir estruturas de repetição, conferindo uma
elegância ao código sob a perspectiva das boas práticas de
programação. No entanto, como mencionado anteriormente, funções
recursivas têm o potencial de consumir mais memória em
comparação com abordagens iterativas.
Para esclarecer o momento adequado para escolher a
recursividade, podemos nos valer de algumas orientações: muitos
problemas exibem a propriedade de possuir uma estrutura recursiva,
na qual cada instância do problema contém uma versão menor do
mesmo problema. Nesses casos, o método recomendado é:
Resolver diretamente a instância do problema se ela for
pequena, utilizando força bruta se necessário.
Caso contrário, reduzir a instância para uma versão menor do
mesmo problema, aplicar o método à instância menor e, em
seguida, retornar à instância original.
A aplicação desse método resulta em um algoritmo recursivo,
indicando a capacidade de um problema maior ser decomposto em
instâncias menores. Contudo, é crucial considerar os recursos
computacionais envolvidos em cada método ao optar pela
recursividade.
for (i = 0; i
#include
float calcularRaiz(float n, float raizAnt) {
float raiz = (pow(raizAnt, 2) + n) / (2 * raizAnt);
if (fabs(raiz - raizAnt)