Linguagem C funções - pessoal.dainf.ct.utfpr.edu.br

Post on 18-Apr-2022

12 views 0 download

Transcript of Linguagem C funções - pessoal.dainf.ct.utfpr.edu.br

Linguagem C – funções

IF61A/IF71A - Computação 1

Prof. Leonelo Almeida

Universidade Tecnológica Federal do Paraná

Até agora ...

• Introdução à linguagem C

▫ ...

▫ Operadores aritméticos, de comparação e lógicos

▫ Entrada e saída de dados

▫ Estruturas condicionais

▫ Estruturas de repetição

▫ Vetores

▫ Matrizes

Aula de hoje

Crie um programa que faça:

• Cadastro de pontos em um sistema 3D

• Desenho de grafos de pontos

• Cálculo de planos, volumes, distância

• ...

Aula de hoje

Crie um programa que faça:

• Cadastro de pontos em um sistema 3D

• Desenho de grafos de pontos

• Cálculo de planos, volumes, distância

• ...

• Potencialmente centenas ou milhares de linhas

• Como mais de um programador poderia trabalhar no mesmo código?

Aula de hoje

Funções

(ou subprogramas)

Funções

• Problemas longos e/ou complexos podem (e devem) ser quebrados em subproblemas menores

• Exemplos:scanf(“%d”, &x);

x = pow(v_num, 2);

Funções

• Problemas longos e/ou complexos podem (e devem) ser quebrados em subproblemas menores

• Exemplos:scanf(“%d”, &x);

x = pow(v_num, 2);

Agrupam conjuntos de comando que são executados quando a função é chamada.

Funções podem retornar valores (resultados) após serem executadas.

Vantagens no uso de funções

• Evitar blocos de código muito grandes

• Separar o programa em partes

• Permite o reuso de códigos

• Evita que o mesmo trecho de código seja repetido várias vezes em um mesmo programa

• Facilita a alteração/correção do código

Declaração de uma função

tipo nome (tipo parâmetro1, ..., tipo parâmetroN) {

comandos;

return valor_retorno;

}

• Toda função tem um tipo de retorno (int, char, float, void, etc)

• Parâmetros são variáveis inicializadas na chamada (ou invocação) da função

• Return devolve para quem chamou a função o resultado da execução da função

Exemplo

int soma (int a, int b) {

int c;

c = a + b;

return c;

}

• A função retorna um valor inteiro e recebe dois parâmetros inteiros

• O valor de retorno é sempre do mesmo tipo que o tipo da função

Usando (chamando) a função soma

#include <stdio.h>

int soma (int a, int b) {

int c;

c = a + b;

return c;

}

int main(){

int r;

r = soma(12, 90);

r = soma (-9, 45);

}

Função sem parâmetros

int leNumero() {

int c;

printf(“Digite um numero:”);

scanf(“%d”, &c);

return c;

}

int main() {

int r;

r = leNumero();

printf(“Número digitado %d\n”, r);

}

Declaração de funções

• Não é possível declarar uma função dentro de outra.

• Exemplo incorreto:int main(){

int f1(int a, int b){

return (a+b);

}

c = f1(9, 90);

}

Chamando (invocando) funções

• Em atribuições:

x = soma(100, 2);

• Em outras expressões:

printf(“A soma é: %d\n”, soma(a,b));

Chamando (invocando) funções

• Atenção:

▫ Para cada parâmetro da função deve ser informada uma constante ou uma variável do mesmo tipo e na mesma ordem da declaração da função

▫ As variáveis passadas como parâmetros nãosão afetadas pela função. O que a função usa é somente uma cópia dos valores dessas variáveis.

Chamando (invocando) funções

• Ainda usando a função soma, que tem dois parâmetros, é incorreto:

x = soma();

x = soma(50);

x = soma(100, 2, 50);

x = soma(10.25, 50);

Número incorreto de parâmetros

Tipo incorreto do primeiro

parâmetro

Exemplo de função#include <stdio.h>

int somaEsq (int x, int y) {

x = x + 1;

y = y + 1;

return (x + y);

}

int main () {

int a, b;

a=10;

b=5;

printf ("Soma de a e b: %d\n", a + b);

printf ("Soma de x e y: %d\n", somaEsq(a, b));

printf ("a: %d\n", a);

printf ("b: %d\n", b);

return 0;

}

O que será impresso na tela?

Exemplo de função#include <stdio.h>

int somaEsq (int x, int y) {

x = x + 1;

y = y + 1;

return (x + y);

}

