algoritmos e estruturas de dados ii por que alunos de engenharia

17
16/08/2011 1 Algoritmos e Estruturas de Dados II Gisele L. Pappa, Clodoveu Davis e Raquel ([email protected]) Por que alunos de engenharia são obrigados a fazer AEDS2? Por que alunos de computação são obrigados a fazer AEDS2? AEDS2: e a diversão começa! Como criar seu próprio Facebook? • Como representar seu perfil, ou seja, como armazenar as Informações pessoais? • Como armazenar sua lista de amigos? • Como armazenar 1 bilhão de usuários? • Como buscar um novo amigo? • Como sugerir novos amigos? •Como ordenar suas fotos em ordem cronológica?

Upload: tranthuy

Post on 07-Jan-2017

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

1

Algoritmos e Estruturas de Dados II

Gisele L. Pappa, Clodoveu Davis e Raquel

([email protected])

Por que alunos de engenharia são obrigados a fazer AEDS2?

Por que alunos de computação são obrigados a fazer AEDS2?

AEDS2: e a diversão começa!

Como criar seu próprio Facebook?

• Como representar seu perfil,ou seja, como armazenar asInformações pessoais?

• Como armazenar sua lista deamigos?

• Como armazenar 1 bilhãode usuários?

• Como buscar um novo amigo?

• Como sugerir novos amigos?

•Como ordenar suas fotos em ordem cronológica?

Page 2: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

2

Ementa

• Tipos Abstratos de Dados (TADs)

• Análise de Algoritmos

O(n), O(n log n), )(n!), ...

• Estruturas de dados

listas, filas, pilhas e árvores

• Métodos de ordenação

quick, heap, merge, select, etc

• Métodos de pesquisa

hash, árvores binárias, árvores digitais

Parte 1Prova 1 – 13/09

TP1

Parte 2Prova 2 – 06/10

TP2

Parte 3Prova 3 – 17/11

TP3

Por que esse auditório vai começar assim....

E terminar assim???? Avaliação

• 3 provas (total 60 pontos)

• 3 trabalhos práticos power – (total 35 pontos)

• Implementação

• Documentação

• Teste

• 1 trabalho prático menos power (3 pontos)

• Exercícios (total 2 pontos)

Moddle

• Todas informações relacionadas ao curso, incluindo notas de aulas, estarão disponíveis no Moodle

• Sistema de submissão de trabalhos práticos

• Prático

http://aeds.dcc.ufmg.br

Detalhes

• Linguagem: C

• Software Recomendado: CodeBlocks

• Instruções de instalação no Learnloop

• Sistema operacional recomendado: Linux

• Alta carga extra classe

Page 3: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

3

Programação em Crecomendações e boas práticas

Clodoveu Davis

Gisele L. Pappa

Tópicos

• Indentação

• Comentários

• Modularização

• Compilação e Debug

• Entrada e saída

• Vetores e Strings

• Passagem de parâmetros

• Structs

Boas Práticas

• Com um pequeno esforço extra, programas escritos em C podem se tornar mais legíveis e mais facilmente “debugáveis”

• No caso de disciplinas de programação, isso ainda ajuda no entendimento das idéias e na correção de trabalhos

Indentação

• É usual empregar TABS para indicar blocos de programação

– Em geral, 1 tab equivale a 8 espaços, MAS NÃO USAR ESPAÇOS para alinhar

• Há vários estilos

• Quando o bloco é longo, é usual colocar um pequeno comentário após o fechamento indicando o que está sendo fechado

Indentação

• K&R: Kernighan & Ritchie

Indentação

• 1TBS: One True Brace Style

Page 4: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

4

Indentação

• Allman

Comentários

• Importantes para compreensão do código

• Mais importantes em código mais complexo

• Úteis para explicar o conteúdo de variáveis, mas não substituem um bom critério de atribuição de nomes

• Não exagerar!

Comentários

• No início de cada módulo de código (arquivos .c, .h)

