Funções — Básico
Funções são como receitas na cozinha — dê os ingredientes (parâmetros), elas seguem os passos para processá-los e servem um prato (valor de retorno). Encapsular lógica repetida em funções mantém o código limpo e eficiente.
Definição de função
Uma definição de função consiste de quatro partes: tipo de retorno, nome da função, lista de parâmetros e corpo da função.
int add(int a, int b) {
return a + b;
}
int: o tipo de retorno, indicando o tipo do resultado da funçãoadd: o nome da função, usado na chamada(int a, int b): a lista de parâmetros, recebendo dados de quem chamou{ return a + b; }: o corpo da função, executando a lógica real
Se não há parâmetros, escreva void na lista de parâmetros:
int get_value(void) {
return 42;
}
Chamada de função
Para chamar uma função, coloque parênteses após o nome da função e passe os argumentos:
int result = add(3, 5);
printf("%d\n", result);
Ao ser chamada, o programa salta para o corpo da função, executa-o e retorna ao ponto da chamada ao encontrar return ou chegar ao fim da função.
Funções podem ser aninhadas — o valor de retorno de uma função pode servir como argumento para outra:
int x = add(add(1, 2), add(3, 4));
Isso equivale a add(3, 7), resultando em 10.
Parâmetros e valores de retorno
Parâmetros vs Argumentos
As variáveis nos parênteses da definição de função são chamadas parâmetros (parâmetros formais). Os valores passados na chamada são chamados argumentos (parâmetros reais).
int square(int n) {
return n * n;
}
int main(void) {
int x = 5;
int y = square(x);
return 0;
}
n é um parâmetro, x é um argumento. Parâmetros são variáveis locais dentro da função; o valor do argumento é copiado para o parâmetro — isso é "passagem por valor". Modificar o parâmetro dentro da função não afeta o argumento.
void try_change(int n) {
n = 100;
}
int main(void) {
int x = 5;
try_change(x);
printf("%d\n", x);
return 0;
}
A saída ainda é 5, porque n é apenas uma cópia de x.
Valores de retorno
Uma função retorna um resultado a quem a chamou através do comando return. O tipo de retorno deve corresponder à declaração da função:
double circle_area(double r) {
return 3.14159 * r * r;
}
Uma função pode retornar uma expressão diretamente sem armazená-la em uma variável primeiro. Uma vez que return é executado, a função termina imediatamente; o código subsequente não é executado:
int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
Declaração de função (protótipo)
Se uma função é definida após o ponto onde é chamada, o compilador não reconhece o nome da função e produzirá um erro ou assumirá implicitamente que ela retorna int. A solução é declarar o protótipo da função antes da chamada:
int add(int a, int b);
int main(void) {
int result = add(3, 5);
return 0;
}
int add(int a, int b) {
return a + b;
}
Uma declaração inclui apenas o cabeçalho seguido de ponto e vírgula; o corpo da função não é necessário. Os nomes dos parâmetros podem ser omitidos:
int add(int, int);
No entanto, manter os nomes dos parâmetros melhora a legibilidade e é recomendado.
Funções void
Funções que não precisam retornar um valor usam void como tipo de retorno:
void print_line(int len) {
int i;
for (i = 0; i < len; i++) {
printf("-");
}
printf("\n");
}
Em uma função void, return pode ser omitido, ou return; pode ser usado para sair antecipadamente:
void greet(int hour) {
if (hour < 0 || hour > 23) {
return;
}
if (hour < 12) {
printf("Good morning\n");
} else {
printf("Good afternoon\n");
}
}
void não pode retornar um valor; return 5; causará erro de compilação. Da mesma forma, todo caminho de execução em uma função não-void deve ter um return com o tipo correto.
Exemplo
Determine se um inteiro é par:
#include <stdio.h>
int is_even(int n) {
return n % 2 == 0;
}
int main(void) {
int nums[] = {3, 4, 7, 8, 11, 16};
int i;
int len = sizeof(nums) / sizeof(nums[0]);
for (i = 0; i < len; i++) {
printf("%d is %s\n", nums[i], is_even(nums[i]) ? "even" : "odd");
}
return 0;
}
3 is odd
4 is even
7 is odd
8 is even
11 is odd
16 is even
O comando return em detalhes
Uma função pode ter múltiplos comandos return, mas apenas um é executado por chamada. return tem dois efeitos:
- Retornar um valor a quem chamou
- Terminar imediatamente a execução da função
const char *grade(int score) {
if (score >= 90) return "Excellent";
if (score >= 80) return "Good";
if (score >= 60) return "Pass";
return "Fail";
}
O valor de retorno é copiado para o ponto da chamada. Para tipos básicos (int, double, etc.), o custo da cópia é insignificante. Após uma função retornar, suas variáveis locais não existem mais, então você não deve retornar um ponteiro para uma variável local.
Funções com múltiplos parâmetros
Uma função pode ter múltiplos parâmetros, separados por vírgulas. O número e os tipos dos argumentos devem corresponder exatamente aos parâmetros:
double bmi(double weight, double height) {
return weight / (height * height);
}
Os argumentos são correspondidos aos parâmetros por posição:
double result = bmi(70.0, 1.75);
Exemplo
Calcule o número de dias entre duas datas (versão simplificada, ignorando anos bissextos e diferenças de meses, apenas demonstrando funções com múltiplos parâmetros):
#include <stdio.h>
int day_of_year(int year, int month, int day) {
int days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int total = 0;
int m;
for (m = 1; m < month; m++) {
total += days_in_month[m];
}
total += day;
return total;
}
int days_between(int y1, int m1, int d1, int y2, int m2, int d2) {
int first = day_of_year(y1, m1, d1);
int second = day_of_year(y2, m2, d2);
int diff = second - first;
if (diff < 0) diff = -diff;
return diff;
}
int main(void) {
int d = days_between(2025, 3, 1, 2025, 6, 15);
printf("%d days apart\n", d);
return 0;
}
106 days apart
❓ Perguntas Frequentes
P: Um parâmetro pode ter o mesmo nome que um argumento? R: Sim, são variáveis em escopos diferentes e não afetam uma à outra. No entanto, para evitar confusão, é recomendável usar nomes diferentes.
P: Uma função pode omitir o tipo de retorno? R: Em C89, omitir o tipo de retorno assume int como padrão. C99 e posteriores exigem um tipo de retorno explícito. Sempre especificar o tipo de retorno é um bom hábito.
P: Qual a utilidade de
return;em uma função void? R: É usado para sair da função antecipadamente, ignorando a lógica subsequente. É semelhante aobreakem um laço.
P: Uma função pode retornar múltiplos valores? R: Uma função C só pode retornar um valor. Para retornar múltiplos resultados, use parâmetros de ponteiro, structs ou vetores.
📖 Resumo
- Uma função consiste de tipo de retorno, nome da função, lista de parâmetros e corpo da função
- Argumentos são copiados para os parâmetros (passagem por valor); modificar parâmetros dentro da função não afeta os argumentos
- Uma função deve ser declarada ou definida antes de ser chamada; uma declaração de protótipo é suficiente
- Funções void não retornam valor; use
return;para sair antecipadamente - O comando return termina imediatamente a função e envia um valor de volta a quem chamou
📝 Exercícios
- Escreva uma função
int max3(int a, int b, int c)que retorne o maior de três inteiros. - Escreva uma função
void swap_wrong(int a, int b)que tente trocar dois valores. Verifique em main se obteve sucesso, e explique o porquê. - Escreva uma função
int digit_sum(int n)que calcule a soma dos dígitos de um inteiro positivo (ex.: 123 retorna 6). Teste-a em main.