int main () {

int a, b;

a=10;

b=5;

printf ("Soma de a e b: %d\n", a + b);

printf ("Soma de x e y: %d\n", somaEsq(a, b));

printf ("a: %d\n", a);

printf ("b: %d\n", b);

return 0;

}

O que será impresso na tela?

Os valores de a e b não são afetados pela função.

Outro exemplo – return• A função termina quando encontra o comando

return. Nada após ele é executado.

int leNumero(){

int n;

printf("Digite um numero:");

scanf("%d",&n);

return n;

printf("bla bla bla bla");

}

int soma(int a, int b){

return (a+b);

}

int main(){

int x1, x2;

x1 = leNumero();

x2 = leNumero();

printf("Soma e: %d\n",soma(x1,x2));

}

Outro exemplo – return• A função termina quando encontra o comando

return. Nada após ele é executado.

int leNumero(){

int n;

printf("Digite um numero:");

scanf("%d",&n);

return n;

printf("bla bla bla bla");

}

int soma(int a, int b){

return (a+b);

}

int main(){

int x1, x2;

x1 = leNumero();

x2 = leNumero();

printf("Soma e: %d\n", soma(x1,x2));

}

Esse comando nunca será executado.

O tipo void

• É um tipo especial• Ele significa “nada” ou “vazio”• Usado para:▫ Indicar que uma função não retorna nenhum

valor▫ A lista de parâmetros de uma função é vazia▫ Tornar funções mais genéricas

• Exemplo:void imprime (int numero) {

printf(“Número $d\n”, numero)

}

Exemplo

#include <stdio.h>

void imprime (int numero) {

printf ("Numero %d\n", numero);

}

int main (void) {

imprime (10);

imprime (20);

return 0;

}

Exemplo 2#include <stdio.h>

