ED1 - Aula 01 Introducao e revisãohebert/disc/aed1/AED1_01_introducao... · 2017-09-07 · ED1 -...

Preview:

Citation preview

ED1 - Aula 01Introducao e revisão

Profa. Nádia FélixHebert Coelho

Instituto de InformáticaUniversidade Federal de Goiás

NF ED1-Aula 01

Roteiro

Detalhes do cursoPlano de Ensinosharif

RevisãoTipos ConstruídosAlocação DinâmicaFunçõesExercíciosLaboratório

NF ED1-Aula 01

Registro

DefiniçãoUm registro é uma estrutura que contém diversas variáveis(chamadas de campos), usualmente de tipos diferentes, mas quedentro de um determinado contexto, fazem sentido se agrupadas.

Podemos comparar um registro com uma ficha que possui todosos dados sobre uma determinada entidade, por exemplo:Registro de alunos (nome, RA, médias de provas, médias delabs, etc...)Registro de produtos (Nome, código, descrição, etc...)

NF ED1-Aula 01

Declarando o formato do registro

Para criar um registro é preciso declarar seu formato/estrutura. Issoé feito utilizando a palavra chave struct, da seguinte forma:

struct nome_do_tipo_do_registro {tipo_1 nome_1;tipo_2 nome_2;tipo_3 nome_3;...

tipo_n nome_n;};

NF ED1-Aula 01

Declarando o formato do registro

#include <stdio.h>struct aluno {

int mat; //matriculafloat media;

};int main () {

struct aluno j;j.mat = 10;j.media = 8.5;printf(“Matricula %d, media %f.”, j.mat, j.media);

}

NF ED1-Aula 01

Lendo os campos de um Registro

A leitura dos campos de um registro a partir do teclado deve serfeita campo a campo, como se fossem variáveis independentes.

printf (“Digite a matricula do aluno: ”);scanf (“%d”, &j.mat);printf (“Digite a média do aluno: ”);scanf (“%f”, &j.media);

NF ED1-Aula 01

Copiando registros

A cópia de um registro pode ser feita como se fosse a cópia de umavariável normal, ou seja

registro_1 = registro_2;

NF ED1-Aula 01

Vetor de registros

Registros podem ser declarados como um vetor.

#include <stdio.h>struct aluno {

int mat; //matriculafloat media;

};int main () {

struct aluno turma[40];turma[0].mat = 10;turma[0].media = 8.5;...

}

NF ED1-Aula 01

Registros Aninhados

Também é possível declarar um registro como uma das variáveis deum registro, quantas vezes isso for necessário.

#include <stdio.h>struct notas {float p1;float p2;float p3;

};typedef struct notas NotasAluno;struct aluno {int mat; //matriculaNotasAluno provas; };

NF ED1-Aula 01

sizeof

O operador unário sizeof calcula o tamanho de qualquer variável outipo Construído.

sizeof retorna um valor inteiro, assim seu resultado pode serapresentado na tela com comando printf.

Exemplo:int i;printf(“%d”, sizeof(i));

O printf acima, imprime o tamanho da variável inteira i.

NF ED1-Aula 01

Alocação Dinâmica

Existem 2 maneiras fundamentais de um programa em C armazenarinformações na memória principal do computador.

Variáveis locais e globais, incluindo matrizes e estruturas;Armazenamento fixo durante toda a execução do programa.

Alocação DinâmicaNesta maneira o programa pode obter espaço paraarmazenamento em tempo de execução.

NF ED1-Aula 01

C ANSI

O padrão C ANSI especifica apenas quatro funções para o sistemade alocação dinâmica:

calloc();malloc();free();realloc();

As funções de alocação dinâmica definidas pelo padrão C ANSI estãona biblioteca stdlib.h

NF ED1-Aula 01

calloc()

void *calloc(size_t num, size_t size);

A função calloc() aloca uma quantidade de memória igual anum×size. Ou seja, calloc() aloca memória suficiente para umamatriz de num objetos de tamanho size;A função devolve um ponteiro para o primeiro byte da regiãoalocada;Se não houver memória suficiente é devolvido um ponteiro nulo.

NF ED1-Aula 01

calloc - Exemplo de uso do calloc

1 #include<stdlib.h>2 #include<stdio.h>34 float ∗get_mem(void){5 float ∗p;67 p=calloc(100, sizeof(float));8 if(!p){9 printf("Erro de alocação − abortando.");

10 exit(1);11 }12 return p;13 }

