funções. 2mf. introdução às funções exercício: escreva um programa que coloque no ecrã o...
TRANSCRIPT
Funções
2MF.
Introdução às funções
Exercício: Escreva um programa que coloque no ecrã o seguinte output:
******************** escrever 20 asteriscosNúmeros entre 1 e 5********************12345********************
3MF.
Introdução às funções#include<stdio.h>
main(){
int i;
for (i=1; i<=20; i++)putchar('*');
putchar('\n');
puts("Números entre 1 e 5");
for (i=1; i<=20; i++)putchar('*');
putchar('\n');
for (i=1; i<=5; i++)printf("%d\n",i);
for (i=1; i<=20; i++)putchar('*');
putchar('\n');}
Código repetido
Solução???
5MF.
Tipo de funções
Funções Pré-definidas pela linguagem (funções de biblioteca)
Funções Definidas pelo programador
6MF.
Funções definidas pelo utilizador
Reduzir a complexidade de um programa
Evita-se a repetição de código ao longo do programa
Têm de ter um nome único
A localização da função é indiferente desde que coloque o protótipo (cabeçalho) da função antes da função main()
7MF.
Funções
SINTAXEEspecificador_de_tipo nome_da_função ( lista de parâmetros )
{
corpo da função
}
Especificador_de_tipo - especifica o tipo de valor que o comando return da função devolve, podendo ser qualquer tipo válido.
nome_da_função - é um identificador escolhido pelo programador que não se deve repetir.
lista de parâmetros - é uma lista de nomes de variáveis separadas por virgulas e seus tipo, que recebem os valores dos argumentos quando a função é chamada.
8MF.
Funçõescorpo da função - é constituído por instruções de C de acordo com a
sintaxe da linguagem. Em C não se podem definir funções dentro de funções.
tem de estar imediatamente a seguir ao cabeçalho da função e é escrito entre chavetas
sempre que uma função é invocada pelo programa, o corpo da função é executado, instrução a instrução, até terminar o corpo da função ou até ser encontrada uma instrução return.
9MF.
FunçõesResolução do programa anterior recorrendo às funções
#include<stdio.h>linha(){
int i;for (i=1; i<=20; i++)
putchar('*');putchar('\n');
}main(){ int i;
linha();puts("Números entre 1 e 5");
linha();for (i=1; i<=5; i++)
printf("%d\n",i);linha();
}
10MF.
Características de uma função
Cada função tem que ter um nome único, o qual serve para a sua invocação algures no programa a que pertence;
Uma função pode ser invocada a partir de outras funções;
Uma função deve realizar uma única tarefa bem definida;
Uma função deve comportar-se como uma caixa negra. Não interessa como funciona, o que interessa é que o resultado final seja o esperado, sem efeitos colaterais;
11MF.
Características de uma função
O código de uma função deve ser o mais independente
possível do resto do programa, e deve ser tão genérico
quanto possível, para poder ser reutilizado noutros
projectos.
Uma função pode receber parâmetros que alterem o seu
comportamento de forma a adaptar-se facilmente a
situações distintas;
Uma função pode retornar, para a entidade que a
invocou, um valor como resultado da sua execução.
12MF.
Funções - notas
se nenhum tipo é especificado, o compilador assume que a função devolve um resultado inteiro (int)
uma função pode não ter parâmetros e neste caso a lista de parâmetros é vazia.
todos os parâmetros da função devem incluir o tipo e o nome da variável.
13MF.
Passar parâmetros à função
Passagem de parâmetros por valor - uma cópia do argumento é passada para a função
O parâmetro comporta-se como uma variável local
……………printf("Introduza o valor de x e N\n\n");scanf("%d%d",&x,&n);Y = 2* soma(x , n)/ soma (x , n);……………
int expressao (int a, int b){ return a+b;}
argumentos
parâmetros
Livro Pág. 166
14MF.
Passar parâmetros à função
#include <stdio.h> #include <math.h>
char minusculo (char ch);
main ( ){ printf (" %c", minusculo ('A') ); }
char minusculo (char ch){ if (( ch >= 'A') && (ch <= 'Z'))
return (ch + 'a'- 'A'); else return (ch);}
15MF.
Passar parâmetros à função - exercício
void main ( ){ int num, b; printf (“ Digite um valor”); scanf (“ %d”, &num ); printf (“ Valor absoluto de num é %d”, abs(num) );}
int abs (int x){ return ( ( x < 0 ) ? -x : x );}
Efectuar um programa para achar o valor absoluto de um número:
16MF.
Passando vários argumentos
Ex 1:float área_retângulo (float
largura, float altura){ return (largura * altura);
}
Ex 2:float potência (float base, int expoente){ int i; float resultado = 1; if (expoente == 0) return 1; for (i = 1; i <= expoente; i++) resultado *= base return resultado;
}
17MF.
Funções Resolução para a seguinte expressão:
1º Verificar o que de repete? Leitura de variáveis x, a, b Somas x+a e x+b
2º pensar na funções Função para ler Função para somar
bx
a)(x*2y
18MF.
Funções – Exemploint ler( )
{
int valor;
puts("Qual o valor: ");
scanf("%d",&valor);
return valor;
}
int soma (int a, int b)
{
return a+b;
}
Agora é só aplicar as funções na expressão na função main()
bx
a)(x*2y
19MF.
Funções – Exemplo
bx
a)(x*2y
#include <stdio.h> #include <math.h>
int ler();int soma (int a, int b);
void main ( ){ int x; float y;
x=ler(); y= 2 * soma( x,ler()) / sqrt( soma(x,ler()) ); printf("O valor y é %4.2f",y);}
20MF.
#include <stdio.h> #include <math.h>
int ler(); int soma (int a, int b);
void main ( ){ int x; float y;
x=ler(); y= 2 * soma( x,ler()) / sqrt( soma(x,ler()) ); printf("O valor y é %4.2f",y);}
int ler( ){ int valor; puts("Qual o valor: "); scanf("%d",&valor); return valor;}
int soma (int a, int b){ return a+b; }
Procedimentos “Funções” que não retornam valores retornam void #include <stdio.h> void desenha();main ( ){ desenha ( ); puts (“\n1ª função”); desenha ( );}void desenha( ){ int i; for (i = 0; i < = 10; i++)
printf (“*”);}
Output
**********1ª função**********
Funções
Retornam valores#include <stdio.h>int fatorial (int);int fatorial (int n){ int i, resultado = 1; for ( i = 1; i <= n; i ++)
resultado *= i; return resultado;} main ( ){ printf (“ o fatorial de 4 = %d”, fatorial(4) ); printf (“ o fatorial de 3 = %d”, fatorial(3) );}
23MF.
Variáveis locais
Variáveis declaradas dentro de uma função são denominadas locais e apenas podem ser usadas dentro do próprio bloco
São criadas apenas na entrada do bloco e destruídas na saída (automáticas)
Variáveis Locais
void desenha ( ){ int i, j; . . .}
main ( ){
int a; desenha();
a = i; erro
. . .}
void desenha ( ){ int i, j; . . . . . .}void calcula ( ){ int i, j; . . . . . .}
i, j em desenha são variáveis diferentes de i, j em calcula.
25MF.
Variáveis Globais
Variável que é declarada externamente podendo ser acedida por qualquer função
#include <stdio.h>main ( ){ int i; ......... .........desenha ( );calcula ( );}
void desenha ( ){ int j; i = 0; . . .} void calcula ( ){ int m; i = 5; . . .}
26MF.
Comando Return
Permite a atribuição de uma expressão a uma função e
força o retorno imediato ao ponto de chamada da função. #include <stdio.h>main ( ){ char letra; printf (“Letra minúscula”); letra = minúsculo ( ); if (letra == ‘a’) printf (“ok”);}
char minúsculo ( ){ char ch;
scanf(“%c”, ch); if ( (ch >= ‘A’) && (ch <= ‘Z’)) return (ch + ‘a’ - ‘A’); else return (ch);}
27MF.
Note pelo exemplo anterior que a função minúsculo lê um valor internamente convertendo-o para minúsculo.
Como usar esta função se já temos uma letra e
desejamos convertê-la para minúsculo?
Exercício prático
S(x, n) = x/1! + x2/2! + x3/3! + ... + xn/ n!
#include <stdio.h>float serie (float , int );float potencia (float , int) int fat (int);void main( ){ float x; int termos;
printf(“Numero de termos: “); scanf(“%d”, &termos); printf(“valor de X: “); scanf(“%f”, &x); printf(“O valor da série = %f “, serie(x, termos));}
float potencia (float base, int expoente){ int i; float resultado = 1; if (expoente == 0) return 1; for (i = 1; i <= expoente; i++) resultado *= base; return resultado;}
float serie (float x, int n){ int i; float resultado = 0; for ( i = 1; i <= n; i++) resultado += potência( x, i ) / fat( i ); return resultado;}
int fat (int n)
{
int i, resultado = 1;
for ( i = 1; i <= n; i ++)
resultado *= i;
return resultado;
}
31MF.
#include <stdio.h>float serie (float x, int n);float potencia (float base, int expoente) int fat (int n);void main( ){ float x; int termos;
printf(“Numero de termos: “); scanf(“%d”, &termos); printf(“valor de X: “); scanf(“%f”, &x); printf(“O valor da série = %f “, serie(x, termos));}
float serie (float x, int n){ int i; float resultado = 0; for ( i = 1; i <= n; i++) resultado += potência( x, i ) / fat( i ); return resultado;}
float potencia (float base, int expoente){ int i; float resultado = 1; if (expoente == 0) return 1; for (i = 1; i <= expoente; i++) resultado *= base; return resultado;}
int fat (int n){ int i, resultado = 1; for ( i = 1; i <= n; i ++)
resultado *= i; return resultado;}
32MF.
Passando um vetor para uma função
#include <stdio.h>
int maximum( int [] ); /* ANSI function prototype */
main( )
{
int values[5], i, max;
printf("Entre com 5 numeros:\n");
for( i = 0; i < 5; ++i )
scanf("%d", &values[i] );
max = maximum( values );
printf("\nValor Maximo: %d\n", max );
}
33MF.
int maximum( int values[5] ) { int max_value, i; max_value = values[0]; for( i = 0; i < 5; ++i ) if( values[i] > max_value ) max_value = values[i]; return max_value; }
Saída: Entre com 5 numeros: 7 23 45 9 121Valor Maximo: 121
34MF.
Matrizes
em ‘C’ podemos definir um vetor em que cada posição temos um outro vetor (matriz).
estrutura de dados homogênea multidimensional Note:
int matéria [ 4 ] [ 40 ];
temos 4 matérias, cada uma com 40 alunos
35MF.
Matrizes - Leitura
int i, j, matéria [ 4 ] [ 40 ];
for ( i = 0 ; i < 4; i++ ) {
printf (“entre com as notas da matéria %d”, i+1);
for ( j = 0; j < 40; j++) {
printf (“entre com a nota do aluno %d”, j+1);
scanf (“%d”, &materia [ i ] [ j ]);
}
}
36MF.
Variável String
matriz do tipo char terminada pelo caractere null ‘\0’ cada caractere de um string pode ser acessado
individualmente vetor de tamanho n string de tamanho ( n-1 )
Ex: char string[10] = “exemplo” ;
char string[10] = { “exemplo” }; char string[10] = { ‘e’, ‘x’, ‘e’, ‘m’, ‘p’, ‘l’, ‘o’, ‘\0’ };
printf ( “%s”, string ); printf ( “%c”, string [ 0 ] );
37MF.
Lendo Strings
scanf : lê o string até que um branco seja encontrado
Ex:main ( ) {
char nome[40];
printf ( “Digite seu nome: “ );scanf ( “%s”, &nome[ 0 ] );//scanf ( “%s”, nome ); printf ( “Bom dia %c”, nome[0] );
}
Saída:Digite seu nome: Jose MariaBom dia Jose
38MF.
Lendo Strings
Getslê caracteres até encontrar ‘\n’
substitui ‘\n’ por ‘\0’
Ex:main ( ) {
char nome[40];
printf ( “Digite seu nome: “ );gets ( &nome[ 0 ] ); // ou gets(nome);printf ( “Bom dia %s”, nome );
}
Saída:Digite seu nome: Jose Maria
Bom dia Jose Maria
39MF.
Imprimindo Strings
printf puts
Ex:main ( ) {
char nome[40];
printf ( “Digite seu nome: “ );gets ( &nome[ 0 ] );puts ( “Bom dia ” ); puts ( nome );
}
Saída:Digite seu nome: Jose MariaBom dia Jose Maria
40MF.
Funções de manipulação de strings
Strlenretorna o tamanho do string - não conta ‘\0’
Ex:main ( ) {
char nome[40];
printf ( “Digite seu nome: “ );gets ( &nome[ 0 ] );printf (“Tamanho = %d”, strlen(&nome[ 0 ]) );
}
Saída:Digite seu nome: Jose MariaTamanho = 10
41MF.
Funções de manipulação de strings
strcat ( str1, str2 )concatena str2 ao final de str1
Ex:main ( ) {
char nome[40] = “Jose”, char sobrenome[30] = “Maria”;
strcat(nome, sobrenome);puts (sobrenome);puts (nome);
}
Saída:MariaJoseMariaCuidado: dado str1 + str2 tem que caber em str1
42MF.
Funções de manipulação de strings
strcmp ( str1, str2 ) compara dois strings retornando:
– negativo se str1 < str2
– 0 se str1 = str2
– positivo se str1 > str2
a comparação é feita por ordem alfabética
#include <stdio.h>main ( )
{char nome[40] = “Jose”;char sobrenome[30] = “Maria”;
if ( strcmp ( nome, sobrenome ) !=0) puts ( “os strings são diferentes” );else puts ( “os strings são identicos” );
}
44MF.
Conversões
podemos também converter strings e números
(inteiros/fracionários) conforme desejarmos:
Exemplo: Conversão de String em Número Inteiro#include <stdio.h>main(){int i;char s[10];printf(“Digite uma sequencia de numeros com letras: “);gets(s);i = atoi(s);printf(“Numero: %d “,i);}
45MF.
Ponteiros
Ponteiros, como o próprio nome diz, é um
tipo de variável que aponta para outra (de um
tipo qualquer). Na verdade um ponteiro
guarda o endereço de memória (local onde
se encontra na memória) de uma variável.
46MF.
Ponteiros
int teste=20;
int *p;
p=&teste;
p irá armazenar o endereço de memória da variável teste. Ou seja, p não armazena o valor 20, mas sim o endereço de teste que, este sim, armazena o valor 20.
como chegar ao valor 20 usando a variável p?
int teste=20;int *p;
p=&teste;printf("%d\n",*p);
47MF.
Ponteiros
Outro exemplo:
char algo[5] = { 5, 4, 3, 2, 1 };char *c;
c=&algo[2];
Colocamos em c o endereço do terceiro elemento de algo: c[0]=3, c[1]=2 e c[2]=1.
Se tivéssemos feito c=&algo[3], então: c[0]=2 e c[1]=1.
Ponteiros
int vet_notas[50];
int *pont_notas;
pont_notas=vet_notas;
Para imprimir a primeira e a décima nota de nosso vetor, temos duas opções:
print ("A primeira nota é: %d", vet_notas[0]);
print ("A primeira nota é: %d", *pont_notas);
print ("A décima nota é: %d", vet_notas[9]);
print ("A décima nota é: %d", *(pont_notas+9));
49MF.
Equivalência entre vetores e ponteiros
vet_notas[0]==*(pont_notas);
vet_notas[1]==*(pont_notas+1);
vet_notas[2]==*(pont_notas+2);
50MF.
Malloc e Free
Alocação dinâmica
#include <stdio.h>
main()
{
int *notas, numero, i;
Printf(“Entre com o número total de alunos\n’”);
scanf(“%d”, &numero);
notas=(int *)malloc(numero * sizeof(int));
for (i=0; i,numero; i++) {
printf(“Digite a nota do aluno %d”, i+1);
scanf(“%d”, ¬as[i]);
printf(“\n A nota do aluno %d é :%d: , i+1, notas[i]);
}
free(notas);
}
52MF.
Estruturas
Uma estrutura é um conjunto de variáveis dentro de um mesmo nome. Em geral, uma variável é de um tipo específico, por exemplo, temos uma variável do tipo inteira e estamos fechados a nos referenciar aquele nome que lhe foi dado sempre por um número do tipo inteiro, logicamente. Já as estruturas, dentro de um mesmo nome podemos nos referenciar a uma gama de variáveis pré-definidas.
53MF.
Estruturas
struct molde_conta
{
char nome[50];
int telefone;
float saldo ;
};
Definido o molde, devemos agora declarar a variável que utilizará desse molde:
struct molde_conta conta;
54MF.
Estruturas
struct molde_conta{char nome[50];int telefone;float saldo;} conta1, conta2;
equivalente a: struct molde_conta conta1, conta2;
55MF.
Estrutras - Utilização do tipo
Podemos fazer atribuição de structs, do tipo conta2 = conta, e os valores serão idênticos.
Para contar o número de caracteres de nome dentro da
estrutura conta, podemos fazer:
for (i=0,conta.nome[i],++i) ;
printf ("o nome tem -> %d letras \n",i);
56MF.
Vetores de Estruturas
struct molde_conta conta[100];
conta[1].telefone=2212324; conta[1].nome=“joao carlos”; conta[1].saldo=1245.89;
conta[5].telefone=2212888; conta[5].nome=“Maria dos Santos”; conta[5].saldo=6908.79;
57MF.
Arquivos - feopen( )
A função “fopen” tem duas finalidades:
- abrir uma fila de bytes
- ligar um arquivo em disco àquela fila
FILE *fopen(char *NomeArquivo, char *modo);
FILE *arquivo;
if ((arquivo = fopen(“teste”,”w”)) == NULL) {
puts(“Não posso abrir o Arquivo teste.\n”);
exit(1); /* força o término da execução da rotina */
}
Modo Significado “r” Abre Arquivo de Texto para Leitura “w” Cria Arquivo de Texto para Gravação “a” Anexa a um Arquivo de Texto “rb” Abre Arquivo Binário para Leitura “wb” Cria Arquivo Binário para Gravação “ab” Anexa a um Arquivo Binário “r+” Abre Arquivo de Texto para Leitura/Gravação “w+” Cria Arquivo de Texto para Leitura/Gravação “a+” Abre ou Cria Arquivo de Texto para Leitura/Gravação “r+b” Abre Arquivo Binário para Leitura/Gravação “w+b” Cria Arquivo Binário para Leitura/Gravação “a+b” Abre ou Cria Arquivo Binário para Leitura/Gravação
59MF.
Arquivos - putc ( )
Grava caracteres em fila previamente abertos
int putc(int ch, FILE *fp);
ch é o caracter a ser gravadofp é o ponteiro devolvido por fopen
putc(‘a’, arquivo);
60MF.
Arquivos - getc ( )
Ler caracteres em uma fila aberta
int getc(FILE *arquivo);
Exemplo:
ch = getc(arquivo);
while (ch != EOF)
ch = getc(arquivo);
61MF.
Arquivos - fclose ( )
Fechar as filas abertas. Caso o programa seja encerrado sem que as filas sejam fechadas, dados gravados nos buffers podem ser perdidos.
int fclose(FILE *fp);
fclose(arquivo);
main(){FILE *arq;char ch;if ((arq=fopen(“teste.dat”,”w”)) == NULL) {
printf(“Arquivo não pode ser criado\n”);
exit(1); }do{
ch=getchar();putc(ch,arq);
}while (ch!=0);fclose(arq);}
63MF.
Arquivos - ferror ( )
Determina se a operação de arquivo produziu um erro. Sua forma geral será:
int ferror(FILE *fp);
64MF.
Arquivos - rewind( )
Reinicia o arquivo, equivale ao Reset do Pascal, ou seja apenas movimenta o ponteiro do arquivo para seu início.
65MF.
Arquivos - fwrite ( ) fread ( )
Permitem que leiamos/gravemos blocos de dados, sua forma geral é a seguinte:
int fread(void *buffer, int num_bytes, int cont,
FILE *fp);
int fwrite(void *buffer, int num_bytes, int cont,
FILE *fp);
Arquivos - fwrite ( )
main()
{
FILE *fp;
float f = 12.23;
if ((fp=fopen(“teste”,”wb”)) == NULL) {
printf(“Arquivo não pode ser criado\n”);
exit(1);
}
fwrite(&f,sizeof(float(),1,fp);
fclose(fp);
}
67MF.
Arquivos - fseek ( )
Entrada e saída com acesso aleatórioint fseek(FILE *fp, long int num_bytes, int origem);
fp - é o ponteiro de arquivo devolvido por fopen().num_bytes - é um inteiro longo que representa o número
de bytes desde a origem até chegar a posição corrente.
OBS: Este comando é normalmente utilizado em arquivos binários.
Exemplo : Leitura de um caracter em um arquivo binário.
main()
{
FILE *fp;
if ((fp=fopen(“teste”,”rb”)) == NULL) {
printf(“Arquivo não pode ser aberto\n”);
exit(1);
}
fseek(fp,234L,0); /* L força que seja um inteiro longo */
return getc(fp); /* lê o caracter 234 */
}
carga(){FILE *fp;int i;if ((fp=fopen(“LISTA.DAT”,”rb”)) == NULL) {puts(“Falha na Abertura do Arquivo!”);return;
}inicia_matriz();for (i=0; i < 100; i++)if (fread(&matriz[i], sizeof(struct registro), 1, fp) != 1) {
if (feof(fp)) {fclose(fp);return;
}else {
puts(“Erro de Leitura! “);fclose(fp);
return; } } }
Exemplo de montagem de um pequeno cadastro de nomes, endereços e salários de funcionários em arquivo.
salvar()
{
FILE *fp;
int i;
if ((fp=fopen(“LISTA.DAT”,”wb”))==NULL) {
puts(“Falhou Abertura! “);
return;
}
for (i=0;i<100;i++)
if (*matriz[i].nome)
if(fwrite(&matriz[i],
sizeof(struct registro), 1,fp) != 1)
puts(“Falha na Gravacao! “);
fclose(fp);
}
Vamos supor que desejamos criar um programa que escreva num arquivo cujo nome será fornecido na chamada do programa
(Exemplificando: KTOD TESTE <Enter>).
Gostaríamos que o DOS criasse o arquivo TESTE guardando o conteúdo digitado durante a execução do programa.
main(argv,argc)
onde
argc - tem o número de argumentos contidos nas linha de comando (necessariamente maior ou igual a um, pois o próprio programa já é considerado um argumento pelo D.O.S.).
argv é um ponteiro que acomodará os caracteres digitados.
Exemplo 1: Programa KTOD, que escreve caracteres num arquivo criado/aberto via D.O.S.
#include “stdio.h”
main(argc,argv)
int argc;
char *argv[];
{
FILE *fp;
char ch;
if (arg != 2) {
printf(“Digite o Nome do Arquivo\n”);
exit(1);
}
if ((fp=fopen(argv[1],”w”)) == NULL) {
printf(“Arquivo não pode ser aberto\n”);
exit(1);
}
do {
ch = getchar();
putc(ch,fp);
} while( ch != ‘$’);
fclose(fp);
}
Exemplo 2: Programa DTOV, que apresenta em vídeo os
caracteres digitados via KTOD.
#include “stdio.h”main(argc,argv)int argc;char *argv[];{FILE *fp;char ch;if (arg != 2) {
printf(“Digite o Nome do Arquivo\n”);exit(1);
}if ((fp=fopen(argv[1],”r”)) == NULL) {
printf(“Arquivo não pode ser aberto\n”);exit(1);}
ch = getc(fp);
do {putchar(ch);ch=getc(fp);
} while( ch != ‘$’);fclose(fp);}
Exemplo 3: Programa para copiar Arquivos.
#include “stdio.h”main(argc,argv)int argc;char *argv[];{FILE *in, *out;char ch;if (arg != 3) {
printf(“Digite o Nome dos Arquivos\n”);exit(1);}
if ((in=fopen(argv[1],”rb”)) == NULL) {printf(“Arquivo origem não existe\n”);exit(1);}
if ((out=fopen(argv[2],”wb”)) == NULL) {printf(“Arquivo destino não existe\n”);exit(1);}
while (! feof(in)) putc(getc(in),out); /* esta é a cópia propriamente dita */
fclose(in);fclose(out);}