void funcImp(void *val, int t) {

switch (t) {

case 1:

printf("%4d",*(int*)val); break;

case 2:

printf(“%c",*(char*)val); break;

case 3:

printf("%.2f",*(float*)val); break;

}

}

int main () {

int a=10; char b='9'; float c=10.2;

void *ptr;

ptr = &a;

funcImp(ptr, 1);

ptr = &b;

funcImp(ptr, 2);

ptr = &c;

funcImp(ptr, 3);

}

A função main

• É uma função especial

• Todo programa começa a ser executado por ela

• Tem sempre o tipo fixo int

• O comando return na função main:

▫ 0 se o programa terminou corretamente

▫ Outro valor se ocorreu algum erro

A função main –

passagem de parâmetros• Pode-se usar 2 parâmetros:

int main(int argc, char *argv[])

• argc – número de parâmetros passados na linha de comando

• argv – vetor de strings contendo os parâmetros passados pela linha de comando

▫ Atenção: na primeira posição de argv está o nome do programa

Exemplo

int main(int argc, char *argv[]) {

int i;

for (i = 0; i < argc; i++)

printf("%s\n", argv[i]);

return 0;

}

• Na linha de comando:nome_programa arg1 arg2 ... argn

Protótipos de funções

• Até o momento as funções são declaradas antes da função main.

• Se a declaração estiver após a main, em certos, compiladores ocorrerá um erro.

#include <stdio.h>

int main () {

float a = 0, b = 5;

printf ("%f\n", soma (a, b));

return 0;

}

float soma (float op1, float op2) {

return (op1 + op2);

}

Pode gerar erro de compilação!

Protótipos de funções

• Podemos adicionar os protótipos das funções no início do programa. Assim é possível declarar as funções em qualquer ordem.

• O protótipo nada mais é do que o cabeçalho da função

• Exemplo:tipo nome (tipo parâmetro1, ... tipo parâmetroN);

Exemplo

#include <stdio.h>

float soma (float op1, float op2);

int main () {

float a = 0, b = 5;

printf (“%f\n”, soma (a, b));

return 0;

}

float soma (float op1, float op2) {

return (op1 + op2);

}

Exemplo com mais de uma função#include <stdio.h>

float soma (float op1, float op2);

float subt (float op1, float op2);

int main () {

float a = 0, b = 5;

printf ("%f\n %f\n", soma (a, b),subt(a, b));

return 0;

}

float soma (float op1, float op2) {

return (op1 + op2);

}

float subt (float op1, float op2) {

return (op1 - op2);

}

Variáveis

int funcao1(char c, float f) {

float res;

...

}

int funcao2(void) {

float res;

...

}

O que acontece ao tentar compilar um código-fonte que tenha essas

duas funções?

Escopo de Variáveis (locais e globais)

Característica Escopo Local Escopo Global

Declaração Dentro de uma função Fora das funções

Existência Após a execução da função a variável deixa de existir

Durante toda a execução do programa

Visibilidade Somente dentro da função

Qualquer função pode acessá-las e alterá-las

Parâmetros de funções São variáveis locais -

Valores passados ao parâmetros de funções

Podem ser locais, globais, ponteiros ou constantes.

Organização geral de programas#include <stdio.h>

#include <outras bibliotecas>

Protótipos de funções

Declaração de Variáveis Globais

int main(){

Declaração de variáveis locais

Comandos;

}

int fun1(Parâmetros){

Declaração de variáveis locais

Comandos;

}

int fun2(Parâmetros){

Declaração de variáveis locais

Comandos;

}

Exemplo#include<stdio.h>

void fun1();

int fun2(int local_b);

int global;

int main() {

int local_main;

...

}

void fun1() {

int local_a;

...

}

int fun2(int local_b){

int local_c;

...

}

Quais as variáveis visíveis aqui?

Quais as variáveis visíveis aqui?

Quais as variáveis visíveis aqui?

Exemplo#include<stdio.h>

void fun1();

int fun2(int local_b);

int global;

int main() {

int local_main;

...

}

void fun1() {

int local_a;

...

}

int fun2(int local_b){

int local_c;

...

}

Quais as variáveis visíveis aqui?

Quais as variáveis visíveis aqui?

Quais as variáveis visíveis aqui?

global, local_main

global, local_a

global, local_b, local_c

Escopo de variáveis

• E se houver uma variável local com o mesmo nome de uma global? Exemplo:

#include <stdio.h>

void fa();

int nota = 10;

int main(){

nota = 20;

fa();

}

void fa() {

int nota;

nota = 5;

}

Escopo de variáveis

• E se houver uma variável local com o mesmo nome de uma global? Exemplo:

#include <stdio.h>

void fa();

int nota = 10;

int main(){

nota = 20;

fa();

}

void fa() {

int nota;

nota = 5;

}

A variável local “esconde” a global, ou seja, dentro da

função é considerada somente a variável local.

Exemplo completo

• Testar se um número é primo:

divisor = 2;

eprimo=1;

while(divisor<=candidato/2) {

if(candidato % divisor == 0){

eprimo=0;

break;

}

divisor++;

}

if(eprimo)

printf(" %d, ", candidato);

Imprimir os n primeiros primosint main(){

int divisor=0, n=0, eprimo=0, candidato=0, primosImpr=0;

printf(“\n Digite número de primos a imprimir:”);

scanf(“%d”,&n);

if(n>=1){

printf("2, ");

primosImpr=1;

candidato=3;

while(primosImpr < n){

divisor = 2;

eprimo=1;

while( divisor <= candidato/2 ){

if(candidato % divisor == 0){

eprimo=0;

break;

}

divisor++;

}

if(eprimo){

printf("%d, ",candidato);

primosImpr++;

}

candidato=candidato+2;

} } }

Criar uma função para dizer se é primo

int ePrimo(int candidato)

int divisor = 2, eprimo=1;

while(divisor<=candidato/2) {

if(candidato % divisor == 0){

eprimo=0;

break;

}

divisor++;

}

if(eprimo)

return 1;

else

return 0;

}

}

Código com a função#include <stdio.h>

int ePrimo(int candidato);

int main(){

int divisor=0, n=0, eprimo=0, candidato=0, primosImpr=0;

printf("\n Digite numero de primos a imprimir:");

scanf("%d",&n);

if(n >= 1){

printf("2, ");

primosImpr = 1;

candidato = 3;

while(primosImpr < n){

if( ePrimo(candidato) ){

printf("%d, ",candidato);

primosImpr++;

}

candidato=candidato+2;

}

}

}

Atividades

• Crie um programa que contém uma função que calcula ab (não use bibliotecas para isso)

▫ double pot(double a, double b)

• Usando a mesma função agora crie um programa que imprime: a0, a1, a2, ... ab

Atividades

• Escreva um programa que tenha uma função que computa o fatorial de um numero n passado por parâmetro.

▫ long fat(long n);

▫ Se n <= 0 seu programa deve retornar 1.

• Agora use a mesma função anterior e crie um programa que imprima todos os valores de 1! até n!

Atividades

• Reescreva o programa de soma de matrizes. Utilize uma função para lê-las, outra para calcular a soma e uma terceira para imprimir a soma.

• Escreva uma função que recebe um número inteiro n passado por parâmetro e devolve o primeiro número da série de fibonacci que é maior ou igual a n.