Carregando
0x70Lição 8 de 20

Funções

Divida os programas em pedaços reutilizáveis e com nome - e aprenda por que as funções em C recebem cópias dos seus argumentos.

14 min Questionário com 5 perguntas 2 exercícios de código
Ao final desta lição, você saberá
  • Definir funções com parâmetros e valores de retorno
  • Declarar funções com protótipos
  • Explicar a passagem por valor e o escopo das variáveis

Uma função é um bloco de código com nome que faz uma tarefa. Você já usou o printf e escreveu a main; agora vai escrever as suas próprias. As funções deixam você dar nome a uma ideia uma vez e reutilizá-la, e mantêm cada parte de um programa pequena o bastante para ser entendida.

Definindo e chamando

square.c
1#include <stdio.h>
2
3int square(int x) {
4    return x * x;
5}
6
7int main(void) {
8    int result = square(7);
9    printf("7 squared is %d\n", result);
10    printf("3 squared is %d\n", square(3));
11    return 0;
12}
Saída
7 squared is 49
3 squared is 9

Lendo int square(int x) da esquerda para a direita:

  • int é o tipo de retorno: o tipo de valor que a função devolve.
  • square é o nome.
  • (int x) é a lista de parâmetros: square recebe um int, chamado x dentro da função.

return x * x; encerra a função e manda o valor de volta para quem chamou. Uma função que não devolve nada tem o tipo de retorno void; uma que não recebe nada tem (void) como lista de parâmetros - igual à main.

Protótipos

O C lê o seu arquivo de cima para baixo, e precisa conhecer a assinatura de uma função antes de você chamá-la. Se você quer a main primeiro (muita gente quer), coloque um protótipo - a assinatura seguida de ponto e vírgula - perto do topo:

prototype.c
1#include <stdio.h>
2
3void greet(const char *name);   // prototype
4
5int main(void) {
6    greet("Ada");
7    greet("Linus");
8    return 0;
9}
10
11void greet(const char *name) {  // definition
12    printf("Hello, %s!\n", name);
13}
Saída
Hello, Ada!
Hello, Linus!

É exatamente isso que arquivos de cabeçalho como o stdio.h contêm: protótipos de funções definidas em outro lugar. (const char *name é como o C passa uma string - mais sobre isso na aula de strings.)

Passagem por valor

Quando você chama uma função, o C copia cada argumento para o parâmetro. A função trabalha na cópia dela; a variável de quem chamou fica intacta. Isso surpreende quase todo mundo na primeira vez:

copy.c
1#include <stdio.h>
2
3void try_to_double(int n) {
4    n = n * 2;
5    printf("inside:  %d\n", n);
6}
7
8int main(void) {
9    int value = 10;
10    try_to_double(value);
11    printf("outside: %d\n", value);
12    return 0;
13}
Saída
inside:  20
outside: 10

Para tirar um resultado, devolva-o: value = doubled(value);. (O outro jeito - passar um endereço para a função poder mudar o original - é para isso que servem os ponteiros, e eles vêm na unidade 5.)

Escopo

Uma variável declarada dentro de uma função (ou de qualquer bloco { }) é local: ela só existe enquanto aquele bloco roda e é invisível fora dele. Duas funções podem ter cada uma o seu próprio count sem interferir uma na outra. As variáveis declaradas fora de todas as funções são globais; elas são visíveis em todo lugar, o que torna os programas mais difíceis de entender. Prefira passar valores para dentro e devolver resultados para fora.

Principais conclusões

  • Uma função tem um tipo de retorno, um nome e parâmetros. Use void para "não devolve nada" e (void) para "não recebe nada".

  • Declare um protótipo antes do uso se a definição vier depois no arquivo - é disso que os cabeçalhos são feitos.

  • Os argumentos são copiados (passagem por valor). Devolva os resultados em vez de esperar que as variáveis de quem chamou mudem.

Quiz da aula

5 perguntas · aprovação com 4 acertos · até 50 XP

Ao passar, você conclui a aula e mantém sua sequência. As perguntas erradas voltarão em sessões de revisão.

Pratique: escreva código em C

Estes exercícios rodam de verdade. Escreva o programa, clique em “Executar testes” e leia o que o compilador informa: aprender a ler as mensagens do compilador é metade do aprendizado de C.

Exercício 1

É primo?

+25 XP

Escreva uma função int is_prime(int n) que devolva 1 se n for primo e 0 caso contrário (números menores que 2 não são primos). A função main já está escrita para você: ela lê um número e imprime prime ou not prime.

  • 13 é primo
  • 21 não é primo
  • 1 não é primo
  • 2 é primo
main.c
Carregando editor…

Seu código é compilado com gcc 14 (-Wall -Wextra) e executado no Compiler Explorer (godbolt.org), um serviço público gratuito.

Exercício 2

Escreva o seu próprio power()

+25 XP

Escreva long power(int base, int exponent), que calcula base elevado a um exponent não negativo usando um laço (sem <math.h>). Leia dois inteiros e imprima o resultado.

Para a entrada 2 10, imprima 1024.

  • 2^10
  • 5^0
  • 3^4
main.c
Carregando editor…

Seu código é compilado com gcc 14 (-Wall -Wextra) e executado no Compiler Explorer (godbolt.org), um serviço público gratuito.

Dúvidas sobre esta lição

Travou em algum ponto? Pergunte. Descobriu algo? Compartilhe. Explicar também é uma ótima forma de aprender.

Carregando publicações…