NF ED1-Aula 01

malloc()

void *malloc(size_t size);

A função malloc() devolve um ponteiro para o primeiro byte deuma região de memória de tamanho size que foi alocada doheap;Se não houver memória suficiente é devolvido um ponteiro nulo;Sempre verificar se o valor devolvido não é um ponteiro nuloantes de utilizá-lo;

NF ED1-Aula 01

malloc - Exemplo de uso do malloc

1 #include<stdlib.h>2 #include<stdio.h>34 struct endereco{5 char nome[40];6 char rua[40];7 char cidade[40];8 char estado[2];9 };

1011 struct endereco ∗get_struct(void){12 struct endereco ∗p;1314 if ((p = malloc(sizeof(struct endereco)))==NULL){15 printf("Erro de alocação");16 exit(1);17 }18 return p;19 }

NF ED1-Aula 01

free()

void free(void *ptr);

A função free() devolve ao heap a memória apontada por ptr,tornando a memória disponível para alocação futura.free() deve ser chamado apenas com um ponteiro que foipreviamente alocado com as funções de alocação dinâmica.Um ponteiro inválido pode destruir o mecanismo degerenciamento de memória;

NF ED1-Aula 01

free - Exemplo de uso do free

1 #include<stdlib.h>2 #include<stdio.h>3 #include<string.h>4 #define tam 35 int main (){6 char ∗str[tam];7 int i;89 for (i=0; i<tam; i++){

10 if ((str[i] = malloc(128))==NULL){11 printf("Erro de alocação");12 exit(1);13 }14 gets(str[i]);15 puts(str[i]);16 }17 for (i=0; i<tam; i++) free(str[i]);18 return 0;19 }

NF ED1-Aula 01

realloc()

void *realloc(void *ptr, size_t size);

A função realloc() modifica o tamanho da memória previamentealocada apontada por ptr para aquele especificado por size;O valor de size pode ser maior ou menor que o original;Um ponteiro para o bloco de memória é devolvido porquerealloc() pode precisar mover o bloco para aumentar o seutamanho;Se precisar mover o bloco, o conteúdo do bloco antigo écopiado no novo bloco, nenhuma informação é perdida.Se size é zero, a memória apontada por ptr é liberada.Se não há memória livre suficiente no heap é devolvido umponteiro nulo e o bloco original é deixado inalterado.

NF ED1-Aula 01

realloc - Exemplo de uso do realloc

1 #include<stdlib.h>2 #include<stdio.h>3 #include<string.h>4 int main (){5 char ∗p;6 if ((p = malloc(23))==NULL){7 printf("Erro de alocação");8 exit(1);9 }

10 strcpy(p, "isso são 22 caracteres");1112 p = realloc(p,24);13 if(!p){14 printf("Erro de alocação");15 exit(1);16 }17 strcat(p,".");18 printf(p);19 free(p);20 return 0;21 }

NF ED1-Aula 01

Funções - Dividindo Tarefas?

NF ED1-Aula 01

Por que dividir o código em funções?

Dividir o código em módulos - Alinhar com orientação a objetos.Reuso: Reuso de código desenvolvido por outros

programadores.Exemplo: Funções de entrada e saída são o

exemplo mais direto deste reuso.Vantagens: Diminui o tempo de desenvolvimento do

programas.Vantagens: Funções foram testadas por diversos

