• Nenhum resultado encontrado

Preferível sempre que não soubermos quanta memória um programa utilizará

N/A
N/A
Protected

Academic year: 2021

Share "Preferível sempre que não soubermos quanta memória um programa utilizará"

Copied!
37
0
0

Texto

(1)
(2)
(3)

 Preferível sempre que não soubermos quanta

memória um programa utilizará

Alocação estática é fixa

▪ Definida durante a compilação

Alocação dinâmica permite utilizar a quantidade

necessária de memória sem desperdícios

(4)

 Memória é dividida em duas áreas

Stack: Utilizada para alocação estática

Heap: Utilizada para alocação dinâmica

Heap Memória Livre Programa Dados / texto Stack

(5)

 Alocar um novo bloco de memória

malloc(), calloc()

 Redimensionar um bloco já alocado

realloc()

 Liberar um bloco alocado

(6)

 malloc aloca um bloco de size bytes

 O conteúdo do bloco alocado é indeterminado  Retorna um ponteiro para void

 O programador decide como usar o bloco alocado

 Retorna NULL em caso de erro

int *primos = malloc(7 * sizeof(int)); if(!primos) { perror(NULL); exit(1); } char *buffer = malloc(64);

if(!buffer) { perror(NULL); exit(1); } double *fracoes = malloc(64);

if(!fracoes) { perror(NULL); exit(1); } memset(fracoes, 0, 8*sizeof(double)); int *primos = malloc(7 * sizeof(int)); if(!primos) { perror(NULL); exit(1); } char *buffer = malloc(64);

if(!buffer) { perror(NULL); exit(1); }

double *fracoes = malloc(8*sizeof(double)); if(!fracoes) { perror(NULL); exit(1); }

(7)

 calloc aloca um bloco com espaço para

count objetos de tamanho size bytes

 O bloco alocado é inicializado com zero

int *primos = calloc(7, sizeof(int)); if(!primos) { perror(NULL); exit(1); } char *buffer = calloc(64, sizeof(char)); if(!buffer) { perror(NULL); exit(1); }

double *fracoes = calloc(8, sizeof(double)); if(!fracoes) { perror(NULL); exit(1); }

(8)

 Redimensiona o bloco de memória apontado

por ptr para size bytes

Mantém o conteúdo do bloco apontado por ptr

(limitado pelo tamanho do novo bloco)

O local do novo bloco de memória pode mudar

▪ Mesmo se o novo bloco for menor que o anterior!

int *primos = calloc(7, sizeof(int)); if(!primos) { perror(NULL); exit(1); }

realloc(primos, 5*sizeof(int)); // BUG primos = realloc(primos, 5*sizeof(int)); // OK if(!primos) { perror(NULL); exit(1); }

(9)

 Alocação estática: memória liberada pelo

compilador

 Alocação dinâmica: memória liberada pelo

programador

Não liberar memória pode causar lentidão no

(10)

 Libera o bloco de memória apontado por ptr

Chamar free mais de uma vez pra um mesmo

bloco de memória é um bug

free só pode ser chamada em ponteiros

retornados por malloc, calloc e realloc.

char * montar_string(struct endereco e) { char *string = malloc(128);

if(!string) { perror(NULL); exit(1); } // montar string ...

return string; }

(11)
(12)

dyn_alloc

(13)
(14)

 Rotinas de entrada e saída não fazem parte

da linguagem

 Disponíveis em bibliotecas que acompanham

os compiladores

 Padronizadas

(15)

 formato específica como os valores devem

ser impressos na saída.

printf(“X = %d”, x);

printf(“Area: %f\n”, PI*r*r); printf(“Nome: %s”, aluno.nome);

 Existem vários caracteres de controle

 Retorna o número de conversões impressas

(16)

conversão c char d int u unsigned int x int, hexadecimal f float e float, científico g float, e ou f p ponteiro s string % sinal percentual %[opções][largura mínima][.precisão][tamanho]conversão

printf(“valor do float na posição %p = %f\n”, ptr, *ptr);