• Uma linha em cada função, explicando o que ela faz– Não é necessário explicar COMO ela faz, o código deve ser

claro o bastante para permitir esse entendimento em uma função razoavelmente pequena

– Se necessário, considerar a quebra em outras funções

• Comentário na linha da declaração, se necessário, para esclarecer o significado/o uso de uma variável

• Comentário na linha do fecha-chave, para ajudar a entender blocos e loops

Comentários

• No início de um bloco/arquivo fonte

Comentários

• Em função (simples)

Comentários

• Em funções (arquivo .h)

Page 5: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

5

Comentários

• Em variáveis

• Em structs

Comentários

• No fim de um bloco de programa

• No código

Modularização

• Planejar a quebra de um programa em módulos– Um módulo não significa necessariamente um arquivo

fonte; muitas vezes, é um par de arquivos .c / .h

– Existe sempre um arquivo fonte para o programa principal (main), e outros para funções adicionais ou componentes

• Montar módulos especificamente para tipos abstratos de dados [aula: TAD]

• Procurar dar independência aos módulos, para que possam eventualmente ser reaproveitados

Modularização

Modularização Modularização

Page 6: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

6

Modularização

Atenção: incluir timer.h e timer.c no projeto

Modularizaçãotransformação em biblioteca

timer.lib

Copiar timer.h para o diretório “includes” do compilador

Copiar timer.lib para o diretório lib do compilador

Constantes e #define

• Não usar “números mágicos” no código

• Algumas constantes usadas no programa podem ter que ser modificadas, e é mais fácil fazer isso em um lugar só

• Sempre que for tornar o código mais legível, usar #define para dar um nome à constante– Em geral, nomes de constantes são em maiúsculas

#define PI 3.141592

#define MAX_VETOR 1000

Nomes de variáveis

• Algumas variáveis merecem nomes significativos: MAX_VETOR, numClientes, listaAlunos

• Variáveis auxiliares em geral recebem nomes curtos: i, j, aux, x

– Cuidado para não fazer confusão– Não abusar: i, ii, iii, aux1, aux2, aux3...

– Variáveis inteiras: i, j, k– Variáveis reais: x, y, z– Strings: s1, s2– Booleanas: nome do teste (existe, valido, ocorre)

Nomes de variáveis

• Estilos variados:– Só minúsculas (i, num, conta)

– Só maiúsculas (constantes: PI, E, MAX)

– CamelCase (numMat, anguloEntrada)

– Indicação do tipo no início do nome (iNum, iValor, fRaio, fAltura, dVolume)

• Há quem prefira inserir comentários e usar nomes de variáveis em inglês, por ficar mais próximo da linguagem de programação

Organização e limpeza

• Procurar dar um aspecto organizado ao código, ajuda na compreensão

• Entender o código fonte como um instrumento de comunicação

• Comentar excessivamente código mal escrito não ajuda

• Dar nomes adequados a variáveis ajuda bastante

Page 7: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

7

Parênteses e espaçamento

• Usar espaços antes de parênteses, depois de vírgulas, ao redor de operadores bináriosif (x == 10) y = 5;

for (i = 0; i < 10; i++) {

x += a;

a = f(b);

}

• Cuidado com notações compactas demais, e com comandos embutidos em outrosif (x++ == b) y = 5;

Correção e robustez

• Testes: prever todo tipo de problema e variações na entrada de dados

– Limites de vetores

– Valores inteiros e de ponto flutuante

– Contadores e incremento

– Testes de fim de arquivo

– Teste de disponibilidade de memória para alocação

Compilação

• LER as mensagens de erro e ENTENDER a origem do problema

• Warnings: indicam problemas potenciais, devem ser resolvidos

• Muitas vezes a mensagem de erro não reflete o que está ocorrendo– Observar a linha em que o erro foi indicado, a

linha anterior, o bloco de código em que ocorreu, e o corpo da função em que ocorreu

Debugger

• Ajuda a acompanhar os valores das variáveis ao longo da execução