usuários contribuindo para a redução doscustos de desenvolvimento dos projetos.

NF ED1-Aula 01

Forma Geral

1 tipo nome (tipo nome1, tipo nome2, ..., tipo nomeN ) {2 declaração das variáveis3 corpo da função4 }

NF ED1-Aula 01

E daí?

Uma função recebe uma lista de argumentos (nome1, nome2, ...,nomeN), executa comandos com estes argumentos e pode retornar ounão um resultado para a função que chamou esta função.

NF ED1-Aula 01

Funções

#include<stdio.h>

void function_name(void)

{

....

....

}

int main (void)

{

....

....

function_name();

....

return 0;

}

Chamada

Retorno

NF ED1-Aula 01

Observações

A lista de argumentos, também chamados de parâmetros, éuma lista, separada por vírgulas, de variáveis com seus tiposassociados.Não é possível usar uma única definição de tipo para váriasvariáveis.A lista de argumentos pode ser vazia, ou seja, a função nãorecebe nenhum argumento.O nome da função pode ser qualquer identificador válido.O tipo que aparece antes do nome da função especifica o tipodo resultado que será devolvido ao final da execução da função.O tipo void pode ser usado para declarar funções que nãoretornam valor algum.

NF ED1-Aula 01

Retornando.

Há basicamente duas maneiras de terminar a execução de umafunção.Normalmente usa-se o comando return para retornar o resultadoda função.Portanto, quando o comandoreturn expressão;

for executado, o valor da expressão é devolvido para a funçãoque chamou.Quando não há valor para retornar o comando return não precisaser usado e a função termina quando a chave que indica otérmino do corpo da função é atingido.

NF ED1-Aula 01

Exemplo

#include<stdio.h>

float media(float n1, float n2)

{

return (n1 + n2)/2;

}

int main (void)

{

float nt1, nt2, nt3, nt4;

float m1, m2;

scanf("%f %f %f %f", &nt1, &nt2, &nt3, &nt4);

m1 = media(nt1, nt2);

m2 = media(nt3, nt4);

printf("%f %f\n", m1, m2);

return 0;

}

ParâmetrosTipo função

Retorno

Nome

Chamadas

NF ED1-Aula 01

Observações

É importante notar que o nome da função pode aparecer emqualquer lugar onde o nome de uma variável apareceria.Além disso os tipos e o número de parâmetros que aparecem nadeclaração da função e na sua chamada devem estar na mesmaordem e ser tipos equivalentes.Os nomes das variáveis nos programas que usam uma funçãopodem ser diferentes dos nomes usados na definição da função.

NF ED1-Aula 01

Exemplo

1 #include<stdio.h>2 int fat(int n) {3 int f = 1;45 for ( ; n>1; n−−) {6 f ∗= n;7 }8 return f;9 }

10 int main ( void ) {11 int n, p, c;12 n = 5; p = 3;13 c = fat(n) / (fat(p) ∗ fat(n−p));14 printf("%d \n", c);15 return 0;16 }

NF ED1-Aula 01

Protótipos

O padrão ANSI estendeu a declaração da função para permitir que ocompilador faça uma verificação mais rígida da compatibilidade entreos tipos que a função espera receber e àqueles que são fornecidos.Protótipos de funções ajudam a detectar erros antes que elesocorram, impedindo que funções sejam chamadas com argumentosinconsistentes.

A forma geral de definição de um protótipo é a seguinte:tipo nome (tipo nome1, tipo nome2, ..., tipo nomeN);

NF ED1-Aula 01

Protótipos

O padrão ANSI estendeu a declaração da função para permitir que ocompilador faça uma verificação mais rígida da compatibilidade entreos tipos que a função espera receber e àqueles que são fornecidos.Protótipos de funções ajudam a detectar erros antes que elesocorram, impedindo que funções sejam chamadas com argumentosinconsistentes.

A forma geral de definição de um protótipo é a seguinte:tipo nome (tipo nome1, tipo nome2, ..., tipo nomeN);

