Por que alunos de engenharia são obrigados a fazer AEDS2? Algoritmos e Estruturas de Dados II

Documentos relacionados
Alocação Dinâmica de Memória

BCC202 - Estrutura de Dados I

Sumário. Introdução à Ciência da Computação. Ponteiros em C. Introdução. Definição. Por quê ponteiros são importantes?

Estruturas da linguagem C. 1. Identificadores, tipos primitivos, variáveis e constantes, operadores e expressões.

Linguagem C: Introdução

Introdução a Programação de Jogos

Exercícios. Alocação Dinâmica. Alocação dinâmica de memória. Alocação de memória. Alocação da Memória Principal. Alocação da Memória Principal

Módulo 5 Vetores e Alocação Dinâmica

1 Exercícios com ponteiros

Alocação Dinâmica em C

INF 1007 Programação II

INF1007: Programação 2. 2 Alocação Dinâmica. 17/02/2014 (c) Dept. Informática - PUC-Rio 1

O que é um apontador em C (type pointer in C)?

Linguagem C Princípios Básicos (parte 1)

Estruturas de Dados Aula 2: Estruturas Estáticas 02/03/2011

Estruturas de Dados Aulas 3 e 4: Uso da. 14/03/2011 e 16/03/2011

Universidade Federal de Uberlândia Faculdade de Computação. Linguagem C: ponteiros e alocação dinâmica

Métodos Computacionais

Programação: Vetores

Tipos Abstratos de Dados. Estrutura de Dados

ALGORITMOS E ESTRUTURAS DE DADOS CES-11

Introdução à Computação

Hello World. Linguagem C. Tipos de Dados. Palavras Reservadas. Operadores Aritméticos. Pré e pós incremento e pré e pós decremento

A Linguagem C. A forma de um programa em C

Alocação de Memória. Lucas Ferrari de Oliveira Professor Adjunto Universidade Federal do Paraná (UFPR)

Linguagem C Ficheiros Compilação Separada

Ambiente de desenvolvimento

PROGRAMAÇÃO I E N T R A DA E S A Í DA D E DA D O S

CAP. IX - MANIPULAÇÃO DE ARQUIVOS Generalidades sobre Arquivos. 9.2 Abertura e Fechamento de Arquivos. Operações com arquivos:

Vetores e Matrizes. Conceito. Conceito. Conceito. Conceito. Conceito. Variáveis Compostas Homogêneas. Matriz

ponteiros INF Programação I Prof. Roberto Azevedo

Introdução à Linguagem C

cadeia de caracteres (string) INF Programação I Prof. Roberto Azevedo

A linguagem C permite dois tipos de alocação de memória: Alocação estática e alocação dinâmica.

1 Exercícios com ponteiros

Estrutura de Programas e Tipos de Dados Simples

Anhanguera Educacional S.A. Centro Universitário Ibero-Americano

Universidade Estadual de Mato Grosso do Sul Ciência da Computação Algoritmos e Estruturas de Dados I (AED-I) Prof. Nilton

Matrizes em C. Lucas Ferrari de Oliveira Professor Adjunto. Universidade Federal do Paraná

Comandos de entrada. e saída. Comandos de entrada. Comandos de entrada. Comandos de entrada. Comandos de entrada. Comandos de entrada.

Apêndice B. Cadeias de Caracteres (Strings)

Linguagem C Controle do Fluxo de Execução. Lógica de Programação

Introdução à Linguagem C

C++ - Matrizes. Observ.: C++ não avisa quando o limite de uma matriz foi excedido. Providenciar a verificação é responsabilidade do programador.

Computação para Informática - Prof. Adriano Joaquim de Oliveira Cruz Segunda Aula Prática - 3 de setembro de 2010

Métodos Computacionais. Funções, Escopo de Variáveis e Ponteiros

Capítulo 2 Operadores. A função scanf()

Funções em C. Lucas Ferrari de Oliveira Professor Adjunto. Linguagem de Programação Estruturada I. Universidade Federal do Paraná

Linguagem C: Ponteiros - Alocação Dinâmica

Introdução à Programação em C (II)