– Observar o valor de variáveis (watches)

– Posicionar pontos de interrupção (breakpoints)

– Executar passo a passo

• Videhttp://wiki.codeblocks.org/index.php?title=Debugging_with_Code::Blocks

• Documentação do CodeBlockshttp://wiki.codeblocks.org/index.php?title=Main_Page

ENTRADA E SAÍDA

I/O em C

• Formalmente, rotinas de entrada e saída não fazem parte da linguagem, e sim de bibliotecas que acompanham os compiladores

– Felizmente, são padronizadas

– Exige-se a linha #include <stdio.h> para usá-las

Page 8: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

8

I/O em C

• printf(string [, valor , valor, ...]);

– O string contém uma “máscara” (template) com lacunas reservadas para os valores que serão impressos

– Pode não existir lacuna

printf(“O valor de x eh %d”, x);

printf(“Area: %f\n”, PI*d*d/4);

printf(“Nome: %s”, nomeAluno);

printf

• Especificadores de formato

– %c (char)

– %s (string)

– %d (int)

– %ld (long int)

– %f (float)

– %lf (double)

– %e (float notação científica)

– %g (e ou f, ou seja, notação científica se necessário)

printf

• Especificação completa

Caracteres de escape

• Acrescentados à máscara para provocar reposicionamento do cursor

– \n: nova linha

– \t: tabulação

– \r: backspace

– \\: caractere da barra invertida

Entrada

• Com máscara: scanf(string, *var [, *var, ...]);

– Mesmos especificadores de formato do printf

– A função precisa receber o endereço da variável à qual o valor digitado será atribuídoscanf(“%d”, &num)

scanf(“%c%d”, &letra, &num);

scanf(“%c”, &ch);

scanf(“%s”, s); // string

scanf(“%13c”, s); //le 13 caracteres

scanf(“ %c”, &ch); //pula brancos

Entrada

Page 9: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

9

Entrada

• Observe que scanf interrompe a leitura de um string quando encontra um branco, se usado com %s

• Uso de %[]:

– %[aeiou]: apenas as vogais são permitidas

– %[^aeiou]: as vogais não são permitidas

– %[^\n]: interrompe quando recebe um [enter]

– %60[^\n]: admite até 60 caracteres, e para quando encontra um enter

Entrada

• Linhas inteiras: gets(string)

– Lê uma linha inteira, excluindo \n, e coloca \0 no final

– Com limite de tamanho: • fgets(string, tamMax, stdin)

Entrada

• Caracteres individuais: getchar()

– O caractere digitado é o valor de retorno da função

I/O para arquivos

• A entrada do teclado e saída para o monitor são realizadas internamente considerando três dispositivos virtuais: stdin, stdout e stderr

– Como são dispositivos padrão, referências a stdin e stdout eles são omitidas dos comandos

• I/O para arquivos é muito semelhante à operação com stdin e stdout, mas um handle

ao arquivo tem que ser fornecido

I/O para arquivos

• O handle é obtido no momento da abertura do arquivoFILE *inFile; // variável handle

FILE *outfile;

...

//abre o arquivo para leitura (r) ou gravacao (w)

inFile = fopen(“arquivo.txt”, “r”);

outFile = fopen(“saida.txt”, “w”);

...

fscanf(inFile, “%d”, &num);

...

fprintf(outFile, “O valor lido eh %8.2d\n”, num);

...

fclose(inFile);

fclose(outFile);

I/O para arquivos

• fopen: modos de abertura

Page 10: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

10

I/O para arquivos

• Se o handle retornar nulo do comando fopen, então ocorreu erro (arquivo não encontrado, arquivo travado contra gravação, permissão negada pelo sistema operacional, etc.)

• Testar:if ((inFile = fopen(“arquivo.txt”, “r”)) == NULL)

{

printf(“Nao consegui abrir.\n”);

exit(1);

}

I/O para arquivos

• gets() � fgets(arq, tamMax, string);

• getchar() � fgetc(arq);