NF ED1-Aula 01

Exemplo

1 #include<stdio.h>23 /∗ Prototipo da funcao ∗/4 int soma (int a, int b);56 /∗ Funcao Principal ∗/7 int main() {8 int a=5, b=9;9 printf("%d\n", soma(a,b));

10 return 0;11 }1213 /∗ Definicao da funcao ∗/14 int soma(int a, int b) {15 return a+b;16 }

NF ED1-Aula 01

Escopo de Variáveis

Variáveis podem ser definidas para serem usadas somentedentro de uma função particular, ou pode ocorrer que variáveisprecisem ser acessíveis à diversas funções diferentes.Por esta razão, temos que apresentar os locais onde as variáveisde um programa podem ser definidas e a partir destes locaispodermos inferir onde elas estarão disponíveis.As variáveis podem ser declaradas basicamente em três lugares:

dentro de funções, variáveis locaisfora de todas as funções, variáveis globaisna lista de parâmetros das funções parâmetros formais.

NF ED1-Aula 01

Escopo de Variáveis

int main()

int i, j;......j = f(i)

int f(int i)

int s, t;...return s;

int k; /* global */

bum!

pá!

NF ED1-Aula 01

Variáveis Locais

As variáveis locais são aquelas declaradas dentro de uma funçãoou um bloco de comandos.Elas passam a existir quando do início da execução do bloco decomandos ou função onde foram definidas e são destruídas aofinal da execução do bloco.Uma variável local só pode ser referenciada, ou seja usada,dentro da função (ou bloco) onde foi declarada.Variáveis locais são invisíveis para outras funções do mesmoprograma.

NF ED1-Aula 01

Exemplo

1 #include <stdio.h>2 void pares(void) {3 int i;4 for (i = 2; i <= 10; i += 2) {5 printf("%d: ", i);6 }7 }8 void impares(void) {9 int i;

10 for (i = 3; i <= 11; i += 2) {11 printf("%d: ", i);12 }13 }14 int main(int argc, char *argv[]) {15 pares();16 printf("\n");17 impares();18 return 0;}

NF ED1-Aula 01

Variáveis Globais

As variáveis globais são definidas fora de qualquer função e sãoportanto disponíveis para qualquer função.Este tipo de variável pode servir como uma canal decomunicação entre funções, uma maneira de transferir valoresentre elas.Por exemplo, se duas funções tem de partilhar dados, mais umanão chama a outra, uma variável global tem de ser usada.

NF ED1-Aula 01

Variáveis Globais

1 #include <stdio.h>2 int i; /* variavel global */3 void soma1(void) {4 i += 1;5 printf("Funcao soma1: i = %d\n", i);6 }7 void sub1(void) {8 int i = 10;9 i -= 1;

10 printf("Funcao sub1: i = %d\n", i);11 }12 int main(int argc, char *argv[]) {13 i = 0;14 soma1();15 sub1();16 printf("Funcao main: i = %d\n", i);17 return 0;18 }

NF ED1-Aula 01

Resultados

O resultado da execução deste programa é o seguinte:Funcao soma1: i = 1Funcao sub1: i = 9Funcao main: i = 1Observe que a variável global i recebe o valor 0 no início dafunção main.A função soma1 ao executar um comando que aumenta o valorde i em uma unidade está aumentando a variável global.Em seguida vemos que a função sub1 define uma variável localtambém chamada i e, portanto, a alteração feita por estafunção somente modifica esta variável.Finalmente, a função main imprime o valor final da variávelglobal.

NF ED1-Aula 01

Parâmetros Formais

As variáveis que aparecem na lista de parâmetros da função sãochamadas de parâmetros formais.Eles são criados no início da execução da função e destruídos nofinal.Normalmente os parâmetros são inicializados durante achamada da função, pois para isto foram criados.No entanto, as variáveis que atuam como parâmetros são iguaisa todas as outras e podem ser modificadas, operadas, etc, semnenhuma restrição.Parâmetros podem ser passados para funções: por valor ou porreferência.