Outline. 33. Manipulação de arquivos DIM

Introdução à Linguagem C Variáveis e Expressões

Estruturas de Dados Aula 6: Cadeias de 28/03/2010

Vetores. e o programa deverá ler os valores separadamente:

Variáveis primitivas e Controle de fluxo

Introdução à Programação. Introdução a Linguagem C. Prof. José Honorato F. Nunes

Trabalho Linguagem e Programação de Compiladores

Universidade Federal do Espírito Santo. Programação I Tipos de Dados Básicos - C Professora: Norminda Luiza

Strings. Introdução. Definição de strings. Criação/Declaração de strings. Inicialização de strings. Manipulação de strings. Exemplos.

19 Vetores, Ponteiros e Funções

Material sobre Funções AEDS 1

Linguagens de Programação PROGRAMAÇÃO DE COMPUTADORES. Linguagem C. Linguagem C Estrutura Básica. Constante (literais) Linguagem C Primeiro Programa

11 - Estrutura de um programa em C

Professora Jeane Melo

Linguagem e Técnicas de Programação

Variáveis, Tipos de Dados e Operadores

Algoritmos e Estruturas de Dados I IEC012. Linguagem C - Guia de bolso - Prof. César Melo

Disciplina de Algoritmos e Programação

Algoritmos e Programação. Linguagem C Procedimentos e. Eliane Pozzebon

Computação L2. Linguagem C++ Observação: Material Baseado na Disciplina Computação Eletrônica.

Tipos Abstratos de Dados

INF 1620 P3-29/06/04 Questão 1 Nome:

Linguagem C. Armazenamento de Dados em Arquivos - Continuação

LINGUAGEM C: ALOCAÇÃO DINÂMICA

Aula 5 Oficina de Programação Introdução ao C. Profa. Elaine Faria UFU

Tipos de Dados, Variáveis e Entrada e Saída em C. DCC 120 Laboratório de Programação

Classes o Objetos. Classes, objetos, métodos e variáveis de instância

INF 1005 Programação I

Estruturas de Dados I

Computação para Informática - Prof. Adriano Joaquim de Oliveira Cruz Segunda Aula Prática - 29 de agosto de 2008

INTRODUÇÃO A LINGUAGEM C

Gilberto A. S. Segundo. 24 de agosto de 2011

4. Estruturas Fundamentais de Programação em C

Depuração e Teste de programas C C Depuração e teste de programas C

Algoritmos RESUMO - LINGUAGEM C

Métodos Computacionais. Operadores, Expressões Aritméticas e Entrada/Saída de Dados

Métodos Computacionais. Strings (Vetor de Caracteres)

Programação Básica. Estrutura de um algoritmo

Lição 4 Fundamentos da programação

Algoritmos I Aula 13 Linguagem de Programação Java

Programação de Computadores I Arquivos na Linguagem C PROFESSORA CINTIA CAETANO

Estruturas de Repetição

Fundamentos de Programação. Linguagem C++ aula II - Variáveis e constantes. Prof.: Bruno Gomes

Algoritmos. Algoritmos. Linguagem de programação. Conceitos. Conceitos. Conceitos. Sintaxe do comando para incluir bibliotecas no programa:

INF1007: Programação 2. 0 Revisão. 06/08/2015 (c) Dept. de Informática - PUC-Rio 1

Linguagens de Programação I

Capítulo 6: Arquivos

INF1337 LINGUAGEM DE PROGRAMAÇÃO ORIENTADA A OBJETOS

5. Vetores e alocação dinâmica

Arquivos em C Parte 2

Transcrição:

Por que alunos de engenharia são obrigados a fazer AEDS2? Algoritmos e Estruturas de Gisele L. Pappa, Clodoveu Davis e Raquel (glpappa@dcc.ufmg.br) 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? 1

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 Parte 2 Prova 2 06/10 TP2 hash, árvores binárias, árvores digitais Parte 1 Prova 1 13/09 TP1 Parte 3 Prova 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 2

Tópicos Programação em C recomendações e boas práticas Clodoveu Davis Gisele L. Pappa Indentação Comentários Modularização Compilação e Debug Entrada e saída Vetores e 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 3