• putc(ch) � fputc(arq, ch)

• printf � fprintf(arq, string, valor)

• scanf � fscanf(arq, string, endereço)

• feof(arq)

– Retorna booleano indicando se o fim do arquivo foi atingido

– Neste caso, o fgetc retorna a constante EOF, definida em stdio como 0xFFFF

I/O para arquivos

• Exemplo

Exercício (POSCOMP 2009)#include<stdio.h>

#include<string.h>

int main (void)

{

char texto[]= "foi muito facil";

int i;

for (i = 0; i < strlen(texto); i++){

if (texto[i] == ' ') break;

}

i++;

for ( ; i < strlen(texto); i++)

printf("%c", texto[i]);

return 0;

}

O que será impresso quando o programa for executado?

I/O para arquivos

• Exemplo (variação)

VETORES E STRINGS

Page 11: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

11

Alocação estática de memória

• Ao se declarar uma variável qualquer, o compilador deixa reservado um espaço suficiente na memória para armazená-la

int a; // 2 bytes

long b; // 4 bytes

float x; // 4 bytes

double y; // 8 bytes

char c; // 1 byte

Alocação estática de memória

• Ao fazer a alocação estática, apenas o espaço necessário na memória é reservado

• O conteúdo de cada posição não é alterado, e portanto uma variável apenas declarada pode conter qualquer coisa

• Inicializar as variáveis, atribuindo valores, antes do uso

– Inclusive vetores, matrizes e strings

Vetores

• Quando se declara um vetor, o valor entre chaves indica quantas vezes o espaço de memória necessário para o tipo básico será alocado

int v[100]; // 100 * sizeof(int) = 200 bytes

long vl[200]; // 200 * sizeof(long) = 800 bytes

double z[1000]; // 1000 * sizeof(double) = 8000 bytes

Vetores

• A referência a uma posição de um vetor indica o cálculo de uma posição de memória a partir do início do vetorfloat x[1000];

// x[20] está na posição x + 20*sizeof(float)

• Na verdade, o símbolo x é um apontador para o início da região de memória reservada para o vetor

Vetores

• C NÃO AVISA NEM PRODUZ ERRO QUANDO O LIMITE DE UM VETOR OU MATRIZ FOR EXCEDIDOy = x[2000]; // não dá erro, mas vai acessar

// uma parte inesperada da memória

– Erro mais comum (runtime): segmentation fault

• É responsabilidade do programador verificar os limites, e garantir que não sejam excedidos

Matrizes = Vetores de mais de uma dimensão

• Na verdade, a alocação na memória é linear

• Muda apenas o cálculo da posição de memória do elemento referenciado

int M[5][5];

...

M[0][0] = 15;

M[2][3] = 2; // posicao: M + (2*5 + 3)*sizeof(int)

Page 12: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

12

Strings

• Um string é um vetor do tipo char

• Para manipulação do string, atribuindo e recuperando valores, e realizando operações sobre ele, é importante entender essa característica

• Quando o conteúdo de um string não ocupa todo o espaço disponível, usa-se um caractere ‘\0’ (ou NULL, código ASCII 0) como delimitador

Strings

• Strings constantes aparecem no código entre aspas

printf(“%s”, “Bom dia!”);

• O delimitador \0 está incluído:

Strings

• Não é possível fazer atribuições diretas para strings

• Usar a função strcpy ou a função strncpy

Strings

• Na inicialização, pode-se usar o mesmo recurso disponível para vetores

• char nome[] = {‘A’, ‘n’, ‘a’, ‘\0’};

• Ou• char nome[] = “Ana”;

Strings

• Como o nome do string representa o endereço onde começa o string, é possível manipulá-lo diretamente

– Cuidado!

• Exemplochar nome[] = “Alexandre”;

printf(“%s\n”, nome + 3); // imprime “xandre”

Strings

• Funções

– strlen(st): retorna o comprimento do string (com exceção do \0)

