Programação · 14 min read · Oct 09, 2025
Aprendendo C/C++ Passo a Passo - Página 6
06. Passo a Passo C/C++ — Programação C - Funções
Funções
| I. Introdução | |
| II. Definição de função | |
| III. Tipos de funções | |
| IV. Funções embutidas |
| | 1. Funções numéricas
- Funções de string
- Funções de teste de caractere | | | V. Funções definidas pelo usuário | | | 1. Funções Simples
- Função com Argumentos
- Função com Retornos
- Função com Recursão | | | VI. Ponteiros e Funções | | | 1. Passagem de Parâmetro por Referência
- Chamada por valor
- Chamada por Referência | | | VII. Local Vs Global | | | VIII. Especificadores de Classe de Armazenamento | | | Classe de Armazenamento Automática
Classe de Armazenamento de Registro
Classe de Armazenamento Estática
Classe de Armazenamento Externa |
I. Introdução
Aqui está um programa para imprimir o endereço de uma pessoa duas vezes, que é escrito em ambos os métodos usando funções e sem usar funções. Ele demonstrará a vantagem das funções.
| | #include
int main()
{
printf(“\nNome da Pessoa”);
printf(“\nRua, Apartamento//Número da Casa “);
printf(“\ncep, Cidade”);
printf(“\nPaís”);
printf(“\nNome da Pessoa”);
printf(“\nRua, Apartamento//Número da Casa “);
printf(“\ncep, Cidade”);
printf(“\nPaís”);
return 0;
} | #include
void address()
{
printf(“\nNome da Pessoa”);
printf(“\nRua, Apartamento//Número da Casa “);
printf(“\ncep, Cidade”);
printf(“\nPaís”);
}
int main()
{
address();
address();
return 0;
} |
II. Definição de Função
Um bloco de instruções, que tem a capacidade de aceitar valores como argumentos e retornar resultados para o programa chamador. Assim, uma função é um bloco de instruções autocontido que executa uma tarefa específica.
III. Tipos de funções
| | - Funções embutidas/ Funções de Biblioteca/ Funções Pré-Definidas
- Funções definidas pelo usuário |
IV. Funções de Biblioteca
As funções de biblioteca são projetadas pelo fabricante do software, elas são carregadas no disco sempre que o software é carregado.
As seguintes funções são exemplos das funções de biblioteca.
1. Funções Numéricas
| Função | Sintaxe | Ex. | Resultado |
| Abs | Abs(n) | abs(-35) | 35 |
| ceil | ceil(n) | ceil(45.232) | 46 |
| floor | floor(n) | floor(45.232) | 45 |
| fmod | fmod(n,m) | fmod(5,2) | 1 |
| cos | cos(n) | cos(60) | 0.5 |
| sin | sin(n) | sin(60) | 0.866 |
| tan | tan(n) | tan(60) | 1.732 |
| sqrt | sqrt(n) | sqrt(25) | 5 |
| pow | pow(n,m) | pow(2,3) | 8 |
2. Funções de String
| Funções | Sintaxe | Ex. |
| strlen | strlen(str) | strlen(“Computador”) |
| strcpy | strcpy(target,source) | strcpy(res,”Passar”) |
| strcat | strcat(target,source) | strcat(“mag”,”gic”) |
| strcmp | strcmp(str1,str2) | strcmp(“abc”,”Abc”) |
| strrev | strrev(target,scr) | fstrrev(res,”LIRIL”) |
3. Funções de Teste de Caractere
| Função | Descrição |
| isalnum | é uma letra ou dígito |
| isalpha | é uma letra |
| isdigit | é um dígito |
| iscntrl | é um caractere de controle comum |
| isascii | é um caractere ASCII válido |
| islower | é um caractere minúsculo |
| isupper | é um caractere maiúsculo |
| isspace | é um caractere de espaço |
| isxdigit | é um caractere hexadecimal |
Há uma enorme biblioteca de funções disponíveis, eu te dei uma pequena parte dela. Para mais funções de biblioteca, consulte o Manual de Ajuda.
V. Funções Definidas pelo Usuário
Os programas que você já viu realizam divisões de trabalho. Quando você chama gets, puts, ou strcmp, você não precisa se preocupar com como o interior dessas funções funciona.
Essas e cerca de 400 outras funções já estão definidas e compiladas para você na biblioteca Turbo C. Para usá-las, você só precisa incluir o arquivo de cabeçalho apropriado em seu programa, “A biblioteca de tempo de execução,” na referência de biblioteca para ter certeza de que você entende como chamar as funções e qual valor (se houver) elas retornam.
Mas você precisará escrever suas próprias funções. Para fazer isso, você precisa dividir seu código em seções discretas (funções) que cada uma executa uma única tarefa compreensível para suas funções, você pode chamá-las em todo o seu programa da mesma forma que você chama funções da biblioteca C.
Passos para implementar uma função
| | 1. Declaração
- Chamada de Função
- Definição |
| | • Cada função deve ser declarada no início do programa.
• A definição da função contém o código real da tarefa de execução.
• Se uma função é definida no início do programa, não há necessidade de declaração da função. |
Um exemplo de função para demonstrar a implementação
| | / 32_egfun.c /
#include
void address(); / Declaração /
int main()
{
address(); / Chamada de Função /
address(); / Chamada de Função /
return 0;
}
void address() / Definição /
{
printf(“\nNome da Pessoa”);
printf(“\nRua, Apartamento//Número da Casa “);
printf(“\ncep, Cidade”);
printf(“\nPaís”);
} |
Funções definidas pelo usuário podem ser divididas em 4 tipos com base em como as chamamos.
| | 1. Funções Simples
- Função com Argumentos
- Função com Retornos
- Função com Recursão |
1. Funções Simples
Executa uma tarefa específica apenas, não precisa de argumentos nem valores de retorno
Exemplo de Função Simples
| | / 33_line.c /
#include
void line(); / Declaração /
int main()
{
line(); / Chamada de Função /
return 0;
}
void line() / Definição /
{
int i;
for(i =1;i<80; i++)
putch(‘*’);
} |
2. Função com Argumentos
Uma função, que aceita argumentos, é conhecida como função com argumentos.
Ex.
| | / 34_argu.c /
void line(char ch, int n)
int main()
{
line(“-“, 50);
line(“*”, 8);
return 0;
}
void line(char ch, int n)
{
int i;
for( i = 1; i<=n; i++ )
putch(ch);
} |
3. Função com valores de retorno
Uma função que pode retornar valores para o programa chamador é conhecida como função com valores de retorno.
Ex.
| | / 35_retu.c /
int abs(int n);
int main()
{
int res;
printf(“%d”, abs(-35))
res = abs(-34); / Chamada de Função/
printf(“%d”, res);
return 0;
}
void abs(int n)
{
if( n < 0 )
n = n * -1;
return n;
} |
4. Função com Recursão
Se uma instrução dentro do corpo de uma função chama a mesma função, é chamada de ‘recursão’. Às vezes chamada de ‘definição circular’, a recursão é, portanto, o processo de definir algo em termos de si mesmo.
Exemplos de Funções Recursivas
| | / O seguinte programa demonstra a chamada da função de si mesma /
int main( )
{
printf(“\nOlá”);
main( ); / Uma função, que pode chamar a si mesma /
return 0;
} Não execute este programa, ainda é uma explicação, portanto o programa não é logicamente válido.
A mesma saída pode ser alcançada usando outra função: void disp( );
int main( )
{
disp( );
return 0;
}
void disp( )
{
printf(“\nOlá”);
disp( );
} |
O programa deve terminar em um certo ponto, então a chave da recursão reside em uma interrupção suave, que pode ser definida usando uma instrução condicional.
Verifique o seguinte exemplo:
| | / 36_recursion.c /
int i = 1; / Declarando uma variável global /
void disp( );
int main( )
{
disp( );
return 0;
}
void disp( )
{
printf(“\nOlá %d “, i);
i ++;
if( i < 10 ) / se o valor de i for menor que 10, então chame a função novamente /
disp( );
} |
| | Programa para encontrar o fatorial do número dado:
/ 37_fact.c /
int factorial(int x);
void main
{
int a, fact;
printf(“\nDigite qualquer número “); scanf(“%d”, &a);
fact = factorial(a);
printf(“\nFatorial é = %d”, fact);
}
int factorial(int x)
{
int f = 1, i;
for( i = x; i>=1; i–)
f = f i;
return f;
} | Para encontrar o fatorial de um número dado usando recursão
/ 38_fact.c /
int rec_fact(int x);
int main( )
{
int a, fact;
printf(“\nDigite qualquer número “); canf(“%d”, &a);
fact = rec_fact(a);
printf(“\nValor do fatorial é = %d”, fact);
return 0;
}
int f = 1;
int rec_fact(int x)
{
if( x > 1)
f = x rec_fact(x-1);
return f;
} |
VI. Ponteiros e Funções
| | Passagem de Parâmetro por Referência
Chamada por valor
Chamada por Referência |
1. Passagem de Parâmetro por Referência
O ponteiro pode ser usado na declaração da função e isso torna uma função complexa ser facilmente representada e acessada. A definição da função faz uso de ponteiros nela, de duas maneiras
| | – Chamada por valor
- Chamada por referência |
O mecanismo de chamada por referência é mais rápido em comparação com o mecanismo de chamada por valor, porque na chamada por referência, o endereço é passado e a manipulação com os endereços é mais rápida do que as variáveis comuns. Além disso, apenas uma localização de memória é criada para cada um dos parâmetros reais.
Quando uma parte do programa, os argumentos reais, chama uma função e os valores alterados dentro da função serão retornados para a parte chamadora do programa na forma alterada. Isso é chamado de chamada por referência ou chamada por endereço. O uso de ponteiro como argumento de função nesse mecanismo permite que os objetos de dados sejam alterados globalmente, ou seja, dentro da função e também dentro da parte chamadora do programa. Quando um ponteiro é passado para a função, o endereço do argumento é passado para as funções e o conteúdo desse endereço é acessado globalmente. As alterações feitas nos parâmetros formais (parâmetros usados na função) afetam o valor original dos parâmetros reais (parâmetros usados na chamada da função no programa chamador).
Ex.
| | / 39_func.c /
void func_c( int *x );
int main()
{
int i = 100;
int *a;
a = &i;
printf(“\nO valor é %d”, i);
func_c(a);
printf(“\nO valor é %d”, i);
return 0;
}
void func_c( int x )
{
(x) ++;
printf(“\nO valor na função é %d “, *x);
} |
No programa acima, há totalmente três instruções ‘printf’, duas na função main() e uma na subprograma da função. Devido ao efeito da primeira instrução printf, o valor de i é impresso como 100. Depois, a chamada da função é feita e dentro da função, o valor é alterado para 101 devido ao incremento. O valor alterado é novamente retornado para a função main() e é impresso como 101.
Portanto, a saída é:
| | O valor é 100
O valor na função é 101
O valor é 101 |
Mais sobre Chamadas de Função
Tendo tido o primeiro contato com ponteiros, vamos agora voltar ao que originalmente nos propusemos a aprender – os dois tipos de chamadas de funções: chamada por valor e chamada por referência. Os argumentos podem geralmente ser passados para a função de uma das duas maneiras:
| | a. Enviando os valores dos argumentos
b. Enviando os endereços dos argumentos |
2. Chamada por Valor
No primeiro método, o ‘valor’ de cada um dos argumentos reais na função chamadora é copiado para os argumentos formais correspondentes da função chamada. Com esse método, as alterações feitas nos argumentos formais na função chamada não têm efeito sobre os valores dos argumentos reais na função chamadora. O seguinte programa ilustra a Chamada por Valor.
| | / 40_callbyvalue.c /
void swap( int x, int y )
int main( )
{
int a = 10, b = 20;
swap( a ,b );
printf(“\n a = %d, b = %d “, a, b);
return 0;
}
void swap( int x, int y )
{
int t;
t = x;
x = y;
y = t;
printf(“\nx = %d, y = %d”, x, y);
} |
A saída do programa acima seria:
| | x = 20 y = 10
A = 10 b = 20 |
Note que o valor de a e b permanece inalterado após a troca dos valores de x e y.
3. Chamada por Referência
Desta vez, os endereços dos argumentos reais na função chamadora são copiados para os argumentos formais da função chamada. Isso significa que, usando esses endereços, teríamos acesso aos argumentos reais e, portanto, poderíamos manipulá-los. O seguinte programa ilustra esse fato.
| | 41_callbyref.c /
void swap( int x, int y )
int main()
{
int a = 10, b = 20;
swap( &a, &b);
printf(“\na = %d, b = %d”, a, b);
return 0;
}
void swap( int x, int y )
{
int t;
t = x; x = y; y = t;
} |
A saída do programa acima seria:
| | A = 20, b = 10 |
Note que este programa consegue trocar os valores de a e b usando seus endereços armazenados em x e y. Geralmente, na programação C, fazemos uma chamada por valor. Ou seja, em geral, você não pode alterar os argumentos reais. Mas se desejado, isso pode sempre ser alcançado através de uma chamada por referência.
Usando a chamada por Referência de forma inteligente
podemos fazer uma função, que pode retornar mais de um valor ao mesmo tempo, o que não é possível normalmente. Isso é mostrado no programa dado abaixo.
| | / 42_callbyref.c /
void areaperi(int r, float a, float p)
int main()
{
int radius;
float area, perimeter;
printf(“\nDigite o raio de um círculo:”); scanf(“%d”, &radius);
areaperi(radius, &area, &perimeter);
printf(“\nÁrea = %f “, area);
printf(“\nPerímetro = %f”, perimeter);
return 0;
}
void areaperi(int r, float a, float p)
{
a = 3.14 r r; p = 2 3.14 r;
} |
E aqui está a saída:
| | Digite o raio de um círculo 5
Área = 78.500000
Perímetro = 31.400000 |
Aqui, estamos fazendo uma chamada mista, no sentido de que estamos passando o valor de radius, mas, o endereço de area e perimeter. E como estamos passando os endereços, qualquer alteração que fizermos nos valores armazenados nos endereços contidos nas variáveis a e p, tornará a mudança efetiva na função main. É por isso que, quando o controle retorna da função areaperi( ), conseguimos imprimir os valores de area e perimeter.
Assim, conseguimos retornar dois valores de uma função chamada, e, portanto, superamos a limitação da instrução return, que pode retornar apenas um valor de uma função por vez.
VII. Variáveis Locais Vs Globais
De acordo com o Escopo dos Identificadores, as variáveis são declaradas como tipos.
| | / 42_globalid.c /
int i=4000; / Declaração de variável global/
int main()
{
int a=10, b=20; / Variável Local /
int i=100; / Variável Local /
printf(“%d %d”, a, b);
printf(“\nLocal i : %d”, i); / Acessando variável Local /
printf(“\nGlobal i : %d “, ::i); / Acessando variável Global /
return 0;
} |
Nota: O Operador de Resolução de Escopo ( :: ) pode estar disponível apenas em C++.
VIII. Especificadores de Classe de Armazenamento
Até este ponto de vista, já estamos familiarizados com a declaração de variáveis. Para definir completamente uma variável, é necessário mencionar não apenas seu ‘tipo’, mas também sua ‘ Classe de Armazenamento ’.
De acordo com esta seção, as variáveis não apenas têm um ‘tipo de dado’, mas também têm uma ‘Classe de Armazenamento’.
As Classes de Armazenamento são de 4 Tipos
| | 1. Classe de Armazenamento Automática
- Classe de Armazenamento de Registro
- Classe de Armazenamento Estática
- Classe de Armazenamento Externa |
1. Classe de Armazenamento Automática
| Palavra-chave | auto | |
| Armazenamento | Memória | |
| Valor Padrão | Nulo | |
| Escopo | Local ao bloco em que a variável é definida | |
| Vida | Até a execução de seu bloco |
Ex:
| | / 43_auto.c /
#include
int main()
{
auto int i, j;
printf(“%d %d”, i, u);
return 0;
} |
2. Classe de Armazenamento de Registro
| Palavra-chave | register | |
| Armazenamento | Registradores da CPU | |
| Valor Padrão | Nulo | |
| Escopo | Local ao bloco em que a variável é definida | |
| Vida | Até a execução de seu bloco |
Ex:
| | / 44_register.c /
#include
int main( )
{
register int i, j;
for(i=1;i<=10;i++)
printf(“\n%d”, i);
return 0;
} |
3. Classe de Armazenamento Estática
| Palavra-chave | static | |
| Armazenamento | Memória | |
| Valor Padrão | Zero | |
| Escopo | Local ao bloco em que a variável é definida | |
| Vida | O valor da variável persiste entre diferentes chamadas de função |
Ex:
| | / 45_static.c /
#include
void add();
int main()
{
add();
add();
add();
return 0;
}
void add()
{
static int i = 1;
printf(“%d\n”,i++);
} |
4. Classe de Armazenamento Externa
| Palavra-chave | extern | |
| Armazenamento | Memória | |
| Valor Padrão | Zero | |
| Escopo | Global | |
| Vida | Enquanto a execução do programa não chegar ao fim |
Ex:
| | / 46_extern.c /
#include
int i;
void add(); / Variável Externa /
int main( )
{
extern j=10; / Variável Externa /
for(i=1;i<=10;i++)
add();
return 0;
}
void add( )
{
j++;
printf(“%d %d\n”, i, j);
} |
Receba novas postagens na sua caixa de entrada
Sem spam. Cancele a assinatura a qualquer momento.