NF ED1-Aula 01

Passagem por valor

Na passagem por valor uma cópia do valor do argumento é passadopara a função. Neste caso a função que recebe este valor, ao fazermodificações no parâmetro, não estará alterando o valor original quesomente existe na função que chamou.

NF ED1-Aula 01

Exemplo

1 #include<stdio.h>2 float Eleva(float a, int b) {3 float res = 1.0;4 for ( ; b>0; b--) res *= a;5 return res;6 }7 int main() {8 float numero;9 int potencia;

1011 puts("Entre com um numero");12 scanf("%f", &numero);13 puts("Entre com a potencia");14 scanf("%d", &potencia);15 printf("%f Elevado a %d e igual a %f\n",16 numero, potencia, Eleva(numero, potencia));17 return 0;18 }

NF ED1-Aula 01

Outro exemplo

1 #include <stdio.h>2 void trocar(int a, int b) {3 int temp;4 temp = a; a = b; b = temp;5 }6

7 int main(int argc, char *argv[]) {8 int a = 10, b = 20;9 trocar(a, b);

10 printf("a = %d, b = %d\n", a, b);11

12 return 0;13 }

NF ED1-Aula 01

Passagem por Referência

Na passagem por referência o que é passado para a função é oendereço do parâmetro e, portanto, a função que recebe pode,através do endereço, modificar o valor do argumento diretamente nafunção que chamou. Para a passagem de parâmetros por referência énecessário o uso de ponteiros.

Isto será visto na próxima apresentação.

NF ED1-Aula 01

Passagem de Vetores e Matrizes

Matrizes são um caso especial e exceção a regra que nomes devariáveis como parâmetros indicam passagem por valor. Comoveremos mais adiante, o nome de um vetor corresponde ao endereçodo primeiro elemento do array. Quando um nome de vetor é passadocomo parâmetro o endereço do primeiro elemento é passado.

NF ED1-Aula 01

Passagem de Vetores e Matrizes

Existem basicamente três maneiras de declarar um vetor comoum parâmetro de uma função.Na primeira ele é declarado segundo as regras de declaração deuma variável do tipo vetor.

NF ED1-Aula 01

Exemplo primeiro caso

1 #include<stdio.h>2 #define DIM 803 int conta (char v[DIM], char c);4 int main() {5 char c, linha[DIM];6 int maiusculas[26], minusculas[26];7 gets (linha);8 for (c = a; c <= z; c++)9 minusculas[c-a] = conta(linha, c);

10 for (c = A; c <= Z; c++)11 maiusculas[c-A] = conta(linha, c);12 for (c = a; c <= z; c++)13 if (minusculas[c-a])14 printf("%c apareceu %d vezes\n", c, minusculas[c-

a]);15 for (c = A; c <= Z; c++)16 if (maiusculas[c-A])17 printf("%c apareceu %d vezes\n", c, maiusculas[

c-A]);18 return 0;19 }

NF ED1-Aula 01

Exemplo primeiro caso

1 #include<stdio.h>2 #define DIM 803 int conta (char v[DIM], char c) {4 int i=0, vezes=0;5 while (v[i] != \0)6 if (v[i++] == c) vezes++;7 return vezes;8 }

NF ED1-Aula 01

Segundo caso

Uma outra maneira, leva em conta que apenas o endereço dovetor é passado.Neste modo o parâmetro é declarado como um vetor semdimensão.Isto é perfeitamente possível porque a função somente precisareceber o endereço onde se encontra o vetor.C não confere onde estão os limites de vetores e portanto afunção precisa do endereço inicial do vetor e uma maneira dedescobrir o final do vetor.Esta maneira pode ser, por exemplo, uma constante, ou ocaractere ’\0’ em um vetor de caracteres.

NF ED1-Aula 01