– strcat(st1, st2): concatena o s2 no s1 (s1 tem que ter espaço)

– strcmp(s1, s2): retorna <0 se s1 é menor que s2, ==0 se s1 é igual a s2, e >0 se s1 é maior que s2 (ordem alfabética)

• A comparação entre strings também tem que ser feita caractere a caractere, portanto não se pode usar s1==s2; isso só compara os endereços

Page 13: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

13

Strings

• strncat, strncmp, strncpy: idem aos anteriores, mas especifica o número de caracteres que serão considerados

Strings• strtok: extrai “tokens”, substrings delimitados

• Exemplolong int num; char linha[256];

...

while (!feof(infile)) {

fgets(linha, 256, infile);

p1 = strtok(linha, " \n"); //delim: branco ou fim de linha

while ((p1 != NULL) && (!feof(infile)))

{

num++;

fprintf(outfile, "%s\n", p1);

p1 = strtok(NULL, " \n");

}

}

printf("O arquivo de entrada tinha %ld palavras.\n", num);

fclose(infile);

Strings

• Vetores de strings podem ser criados

• Exemplo

char DiaSemana[7][14] = {“Domingo”,

“Segunda”, “Terça”, “Quarta”,

“Quinta”, “Sexta”, “Sabado”};

...

printf(“%s\n”, DiaSemana[3]);

Algoritmos e Estrutura de Dados II

Alocação Estática x Dinâmica• Linguagens de programação como Pascal, C e C++

permitem dois tipos de alocação de memória: Estática e

Dinâmica

• Na alocação estática, o espaço de memória para as

variáveis é reservado no início da execução, não podendo

ser alterado depois

– int a; int b[20];

• Na alocação dinâmica, o espaço de memória para as

variáveis pode ser alocado dinamicamente durante a

execução do programa

Algoritmos e Estrutura de Dados II

E Java?

• Em java não existe manipulação explícita de apontadores.

• Todo objeto é criado dinamicamente (new) e as variáveis apontam para os objetos

– Variáveis dos tipos básicos são alocadas estaticamente (não é necesário o new)

• A desalocação de memória é feita automaticamente (garbage collection)

Algoritmos e Estrutura de Dados II

Alocação Dinâmica• A memória alocada dinamicamente é acessada

através de Apontadores (pointers) que na verdade são variáveis que armazenam o endereço de uma área de memória

• A memória alocada dinamicamente faz parte de uma área de memória chamada heap

– Basicamente, o programa aloca e desaloca porções de memória do heap durante a execução

Page 14: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

14

Algoritmos e Estrutura de Dados II

Alocação Dinâmica

a

HeapMemória Estática

10

0x214

0x218

0x222

0x226

0x230

0x234

0x238

0x242

0x246

a é um intb é um apontador para um int

b 0x234

10

0x016

0x020

Algoritmos e Estrutura de Dados II

Apontadores – Notação em C

• definição de p como um apontador para uma variável do tipo T

– T *p;

• Alocação de memória para uma variável apontada por p

– p = (T*) malloc(sizeof(T));

• Desalocação de memória

– free(p);

• Conteudo da variável apontada por P

– *p;

• Valor nulo para um apontador

– null;

• Endereço de uma variável a (endereço do primeiro byte)

– &a;

Algoritmos e Estrutura de Dados II

Endereço da Variável• Endereço do primeiro byte.

• Exemplo

2293612

2293611

2293552

2293544

int i;

char c;

int v[5];

struct {

int x,y;

} p;

printf("%d\n", &i);

printf("%d\n", &c);

printf("%d\n", &v);

printf("%d\n", &p);

Endereços Impressos:

P – 8 bytes

P – 8 bytes

Algoritmos e Estrutura de Dados II

Alocação Dinâmica

int *a, b;...b = 10;a = (int *) malloc(sizeof(int));*a = 20;a = &b;*a = 30; // qual o valor de b?

HeapMemória Estática

Algoritmos e Estrutura de Dados II

Alocação Dinâmica