tamanho hh char h short l long ll long long L long double z size_t t ptrdiff_t j intmax_t

printf(“valor do double na posição %p = %lf\n”, ptr, *ptr);

tamanho

0 zeros à esquerda # alternativa

- alinhar à esquerda + mostrar sinal positivo

espaço para sinal positivo agrupar milhares

I digitos alternativos

(17)

 Caracteres especiais e reposicionamento do

cursor

printf(“barra invertida \\\n”); printf(“aspas duplas \”\n”);

(18)

 scanf é o inverso do printf:

lê dados do terminal

Mesmos códigos de conversão  Mesmas sequências de escape

 Passar um ponteiro para a variável que você

quer inicializar

int nlados = 0; float lado = 0;

scanf(“%f %d\n”, &lado, &nlados); perimetro = lado * nlados;

(19)

 Observe que scanf interrompe a leitura de

um string (%s) quando encontra um branco

 Especificadores de tamanho e filtro  %[aeiou]s lê apenas vogais

Para na primeira consoante, número, espaço, pontuação, etc

%[0123456789]s lê apenas números %60s lê apenas 60 caracteres

%60[^0123456789]s lê até 60 caracteres parando

quando encontrar um número

char buffer[80];

(20)

 getchar lê um único caractere do terminal  putchar(int c) imprime o caractere

(21)

 Mesma coisa, só precisamos passar o

manipulador do arquivo como parâmetro

FILE *entrada; FILE *saida; ... fscanf(entrada, “%79s”, buffer); char c = fgetc(entrada); fputc(c, saida); fprintf(saida, “X = %d”, x);

(22)

FILE * fopen(char *nome, char *modo)

Abre o arquivo com o dado nome modo pode ser:

▪ “r” para leitura, “w” para escrita, “rw” para leitura e escrita

▪ Se o arquivo já existir, podemos usar “a” para adicionar ao arquivo

 Sempre teste se o retorno é nulo, pois podem ocorrer erros

▪ Arquivo ou caminho não existente, permissões insuficientes, etc.

int fclose(FILE *arquivo)

Fecha o arquivo apontado por arquivo

FILE *arquivo = fopen(“C:\Users\Cunha\Desktop\teste.txt”, “w”); if(!arquivo) { perror(NULL); exit(EXIT_FAILURE); }

fprintf(arquivo, “hello arquivo!\n”); fclose(arquivo);

(23)

printf e fprintf são idênticas, só operam sobre manipuladores de arquivos diferentes

printf sempre imprime na saída padrão (terminal)

fprintf recebe o arquivo onde imprimir como parâmetro

O manipulador do arquivo correspondente à saída padrão é o

stdout, e o manipulador da entrada padrão é o stdin

(24)

 Cuidado ao terminar de ler um arquivo

Use int feof(FILE *arquivo)para testar

se já leu o arquivo até o fim

feof retorna falso se o arquivo ainda não tiver

terminado

feof só retorna verdadeiro depois que você tentar ler

(25)

 Saber a posição atual do arquivo

long ftell(FILE *arquivo)

 Mudar para uma dada posição no arquivo

int fseek(FILE *arquivo,

int base, int distancia) Onde base pode ser:

SEEK_SET, o começo do arquivo

SEEK_CUR, a posição atual no arquivo

(26)

 Podemos ler uma linha de texto de um arquivo

usando fgets

char buf[BUFSIZE];

fgets(buf, BUFSIZE, arquivo);

 Depois processamos a linha usando sscanf

