Você está na página 1de 8

© E.L.

Favero Introdução a Programação em C 44

Capítulo

7 FUNÇÕES
Este capítulo apresenta as funções definidas pelo programador para organizar e
sistematizar o seu código.

7.1 Mini e maxi e intermediário


Uma função é definida pelo seu tipo, nome e uma lista de parâmetros. Ela deve ser
definida antes do seu uso. Depois da lista de parâmetros as {} delimitam seu corpo.
Dentro do corpo deve ter um ou mais comandos return, ver mini() abaixo. Todo
programa C deve ter uma função main().

int mini(int a, int b){


if (a<b) return a;
else return b;}
int main(){
int x=4,y=7;
printf("min: %d\n", mini(x,y));
printf("min: %d\n", mini(11,17));}

Passagem de parâmetros por valor. Como vemos acima quando mini entra no
Stack de execução uma cópia dos valores x=4, y=7 é passada para dentro da
função mini. O resultado da execução de mini(a=4,b=7) é 4.
© E.L.Favero Introdução a Programação em C 45

Exemplo 1. Vamos exemplificar agora com três funções: mini, maxi e inter. Com elas vamos
ler três valores int e mostra-los em ordem crescente. Seguem as três funções.

#include <stdio.h>
int mini(int a, int b){
if (a<b) return a;
else return b;}
int maxi(int a, int b){
if (a>b) return a;
else return b;}
int inter(a,b,c){ //intermediário
if (a<=b && b<=c || c<=b && b<=a) return b;
else if (b<=c && c<=a || a<=c && c<=b) return c;
else return a;}
int main(){
int min_, max_, inter_;
int a,b,c;
scanf("%d %d %d", &a, &b, &c);
min_=mini(a,mini(b,c));
max_=maxi(a,maxi(b,c));
inter_=inter(a,b,c) ;
printf("ordenados: %d %d %d", min_,inter_, max_ );}
>>>
3 7 3
ordenados: 3 3 7
--------------------------------

Note que na função intermediário, em cada caso, a condição tem dois && e um || (dois and e
um or). Por exemplo, em (a<=b && b<=c || c<=b && b<=a) primeiro testa-se se a<=b<=c; e
depois se c<=b<=a. Entre estas duas conjunções temos um ou ||.

7.2 Função soma()


Um vetor é uma estrutura de dados homogênea, com todos elementos de um mesmo tipo
de dados. Os índices começam sempre no 0 e terminam com o comprimento menos 1.
Como um vetor é passado para uma função?
© E.L.Favero Introdução a Programação em C 46

Passagem de parâmetros por referência. Acima ilustramos a passagem de vetores para


uma função, por referência. É apenas passado o ponteiro para dentro da função, como uma
seta que aponta na var. Em C, vetores sempre são passados por referência.

Escopo das variáveis. Acima vemos “Global variables” a área das variáveis globais. Neste
programa global é o vetor VET[MAX]. Dentro da função soma temos int soma=0,i; que são
as variáveis locais (particulares da função). Elas só são visíveis dentro da função. Na
função o parâmetro é v, chamado de parâmetro formal. Na chamada é VET parâmetro real.
Note que o MAX é uma constante simbólica, onde o compilador troca ela pelo valor
real, no caso 6; por isso ela não ocupa espaço na memória.
Segue abaixo o código da função soma(int v[]) com duas versões: uma com for e
outra com while.

#include <stdio.h>
#define MAX 6
int VET[MAX]={1,2,7,11,23,6};
int soma(int v[]){
int soma=0,i;
for (i=0;i<MAX;i++){soma = soma+v[i];}
return soma;}
// usando while
int soma1(int v[]){
int soma=0,i=0;
while (i<MAX) {soma += v[i]; i++;}
return soma;}
int main(){
printf(" soma: %d \n",soma(VET));
printf("soma1: %d \n",soma1(VET));}
>>>
soma: 50
soma1: 50

Na passagem de parâmetros de um vetor não importa o tamanho dele, pois só se passa o


endereço, ponteiro para ele. Aqui neste código, o tamanho do vetor é a constante simbólica
global MAX. Se a função precisa do tamanho do vetor, deve ser utilizada outra variável para
passar o tamanho.

7.3 Função média() e desvio()

Outra função bem usual é a média de um vetor de valores. A média é a soma dos elementos
do vetor dividida pelo seu comprimento. Uma função parente da média é o desvio padrão.
Seja SS o somatório da diferença de cada elemento com a média elevada ao quadrado.
© E.L.Favero Introdução a Programação em C 47

Assim SS = somatório de (V[i]-med)**2. O desvio é a raiz quadrada de SS/len(V), sqrt