int *a, b;...b = 10;a = (int *) malloc(sizeof(int));*a = 20;a = &b;*a = 30; // qual o valor de b?

a

20

b

HeapMemória Estática

10

X

30

Memória não foi desalocada. O espaço continua ocupado

Algoritmos e Estrutura de Dados II

Erros Comuns

• Esquecer de alocar memória e tentar acessar o conteúdo da variável

• Copiar o valor do apontador ao invés do valor da variável apontada

• Esquecer de desalocar memória

– Ela é desalocada ao fim do programa ou procedimento função onde a variável está declarada, mas pode ser um problema em loops

• Tentar acessar o conteúdo da variável depois de desalocá-la

Page 15: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

15

Algoritmos e Estrutura de Dados II

Alocação Dinâmica de Vetores

• Normalmente, a alocação dinâmica é utilizada para criar vetores em tempo de execução

• Exemplo:

int *p;

p = (int *)malloc(10*sizeof(int));

– Aloca um vetor de inteiros com x posições. A manipulação pode ser feita normalmente: p[i] = ...

– O apontador p guarda o endereço (aponta) da primeira posição do vetor.

Algoritmos e Estrutura de Dados II

Vetores e Apontadores• Na verdade, em C todo vetor (mesmo alocados

de forma estática) pode ser visto como um apontador.

• Pode se trabalhar usando ambas notações:

– *p é equivalente a p[0]

– p é equivalente a &p[0]

– *(p + i) é equivalente a p[i]

– considerando v um vetor alocado estaticamente, e p dinamicamente, pode-se fazer p = v, mas não v = p (v é, de certa forma, um “ponteiro constante”)

6 4

p

0 1 ...

Alocação Dinâmica de Matrizes• Declaração de Matriz Dinâmica: int** result_matrix;

int** read_matrix(int size_x, int size_y)

{

int** matrix;

int i;

matrix = calloc(size_x, 1+sizeof(int*)); // alloc one

extra ptr

for(i = 0;i<size_x;i++) {

matrix[i] = calloc(size_y, sizeof(int));

}

matrix[size_x] = NULL; // set the extra ptr to NULL

for(int i = 0;i<size_x;i++) {

for(int j = 0;j<size_y;j++) {

matrix[i][j] = i*10+j;

}

}

return matrix;

}

Matrizes

void free_matrix(int **matrix, int rows){

int i;for(i=0; i<rows; i++){

free(matrix[i]);}free(matrix);

}

Reallocvoid *realloc(void *ptr, size_t size)

int main() { char buf[80], *message; puts("Enter a line of text."); gets(buf); /* Allocate the initial block and copy the string to it. */message = realloc(NULL, strlen(buf)+1); strcpy(message, buf); puts(message); puts("Enter another line of text."); gets(buf); // Increase the allocation, and concatenate the string to it.message = realloc(message,(strlen(message) + strlen(buf)+1)); strcat(message, buf); puts(message); return 0;

}Algoritmos e Estrutura de Dados II

Exercício: O que vai ser impresso?double a;

double *p, *q;

a = 3.14;

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

p = &a;

*p = 2.718;

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

a = 5;

printf("%f\n", *p);

p = NULL;

p = (double *)malloc(sizeof(double));

*p = 20;

q = p;

printf("%f\n", *p);

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

free(p);

printf("%f\n", *q);

int a, b, i, v[10];

int *p;

b = 10;

p = &b;

a = *p + 100;

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

a = *&b;

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

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

v[i] = i;

p = v;

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

*(p+i) = 10*i;

p = p + 5;

*p = -5;

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

printf(“%d”,v[i]);

3.142.718

5.020.0

5.0?

11010

010203040-56789

Page 16: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

16

Algoritmos e Estrutura de Dados II

Apontadores para Tipos Estruturados• Apontadores podem ser utilizados com tipos

estruturados. Isso é muito comum na criação de estruturas encadeadas (listas, filas, etc...)

typedef struct {

int idade;

double salario;

} TRegistro;