sscanf(buf, “%d %d %lf\n”, &int1, &int

 Seguro:

 Não tem como ler uma linha maior do que BUFSIZE

Retorna NULL se aconteceu algum erro

(27)

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

argv é um arranjo de strings, um parâmetro em cada

índice do arranjo

argc é o número de parâmetros em argv argv[0] é sempre o nome do executável

▪ Logo, argc >= 1

 Para processamento avançado de parâmetros,

use getopt()

Parâmetros em qualquer ordem, opcionais, etc.

ls -al --color=auto --sort=x

(28)
(29)

 Pequeno esforço, grande impacto  Código mais legível

Ajuda o entendimento das idéias

 Útil quando você for ler o código 6 meses depois

 Útil para outras pessoas

 Código com menos erros

Economizar tempo e ter menos dor de cabeça

 Em AEDS2: ajuda entendimento das idéias e

(30)

 Realça estrutura lógica do código

 Em geral, indenta-se com tabulação (tab)

 Em geral um tab corresponde a 8 espaços, mas é configurável na maioria dos editores

(31)

static char * concat (char *s1, char *s2) { while (x == y) { something (); somethingelse (); } finalthing (); }

static char * concat (char *s1, char *s2) { while (x == y) { something (); somethingelse (); } finalthing (); }

static char * concat(char *s1, char *s2) { while(x == y) { something(); something_else(); } final_thing(); } static char *

concat(char *s1, char *s2) { while(x == y) { something(); something_else(); } final_thing(); } static char *

concat(char *s1, char *s2) { while(x == y) { something(); something_else(); } final_thing(); } GNU K&R Allman

(32)

 Facilitam a compreensão do código, mais

importantes para código complexo

 Código bem escrito não depende muito de

comentários

Comentário errado é pior do que nenhum

comentário

(33)

 No início de um módulo

 Descrever variáveis globais ou importantes  Em funções para explicar os parâmetros, o

tipo de retorno, e o que a função faz

Não explicar como a função faz a tarefa, código

deve ser claro o bastante

 Indicar invariantes de loops

 Não comentar o óbvio DUH:i += 1; // incrementa i.

OK:

(34)

 Escolher bons identificadores ajudam a

compreensão do código

void ordena(int *vetor);

void processa(int *vetor);

double media(int *vetor);

Mesma coisa para variáveis

▪ Variáveis auxiliares podem receber nomes simples, mas sem exagerar

Indices: i, j, k

Variáveis tipo ponto flutuante: x, y, z

(35)

 Se houver, preferir o estilo que já estiver em uso  Underscore:

int num_clientes;

struct list *lista_alunos;

 CamelCase:

int numClientes;

(36)

 Não usar “números mágicos” no código  Valores podem precisar ser modificados  “Números mágicos” não têm significado

Usar #define para dar nome a constantes

Nomes em maiúsculas

#define PI 3.14159

#define TAMANHO_MAX_LINHA 256 char * le_linha(FILE *entrada) {

char *linha = malloc(TAMANHO_MAX_LINHA); ...

return linha; }

(37)

 Particionamento de um programa

 Um módulo geralmente é um par de arquivos

modulo.c contém a implementação das funções modulo.h contém a declaração das funções e

tipos de dados; é importado por outros módulos

 Outros programadores só precisam saber o

que o módulo faz, não como ele funciona

 Procurar identificar módulos independentes

Referências

Documentos relacionados

Benetton (1999) apresenta o caráter de funcionalidade na Terapia Ocupacional como tendo sido assumido por muitos autores, pelos precurssores da profissão (Meyer, Simon e Schneider)

Para o menino Momik, a constituição de sua própria memória, no que diz respeito ao trauma não vivido do holocausto e a constituição de si mesmo como judeu, se dará necessariamente

60 Fátima Cristina da Silva Rodrigues 46 RJ CARIOCA (ANA KATIA). 61 Gisele Bahia Pereira Barbosa 34 RJ CARIOCA

A questão não veio de Pedro, porque Pedro sabia que Jesus o

A exposição ao subprime e o agudizar da crise de liquidez e de crédito reflectiu-se de forma extrema em muitas instituições financeiras que, ou foram nacionalizadas

Há amplo espaço para preocupação quanto às dificuldades para aprovação de reformas necessárias à contenção do déficit público, peça crucial para o sucesso

Ó Deus, neste momento em que a Vossa obra de criação continua a avançar sempre tão firmemente em Vossa grande harmonia, permiti-nos realizar o Culto Mensal

O selo é oferecido pela ABIC (Associação Brasileira da Indústria do Café) às torrefadoras que são aprovadas pela avaliação de qualidade.. A auditoria foi realizada