Escolar Documentos
Profissional Documentos
Cultura Documentos
Funções
2
Estruturas das Funções em
C
tipo nome-da-função([lista-de-parâmetros]) {
corpo da função
}
tipo: especifica o tipo do valor que a função
retorna
lista-de-parâmetros: uma lista separada por
vírgulas das variáveis que recebem os valores
dos argumentos passados quando a função é
chamada
corpo da função: comandos delimitados por
chaves { }
3
Exemplo
#include <stdio.h>
int main() {
linha();
printf("\n\t\t\t\tUm programa em C\n");
linha();
return 0;
}
void linha() {
int i;
for (i = 1; i <= 80; i++)
printf("-");
}
4
Protótipos de funções
Do mesmo modo que chamamos uma
função da biblioteca C (printf(),
scanf(), etc.) chamamos nossas
próprias funções como linha()
Os parênteses que seguem o nome são
necessários para que o compilador
possa diferenciar a chamada a uma
função de seu endereço de memória
6
Chamando funções
Função F1
Fluxo de Função Comando
controle main
Comando Função F3
Comando Comando
Comando
Chamada de F3 Comando
Comando
Chamada de F1 Comando final
Comando
Comando final
Comando Função F2
Comando
Chamada de F2
Comando Comando
Variáveis que são declaradas dentro de uma
função e são conhecidas somente dentro do
seu próprio bloco
Um bloco começa quando o compilador
encontra uma chave de abertura ({) e
termina quando o compilador encontra uma
chave de fechamento (})
Variáveis locais existem apenas durante a
execução do bloco de instruções onde estão
declaradas
Os blocos aonde uma variável é conhecida,
chama-se escopo da variável
8
Passando Argumentos para
Funções
O mecanismo usado p/ transmitir
informações a uma função é chamado
argumento
O argumento também é chamado de parâmetro
formal da função
O argumento é uma nova variável que
armazena a informação passada p/ a função
Funciona exatamente como uma variável local
É criada quando a função inicia sua execução e
destruída quando a função termina
9
Passando Argumentos para
Funções
Argumentos - chamada por valor
Em C, todos os argumentos de funções
são passados “por valor”, exceto vetores
Isto significa que à função chamada é
dada uma cópia dos valores dos
argumentos, e ela cria outras variáveis
temporárias para armazenar estes valores
A função chamada não pode alterar o
valor de uma variável da função que
chama; ela só pode alterar sua cópia
temporária
10
Exemplo
#include <stdio.h>
void dobro(int);
int main() {
int n;
printf("Informe um número inteiro: ");
scanf("%d", &n);
dobro(n);
printf("Número informado %d\n", n);
return 0;
}
void dobro(int x) {
x = x * 2;
printf("Dobro: %d\n", x);
}
11
Funções que Devolvem um
Valor
O comando return
Causa uma saída imediata da função onde
ele está contido, ou seja, termina a função
Pode ser usado para devolver um valor
Todas as funções, exceto aquelas do tipo
void, devolvem um valor
Este valor é explicitamente especificado pelo
comando return
O comando return faz com que a chamada à
função que contém o return seja substituída
pelo valor que sucede este comando
12
Funções que Devolvem um
Valor
Desde que uma função não seja declarada
como void, ela pode ser usada como um
operando em qualquer expressão
x = pow(y, 2);
if (max(x, y) > 100) printf("Maior");
for (ch = getchar(); isdigit(ch); ) ...;
printf("Valor absoluto de %d = %d", x, abs(x));
Entretanto, uma função não pode receber
uma atribuição
sqr(x) = 100; // instrução errada
13
Exemplo
#include <stdio.h>
int main() {
int n1, n2;
printf("Digite dois números inteiros: ");
scanf("%d %d", &n1, &n2);
printf("O maior é: %d\n", maior(n1, n2));
return 0;
}
14
Conceito de Ponteiro
16
Declarando Variáveis do
Tipo Ponteiro
Sintaxe:
tipo * variável;
Exemplos:
int * pcont;
float * px, * py;
Todo ponteiro tem um tipo específico
que indica o tipo da variável para o qual
ele aponta
Um ponteiro inteiro deve armazenar o
endereço de memórias de variáveis inteiras
17
Inicializando Ponteiros
Um ponteiro pode ser inicializado com:
0: é convertido para um ponteiro do tipo
apropriado
NULL: uma constante simbólica definida na
arquivo de cabeçalho <stdio.h>
Um endereço de memória
18
Operadores de Ponteiros
2 operadores unários são usados:
&: obtém o endereço de memória de uma
variável
*: obtém o conteúdo do endereço de
memória armazenado em um ponteiro
Exemplo:
int cont = 7;
int * pcont = &cont;
printf("%d\n", *pcont);
19
Exemplo
#include<stdio.h>
int main() {
int x = 10;// x é um inteiro
int * px; // px é um ponteiro p/ inteiro
px = &x; // px recebe o endereço de x
printf("Endereço de x: %p\n", &x);
printf("Valor de px: %p\n", px);
printf("Valor de x: %d\n", x);
printf("Valor do endereço armazenado em px: %d\n",
*px);
/* alterando dados */
*px = 30;
printf("Valor de x: %d\n", x);
printf("Valor de px: %p\n", px);
return 0;
}
20
Passagem de Parâmetros
por Referência
Por default, a passagem de parâmetros em C
é feita por valor (com exceção de vetores e
matrizes)
Uma cópia do valor do parâmetro é
transmitida para a função
A função chamada não pode alterar o valor
de uma variável da função que chama; ela só
pode alterar sua cópia temporária
A passagem de parâmetros por referência
permite à função chamada alterar os valores
das variáveis que foram passadas como
parâmetro em sua chamada 21
Passagem de Parâmetros
por Referência
Na chamada à função, são
transmitidos os endereços das
variáveis
Usa-se o operador &
Os parâmetros da função devem ser
ponteiros
22
Exemplo
#include <stdio.h>
int main() {
int a = 10, b = 20;
24
Vetores como Argumentos
de Funções
Chamamos a função com o nome do
vetor/matriz sem nenhum índice
Passamos o endereço do 1o elemento do
vetor/matriz para a função
Exemplo:
int main() {
int vet[10];
. . .
fun(vet);
. . .
}
25
Vetores como Argumentos
de Funções
Se a função recebe um vetor, o parâmetro
formal pode ser um ponteiro, um vetor
dimensionado, ou um vetor sem dimensão
void fun(int *a) void fun(int a[10]) void fun(int a[])
{ { {
. . . . . . . . .
} } }
Esses 3 métodos dizem ao compilador que um
ponteiro para um inteiro está sendo recebido
Passagem de parâmetros por referência
26
Matrizes como Argumentos
de Funções
Se a função recebe uma matriz bidimensional
como argumento, o número de elementos da
segunda dimensão (colunas) deve ser incluído
no cabeçalho da função
Exemplo: suponha a uma matriz 4 x 6
void fun(int a[4][6]) void fun(int a[][6]) void fun(int (*a)[6])
{ { {
... ... ...
} } }
27
Matrizes como Argumentos
de Funções
A partir do C99 é possível definir a dimensão
de uma matriz que é o parâmetro de uma
função também através de parâmetros
Exemplo: protótipo de função com uma matriz
de dimensão variável como parâmetro
int soma2d(int lin, int col, int v[lin][col]);
Ou omitindo o nome dos parâmetros
int soma2d(int, int, int [*][*]);
Os parâmetros que definem a dimensão
da matriz devem aparecer antes da
matriz na lista de parâmetros da função
28
O Qualificador const
Você pode impedir que o conteúdo do
endereço de memória de um ponteiro seja
alterado através do qualificador const
Por exemplo:
void fun(const char * x);
31
Classes de Armazenamento
Determina em que pontos do programa ela
pode ser acessada, quando ela será criada e
quando será destruída, em que lugar ela
será armazenada e qual o seu valor inicial
São quatro as classes de armazenamento
em C:
auto (automáticas)
extern (externas)
static (estáticas)
register (em registradores)
32
Classes de Armazenamento
A classe auto
São visíveis ou acessíveis somente às funções em
que estão declaradas
A palavra reservada auto pode ser usada para
especificar uma variável automática, mas não é
necessária, visto que a classe auto é default
São criadas em tempo de execução
São destruídas ao término da execução do bloco
ao qual pertencem
Não são inicializadas com nenhum valor
específico
33
Classes de Armazenamento
A classe extern
Ao contrário de variáveis automáticas,
declaradas dentro das funções, as
variáveis externas são declaradas fora de
qualquer função
A instrução de declaração de uma variável
externa é idêntica à de uma variável
automática
A acesso a elas é permitido a todas as
funções definidas após a sua declaração, e
elas existirão enquanto o programa estiver
sendo executado 34
Classes de Armazenamento
...A classe extern
São criadas em tempo de compilação
São inicializadas com zero por falta de
inicialização explícita
A palavra reservada extern não é usada
para criar variáveis da classe extern e sim
para informar ao compilador que a
variável em questão foi criada em outro
programa compilado separadamente e
que será linkeditado junto a este para
formar o programa final
35
Classes de Armazenamento
A classe static
As variáveis da classe static por um lado
se assemelham às automáticas, pois são
conhecidas somente das funções que as
declaram, e por outro lado se assemelham
às externas, pois mantêm seus valores
mesmo quando a função termina
São criadas em tempo de compilação
São inicializadas com zero por falta de
inicialização explícita
36
Classes de Armazenamento
A classe register
Indica que a variável deve ser guardada
fisicamente numa memória de acesso
muito rápido chamada registrador
Basicamente, variáveis register são
usadas p/ aumentar a velocidade de
processamento
O programador deve escolher as variáveis
que são mais frequentemente acessadas e
declará-las como da classe register
Fortes candidatas a este tratamento são
as variáveis de laços e os argumentos de
funções 37
O Preprocessador
Programa que examina o código-fonte
em C e executa modificações nele antes
da compilação com base em instruções
chamadas diretivas
Diretivas seriam as instruções que o
preprocessador executa
Estão contidas no programa-fonte, mas não
do programa que compilamos
O preprocessador faz parte do
compilador e é executado
automaticamente antes da compilação
38
O Preprocessador
Já usamos a diretiva #include para
incluir arquivos de cabeçalho em nossos
programas
Conjunto de diretivas mais comum
#define #ifndef
#undef #else
#include #elif
#if #endif
#ifdef #error
39
O Preprocessador
As diretivas podem ser colocadas em
qualquer lugar do programa
Geralmente são escritas no início do
programa (antes da main) ou antes de uma
função em particular
Elas se aplicam somente do ponto onde
estão escritas ao final do programa-
fonte
40
A diretiva #define
Em sua forma mais simples é usada
para definir constantes simbólicas com
nomes apropriados
Exemplo: identificador
texto
#define PI 3.14
O nome que segue a palavra #define é
chamado identificador
A frase escrita após o identificador é
chamado texto
41
A diretiva #define
Quando o preprocessador encontra uma
diretiva, procura abaixo dela seu
identificador e o substitui pelo seu texto
Por convenção, o identificador é escrito
em letras maiúsculas
Não há ; após a diretiva
Cada diretiva deve ser escrita em uma
linha
42
A diretiva #define
Por meio da diretiva #define podemos
definir textos ou instruções completas
com um nome indicativo
Por exemplo:
#define ERRO fprintf(stderr,"\t\tERRO!\n")
...
if(zebra) ERRO;
43
Macros
Diretivas #define que aceitam
argumentos
Exemplo:
#define PRN(x) printf("%d\n",x)
...
PRN(n1); Será substituído por printf("%d\n",n1);
Na definição de uma macro não pode
haver espaço em branco no
identificador
44
O uso de parênteses em
macros
A falta de parênteses em macros pode
provocar erros consideráveis
Exemplo:
#define SOMA(x,y) x + y
...
z = 10 * SOMA(3,4); z = 10 * 3 + 4;
Solução:
#define SOMA(x,y) (x + y)
45
O uso de parênteses em
macros
Parênteses envolvendo o texto não
solucionam todos os problemas
Exemplo:
#define PROD(x,y) (x * y)
...
z = PROD(2+3, 4); z = (2 + 3 * 4);
Solução:
#define PROD(x,y) ((x) * (y))
46
Definindo macros usando
outras macros
Uma macro pode ser definida usando
outra macro
Por exemplo:
#define PI 3.14
#define SQ(x) ((x) * (x))
#define AREA(x) (PI * SQ(x))
47
Macros versus Funções
Macros
Simples substituições dentro do programa
Execução mais rápida
Código do programa aumentado
O tipo de argumentos em macros não é
validado (vantagem?)
48
Referências
SCHILDT, Herbert. C Completo e Total. 3. ed.,
Makron Books, 1997.
MIZRAHI, Victorine Viviane. Treinamento em
linguagem C: [curso completo em um
volume]. 2. ed. São Paulo: Pearson Prentice
Hall, 2008.
DEITEL, M.H.; DEITEL, P.J.. Como Programar
em C. 2. ed., LTC, 1999.
PRATA, Stephen. C Primer Plus. 6. ed.,
Addison Wesley, 2014.
49