(SS/(len(V)). Onde len é o tamanho do vetor. Média e desvio são do tipo float.
#include <stdio.h>
#include <math.h>
#define MAX 6
int soma(int v[]){
int soma=0,i;
for (i=0;i<MAX;i++){soma = soma+v[i];}
return soma;}
float media(int v[]){return(float)soma(v)/MAX;}
float desvio(int v[]){
float ss=0,vi,med; int i;
med=media(v);
for (i=0;i<MAX;i++) {
vi=(v[i]-med);
ss+=pow(vi,2); }
return sqrt(ss/MAX);}
int main(){
int Vi[MAX]={1,2,7,11,23,6};
printf("media: %f\n", media(Vi));
>>>
media: 8.333333
desv: 7.340905

Neste código, o tamanho do vetor é “passado” para as funções média e desvio pela
constante simbólica MAX.

7.4 Função troca dois elementos de um vetor


Abaixo mostramos como trocar o conteúdo de duas posições de um vetor. São passados
na função troca o vetor e os dois índices. O resultado da troca fica sobre o vetor passado
por referência na entrada da função, assim a função não precisa de return, por isso o tipo
void (vazio).

#include <stdio.h>
#define MAX 6
int V[MAX]={1,2,7,11,23,6};
void troca(int V[], int a, int b) {
int temp = V[a];
V[a] = V[b];
V[b] = temp;};
int main(){
int i;
printf("\nV antes da troca: \n");
for (i=0; i<MAX; i++) printf(" %d", V[i]);
troca(V, 2,5);
printf("\nV depois da troca(V,2,5): \n");
for (i=0; i<MAX; i++) printf(" %d", V[i]);}
>>>
V antes da troca:
1 2 7 11 23 6
V depois da troca(V,2,5):
1 2 6 11 23 7
© E.L.Favero Introdução a Programação em C 48

7.5 Ordenar por seleção direta


Ordenar um vetor por seleção direta, como exemplo de uso da função troca. A estratégia é
de trazer sempre o míni(mo) para o início da lista ainda não ordenada, com o uso de troca.
A função mini(int j, int V[]) retorna o mínimo de parte do vetor, inicia a busca na
posição j. A parte inicial do vetor já estará ordenada, trabalha-se de j em diante.

#include <stdio.h>
#define MAX 6
int V[MAX]={1,2,7,11,23,6};
void troca(int V[], int a, int b) {int temp=V[a]; V[a]=V[b]; V[b]=temp;};
int mini(int j, int V[]){ // mini() a partir da pos j de V
int iM=j, i;
for (i=j;i<MAX;i++){if (V[iM]>V[i]) iM=i;}
return iM;}
void selDireta(int V[]){
int i, iM;
for (i=0;i<MAX;i++){iM=mini(i,V); troca(V,i,iM);};
return ;}
void printv(int V[])
{int i;for (i=0;i<MAX;i++)printf("%d ",V[i]);printf("\n");};
int main(){
printf("vetor original:");printv(V);
selDireta(V);
printf("vetor ordenado:");printv(V); }
>>>
vetor original:1 2 7 11 23 6
vetor ordenado:1 2 6 7 11 23

7.6 Criar funções para tipo string


Exemplo 1. Palíndromo sobre um string. Se for sobre números abaixo temos uma pirâmide
de palíndromos, baseados em números binários. Um palíndromo é uma sequência onde
cada metade é espelhada sobre a outra.

Vamos identificar palíndromos sobre uma variável string. A estratégia é caminhar da frente
para o final e vice-versa sempre comparando os caracteres das extremidades. Se
chegarmos ao meio então é um palíndromo. O início é i=0. O final do string é f=len-1.
Comparamos sempre str[i] ==str[f]. i++ e f-- levam os extremos em direção ao meio.

#include <stdio.h>
#include <string.h>
#define LEN 80
int palindromo(char str[])
{int i = 0, f = strlen(str)-1, cond = TRUE;
// f = len-1 final
while (cond && i < f) {
cond = (str[i] == str[f]);
© E.L.Favero Introdução a Programação em C 49

i++;f--;}
return cond;}
int main(void)
{char str[LEN];
printf("Digite str:");
gets(str);
if (palindromo(str)) printf("eh palimdromo\n");
else printf("nao eh palimdromo\n");
return 0;}
>>>
Digite str:abcdcba
eh palimdromo
>>>
Digite str:abcdfba
nao eh palimdromo

Exemplo 2. Palíndromo sobre um string 2. Neste exemplo, vamos mostrar outros recursos
para trabalhar com strings, usando uma estratégia de inverter uma cópia do string e então
comparar as duas cópias para saber se o conteúdo das duas é igual. Se x==reverso(x)
então x é palíndromo.
Primeiro mostramos como calcular o len de um str: caminha-se até encontrar o
caractere ‘\0’ que marca o final do string.
Em C não podemos inverter uma string sem destruir a cópia original, portanto antes
de inverter vamos tirar a cópia com strcpy(). Na função reverse(), para trocar o elementos,
usamos a variável temporária tmp: tmp=str[i]; str[i]=str[f]; str[f]=tmp. Por fim, para comparar
a cópia original com a invertida usamos strcmp() que retorna 0 se as duas são iguais.

#include <stdio.h>
#include <string.h>
#define LEN 80
int len(char str[]){
int i = 0;while(str[i] != '\0') i++;return i;}
char str1[LEN], str2[LEN];
void reverse(char str[]) {
char tmp;
int i=0, f=len(str)-1;
while (i < f) {
tmp=str[i];str[i]=str[f];str[f]=tmp; //troca
i++;f--;}}
int main(void)
{ printf("Digite str: ");
gets(&str1);
strcpy(str2, str1);
reverse(str2);
if (strcmp(str1,str2)==0) printf("eh palimdromo\n");
else printf("nao eh palimdromo\n");
return 0;}
>>>
Digite str: abcdcba
eh palimdromo
>>>
Digite str: abcdfba
nao eh palimdromo
© E.L.Favero Introdução a Programação em C 50

A função gets() lê um string até encontrar uma nova linha <enter>. A função scanf(), leitura
formatada, lê uma ou mais variáveis, cada variável tem um marcador de tipo. Na scanf() o
(&) nas variáveis diferentes de “%s” é necessário (passagem por referência). No gets() ele
assume um string, vetor de char, “%s”, então (&) nas vars é opcional.
A função gets() deve ser usada com cuidado, pois ela lê até encontrar ‘\n’; se
ultrapassar o tamanho da var string do parâmetro, ela irá sobrepor na memória outra
variável; causando erros difíceis de localizar e de identificar sua origem. O problema de
estouro de strings foi exemplificado no capítulo sobre vetores de char.

7.7 Ler um valor int


Na linguagem C existe uma função que lê char e retorna um valor inteiro, atoi(). Aqui
fazemos uma versão dela. No main comparamos a versão do C atoi() com a atoi2(). No
início do código mostramos como fazer uma função para testar se um caractere é ou não
numérico.

include <stdio.h>
int isNumeric(char x){return ((x>='0' && x<='9')? 1: 0);}
int atoi2(char str[]){
int res=0, sign=1, i=0;
if (*str==NULL) return 0;
// salta nao numericos
while(str[i]!='\0'&& !(isNumeric(str[i])||str[i]=='-')){i++;}
if (str[i] == '-') {sign = -1;i++;} // pega sinal
for (;str[i] !='\0' && (isNumeric(str[i])!= 0); ++i){
res = res*10 + str[i]-'0';}
return sign*res;}
int main(){
char str[] = " -89789 aa";
// atoi do C x atoi1
int val1 = atoi(str);
int val3 = atoi2(str);
printf("%d %d ", val1, val3);
return 0;}
>>>
-89789 -89789

7.8 Exercícios (4)


Ao responder estes exercícios, teste cada função com duas entradas para garantir que a
saída está correta.
E10.1 Usando a função mini(), maxi() e inter(), como no item 7.1, leia 4 valores int a,b,c,d
e imprima eles ordenados em ordem decrescente.
E10.2 Faça uma função de ordenação seleção direta, que ordena as letras de um string
passado por parâmetro: se entra “asdfg” deve retornar “adfgs”. Mostre ela
funcionando.
E10.3 Defina a função que retorna o produtório de V; por exemplo, para int
V[MAX]={1,2,7,11,23,6}; o produtório é 1*2*7*11*23*6.
E10.4 NERD: refaça em C o fragmento de código abaixo que está em Python.
FF=0xFF
while FF>1:
FF=FF>>1
FI=int(str(bin(FF))[2:])
print('%10d**2=%-10d' % (FI,FI*FI))
>>>
1111111**2=1234567654321
© E.L.Favero Introdução a Programação em C 51

111111**2=12345654321
11111**2=123454321
1111**2=1234321
111**2=12321
11**2=121
1**2=1

7.8.1 Perguntas conceituais (3)


Responda com no mínimo 10 palavras e no máximo 20 palavras:
E10.5 O que é a passagem de parâmetros por referência?
E10.6 O que é a passagem de parâmetros por valor?
E10.7 Em C um vetor pode retornar de uma função? Como?

Você também pode gostar