Indentação Comentários Allman 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 Em função (simples) Comentários Comentários Em funções (arquivo.h) 4

Comentários Comentários Em variáveis Em structs No fim de um bloco de programa No código Modularização 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 5

Modularização Modularização transformação em biblioteca timer.lib Copiar timer.h para o diretório includes do compilador Atenção: incluir timer.h e timer.c no projeto 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 : 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 6

Parênteses e espaçamento Usar espaços antes de parênteses, depois de vírgulas, ao redor de operadores binários if (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 outros if (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 Vide http://wiki.codeblocks.org/index.php?title=debugging_with_code::blocks Documentação do CodeBlocks http://wiki.codeblocks.org/index.php?title=main_page 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 ENTRADA E SAÍDA 7

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 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ído scanf( %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 8

Entrada Observe que scanfinterrompe 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 arquivo FILE *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 9

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 Exemplo I/O para arquivos Exercício (POSCOMP 2009) #include<stdio.h> #include<string.h> int main (void) O que será impresso quando o programa for executado? 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; I/O para arquivos Exemplo (variação) VETORES E STRINGS 10

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 vetor float 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 EXCEDIDO y = 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) 11

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 constantes aparecem no código entre aspas printf( %s, Bom dia! ); O delimitador \0 está incluído: Não é possível fazer atribuições diretas para strings Usar a função strcpy ou a função strncpy Na inicialização, pode-se usar o mesmo recurso disponível para vetores char nome[] = A, n, a, \0 ; Ou char nome[] = Ana ; Como o nome do string representa o endereço onde começa o string, é possível manipulá-lo diretamente Cuidado! Exemplo char nome[] = Alexandre ; printf( %s\n, nome + 3); // imprime xandre 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 12

strncat, strncmp, strncpy: idem aos anteriores, mas especifica o número de caracteres que serão considerados strtok: extrai tokens, substrings delimitados Exemplo long 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); Vetores de strings podem ser criados Exemplo char DiaSemana[7][14] = Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sabado ; printf( %s\n, DiaSemana[3]); 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 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) 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 13

Alocação Dinâmica Apontadores Notação em C 0x016 a 0x020 b Memória Estática 10 0x234 a é um int b é um apontador para um int 10 Heap 0x214 0x218 0x222 0x226 0x230 0x234 0x238 0x242 0x246 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; Endereço da Variável Endereço do primeiro byte. Exemplo 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: 2293612 2293611 2293552 2293544 P 8 bytes P 8 bytes 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? Memória Estática Heap Alocação Dinâmica Erros Comuns int *a, b; b = 10; a = (int *) malloc(sizeof(int)); *a = 20; a = &b; *a = 30; // qual o valor de b? Memória Estática b 10 30 a X Memória não foi desalocada. O espaço continua ocupado 20 Heap 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 Algoritmos e Estrutura Dados de II desalocá-la 14

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 pguarda o endereço (aponta) da primeira posição do vetor. 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] 6 4 0 1 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 ) p 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; void free_matrix(int **matrix, int rows) int i; for(i=0; i<rows; i++) free(matrix[i]); free(matrix); Matrizes Realloc void *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; Exercício: O que vai ser impresso? double a; double *p, *q; 3.14 2.718 5.0 20.0 5.0? 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]); 110 10 0 10 20 30 40-5 6 7 8 9 15

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; 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 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); 1 1 int main() int a=0, b=0; SomaUm(a, &b); printf("programa principal: %d %d\n", a, b); 0 1 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() Error! Access Violation! int *a; aloca(a, 10); a[1] = 40; void aloca(int **x, int n) *x=(int *)malloc(n*sizeof(int)); *x[0] = 20; int main() OK int *a; aloca(&a, 10); a[1] = 40; 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 a inteiro 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. 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 modificado Não é necessário passar por referência pois todo vetor já é um apontador 16

typedef struct int a; char *b; TRegistro; Respostas (2) 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 para o registro e para o campo b. *(reg->b) representa o conteúdo da 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 main int 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 17