Exemplo segundo caso

12 #include<stdio.h>3 #define DIM 64 void Le_vetor (int v[], int tam);5 void Imprime_vetor (int v[], int tam);6 void Inverte_vetor (int v[], int tam);78 int main() {9 int v[DIM];

1011 Le_vetor(v, DIM);12 Imprime_vetor (v, DIM);13 Inverte_vetor (v, DIM);14 Imprime_vetor (v, DIM);15 return 0;16 }

NF ED1-Aula 01

Exemplo segundo caso

1 void Le_vetor (int v[], int tam) {2 int i;3 for ( i = 0; i < tam; i++) {4 printf("%d = ? ", i); scanf("%d", &v[i]);5 }6 }7 void Imprime_vetor (int v[], int tam) {8 int i;9 for (i = 0; i < tam; i++)

10 printf("%d = %d\n", i, v[i]);11 }12 void Inverte_vetor (int v[], int tam) {13 int i, temp;14 for (i = 0; i < tam/2; i++){15 temp = v[i];16 v[i] = v[tam-i-1];17 v[tam-i-1] = temp;18 }19 }

NF ED1-Aula 01

Passagem de Vetores e Matrizes

A terceira maneira de passagem de parâmetros implica no uso deponteiros

NF ED1-Aula 01

Passagem de argumentos por valor

Quando passamos argumentos a uma função, os valoresfornecidos são copiados para os parâmetros da função. Esteprocesso é idêntico a uma atribuição.Desta forma, alterações nos parâmetros dentro da função nãoalteram os valores que foram passados.

Exemplovoid nao_troca(int x, int y) {

int aux;aux = x;x = y;y = aux;

}

NF ED1-Aula 01

Passagem de argumentos por referência

Existe uma forma de alterarmos as variáveis passadas comoargumento, ao invés de usarmos apenas o seu valor.O artifício é passarmos como argumento o endereço da variável,e não o seu valor.Para indicarmos que será passado o endereço do argumento,usamos o mesmo tipo que usamos para declarar um variável queguarda um endereço.

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

comandos;}

NF ED1-Aula 01

Passagem de argumentos por referência

Um endereço de uma variável passado como parâmetro não émuito útil. Para acessarmos o valor de uma variável apontadapor um endereço, usamos o operador *;Ao precedermos uma variável que contém um endereço comeste operador, obtemos o equivalente a variável armazenada noendereço em questão;

Exemplovoid troca(int *x, int *y) {

int aux;aux = *x;*x = *y;*y = aux;

}

NF ED1-Aula 01

Passagem de argumentos por referência

Uma outra forma de conseguirmos alterar os valores de variáveisexternas a funções é usando variáveis globais;Nesta abordagem usamos variáveis globais no lugar deparâmetros e de valores de retorno;Porém, ao usar esta técnica estamos negando uma das principaisvantagens de se usar funções, reaproveitamento de código.

NF ED1-Aula 01

Vetores em funções

Vetores têm um comportamento diferente quando usados comoparâmetros ou valores de retorno de funções;Por padrão, um vetor é interpretado pelo compilador como oendereço do primeiro elemento do vetor;Desta forma, sem precisarmos usar uma notação especial, osvetores são sempre passados por referência.

Maneiras para declarar um parâmetro que receberá um vetorvoid display(int num[10])

void display(int num[])

void display(int *num) // Forma mais usada

NF ED1-Aula 01

Vetores em funções

Ao passar um vetor como parâmetro não é necessário fornecer oseu tamanho na declaração da função. Porém, é importantelembrar que o vetor tem um tamanho que deve ser considerado.Quando o vetor é multi-dimensional a possibilidade de nãoinformar o tamanho na declaração se restringe apenas aprimeira dimensão.

Maneiras para declarar um parâmetro que receberá um vetorvoid display(int num[10])

void display(int num[])

void display(int *num) // Forma mais usada

NF ED1-Aula 01