...

TRegistro *a;

...

a = (TRegistro *) malloc(sizeof(TRegistro);

a->idade = 30; // equivalente: (*a).idade

a->salario = 80; Algoritmos e Estrutura de Dados II

Passagem de Parâmetros• Em pascal e C++, parâmetros para função podem ser

passados por valor ou por referência

– Por valor: o parâmetro formal (recebido no procedimento) é

uma cópia do parâmetro real (passado na chamada)

– Por referência: o parâmetro formal (recebido no procedimento)

é uma referência para o parâmetro real (passado na chamada)

• As modificações efetuadas acontecem no parâmetro real

• Em C só existe passagem por valor, logo deve-se

implementar a passagem por referência utilizando-se

apontadores

Algoritmos e Estrutura de Dados II

Passagem de Parâmetros (C)

void SomaUm(int x, int *y)

{

x = x + 1;

*y = (*y) + 1;

printf("Funcao SomaUm: %d %d\n", x, *y);

}

int main()

{

int a=0, b=0;

SomaUm(a, &b);

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

}

1 1

0 1

Algoritmos e Estrutura de Dados II

Passagem de Parâmetros• E para alocar memória dentro de um procedimento?

– Em pascal, basta passar a variável (apontador) como referência.

– Em C também, mas como não há passagem por referência as

coisas são um pouco mais complicadas

void aloca(int *x, int n)

{

x=(int *)malloc(n*sizeof(int));

x[0] = 20;

}

int main()

{

int *a;

aloca(a, 10);

a[1] = 40;

}

Error!Access Violation!

void aloca(int **x, int n)

{

*x=(int *)malloc(n*sizeof(int));

*x[0] = 20;

}

int main()

{

int *a;

aloca(&a, 10);

a[1] = 40;

}

OK

Algoritmos e Estrutura de Dados II

Exercícios

1. Faça um programa que leia um valor n, crie dinamicamente um vetor de n elementos e passe esse vetor para uma função que vai ler os elementos desse vetor.

2. Declare um TipoRegistro, com campos ainteiro e b que é um apontador para char. No seu programa crie dinamicamente uma váriavel do TipoRegistro e atribua os valores 10 e ‘x’ aos seus campos.

Algoritmos e Estrutura de Dados II

Respostas (1)

void LeVetor(int *a, int n){

int i;

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

scanf("%d",&a[i]);

}

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

int *v, n, i;

scanf("%d",&n);

v = (int *) malloc(n*sizeof(int));

LeVetor(v,n);

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

printf("%d\n",v[i]);

}

Apesar do conteúdo ser modificadoNão é necessário passar por referência pois todo vetor jáé um apontador...

Page 17: Algoritmos e Estruturas de Dados II Por que alunos de engenharia

16/08/2011

17

Algoritmos e Estrutura de Dados II

Respostas (2)

typedef struct {

int a;

char *b;

} TRegistro;

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

{

TRegistro *reg;

reg = (TRegistro *) malloc(sizeof(TRegistro));

reg->a = 10;

reg->b = (char *) malloc(sizeof(char));

*(reg->b) = 'x';

printf("%d %c",reg->a, *(reg->b));

}

É necessário alocar espaço parao registro e para o campo b.*(reg->b) representa o conteúdoda variável apontada por reg->b

Passagem de parâmetros para o programa

• Chamada: C:\> prog.exe arg1 arg2 arg3

• Declaração completa da função mainint main(int argc, char *argv[])

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

• argv: um vetor de argc strings

– argv[0]: nome do programa

– argv[1]: primeiro parâmetro

– argv[argc – 1]: último parâmetro

– argv[argc] é sempre NULL

Referências

• Mizrahi, V. V. Treinamento em Linguagem C. Pearson, 2008.

• Kernighan B.W., Ritchie, D.M. C A linguagem de programação (padrão ANSI). Campus, 1989.

• Vide Moodle para links (inclusive cursos online), exemplos e exercícios