Estrutura de Dados para Tecnologia

34 

Full text

(1)

Estrutura de Dados para

Tecnologia

(2)

Tipos de Dados (em C)

Tipo Bits Intervalo

Início Fim

(signed) char 8 -128 127

unsigned char 8 0 255

int (proc. de 32 bits) 16 -32768 32767

int (proc. De 64 bits) 32 -2147483648 2147483647

unsigned int (32 bits) 16 0 65535

(3)

Tipos de Dados (em C)

Tipo Bits Intervalo

Início Fim

(signed) short int 16 -32768 32767

unsigned short int 16 0 65535

(signed) long int 32 -2147483648 2147483647

unsigned long int 32 0 4294967295

float 32 3,4x10-38 3,4x1038

double 64 1,7x10-308 1,7x10308

(4)

Tipos Compostos

Heterogêneos: permitem criar um tipo formado por

componentes simples.

Registro ou Estrutura:

struct { int dia; int mes; int ano; } v_data;

Ou

(5)

Tipos Compostos

Referenciando:

 v_data.dia = 31;  v_data.ano = n;

(6)

Tipos Abstratos

Pode-se definir tipos abstratos baseados em tipos

simples ou compostos.

Para isso, devemos usar o comando

typedef

Exemplos:

 typedef int numero;  typedef char tecla;

 Definindo variáveis:

(7)

Tipos Abstratos

Typedef para Registros:

struct sdata { int dia; int mes; int ano; };

typedef struct sdata data; data v_data;

Ou

typedef struct sdata { int dia;

(8)

Ponteiros ou Apontadores

Ponteiros ou apontadores são variáveis cujo

conteúdo é um endereço de memória

Variáveis são posições na memória que podem conter

um determinado valor, dependendo do seu tipo (int,

char, float, double, etc.)

Assim, uma variável do tipo ponteiro contém valores

(9)

Declarando Ponteiros

Uma variável do tipo ponteiro “aponta” para uma

variável de um determinado tipo conhecido, ou seja,

contém um endereço de memória da variável.

Assim, é necessário na declaração de um ponteiro

especificar para qual tipo de variável ele irá apontar.

Utilizamos o operador “*” para indicar que uma

variável é do tipo “ponteiro”:

int *pi // variável “pi” é ponteiro para inteiro float *pc // variável “pc” é ponteiro para float char *xy // variável “xy” é ponteiro para caracter

(10)

Declarando Ponteiros

Da mesma forma, utilizamos o operador “&” com o

significado de “endereço de”:

pi = &a // “pi” contém o endereço da variável “a” pc = &b // “pc” contém o endereço da variável “b”

O operador “*” antes da variável significa “o valor

de”

São equivalentes os seguintes comandos:

(11)

Utilizando Ponteiros

Quanto trabalhamos com o endereço de uma

variável, ao manipularmos o valor do ponteiro,

estamos de fato manipulando o valor desta

variável.

Exemplo:

int v; // variável “v” é inteiro

int *p; // variável “p” é ponteiro para inteiro

v = 10; p = &v;

*p = *p + 10;

(12)

Utilizando Ponteiros

Há um formato específico na função “printf()” para

exibir o conteúdo de um ponteiro (endereço): %p

Exemplo:

int *p; // variável “pi” é ponteiro para inteiro

*p = 10;

printf(“%p”,p);

Produzirá algo como 00404010, indicando que:

No segmento de memória 0040, os segmentos

(13)

Utilizando Ponteiros

Ponteiros também são variáveis e portanto ocupam

posições na memória.

Logo, podemos utilizar ponteiros de ponteiros !

Exemplo:

int v; // variável “v” é inteiro

int *p; // variável “p” é ponteiro inteiro

int **pp; // variável “pp” é ponteiro para ponteiro para inteiro

(14)

Utilizando Ponteiros

Logo, também podemos realizar operações sobre

endereços de memória:

Exemplo:

int v; // variável “v” é inteiro

int *p; // variável “p” é ponteiro para inteiro

int **pp; // variável “pp” é ponteiro para ponteiro para inteiro

(15)

Utilizando Ponteiros

 Com ponteiros, podemos implementar a passagem de valores

por referência, pois os parâmetros que passamos para os procedimentos são os endereços das variáveis (através do operador “&”), permitindo assim que seus conteúdos sejam modificados (através do operador “*”):

int v; // variável “v” é inteiro int altera (int *p) {

(*p)++; }

(16)

Utilizando Ponteiros

 Exemplo de uso de ponteiro:

void main () {

int n; // variável “n” é inteiro

int *p; // variável p é endereço para inteiro scanf(“%d”,&n); // lê o conteúdo da variável “n”

p = &n; // faz “p” armazenar o endereço de “n” printf(“%d”,*p); // Exibe o conteúdo do valor armazenado

(17)

Utilizando Ponteiros

 Exemplo de uso de ponteiro:

void main () {

int n; // variável “n” é inteiro

int *p; // variável p é endereço para inteiro scanf(“%d”,&n); // lê o conteúdo da variável “n”

p = &n; // faz “p” armazenar o endereço de “n” (*p)++;

printf(“%d”,n); }

(18)

Utilizando Ponteiros

 Tentem executar o seguinte programa:

void main () {

int n; // variável “n” é inteiro

int *p; // variável p é endereço para inteiro scanf(“%d”,&n); // lê o conteúdo da variável “n” *p = n;

(19)

Utilizando Ponteiros

 Passagem de variáveis do tipo ponteiro por referência:

#include<stdio.h>

void copia (int **a, int *b) {

*a = b; }

int main () {

int n; int *p;

(20)

Alocação Dinâmica de Memória

 Alocação dinâmica é o processo que aloca memória em tempo

de execução.

 Ela é utilizada quando não se sabe ao certo quanto de memória

será necessário para o armazenamento das informações,

podendo ser determinadas em tempo de execução, conforme a necessidade do programa.

 Com isso, evita-se o desperdício de memória.

 Geralmente é utilizada quando se armazena uma certa

quantidade de valores, onde não se pode prever o quanto de memória será necessário, pois:

(21)

Alocação Dinâmica de Memória

 Aplicações que utilizam alocação dinâmica de memória:

 Strings (cadeias de caracteres)  Pilhas e Filas

 Árvores  Grafos  Etc.

 Para manipular dados dinamicamente em memória, temos as

seguintes funções em C, todas disponíveis na biblioteca stdlib.h:

 malloc()

 calloc()

 realloc()

(22)

Alocação Dinâmica de Memória

Função

malloc():

Sintaxe:

(void *) malloc(<tamanho>)

Exemplo:

int *p;

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

 Irá alocar uma posição de memória para “p”, de forma

(23)

Utilizando Ponteiros

 Tentem executar o seguinte programa:

void main () {

int n; // variável “v” é inteiro

int *p; // variável p é endereço para inteiro scanf(“%d”,&n); // lê o conteúdo da variável “n”

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

*p = n;

printf(“%d”,*p);

free(p);

(24)

Alocação Dinâmica de Memória

Função

malloc():

Exemplo muito mais interessante:

int *p;

int a;

scanf(“%d”,&a)

p = (int *) malloc(a * sizeof(int))

 Irá alocar, para “p” uma quantidade “a” de números

inteiros.

 Com isso, “p” terá “a” valores, e não apenas um.

(25)

Alocação Dinâmica de Memória

Função

malloc():

Programa:

void main() { int a,i; int *p;

scanf("%d",&a);

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

for (i=0; i < a; i++) scanf("%d",&p[i]); printf("\nValores digitados:\n");

for (i=0; i < a; i++) printf("%d ",p[i]); free(p);

(26)

Alocação Dinâmica de Memória

 Função malloc():

 Outro exemplo:

main() { int a,i; char *p;

printf("Quantos caracteres serão digitados ? "); scanf("%d",&a);

p = (char *) malloc((a+1) * sizeof(char));

printf("Digite a palavra : ");

(27)

Alocação Dinâmica de Memória

 Função malloc():

 Com estruturas heterogêneas (registros) e uma posição de

memória:

struct Registro {

unsigned long int matricula; char nome[40]; char sexo;

char datanasc[11]; };

Registro* p;

void main() {

p = (Registro *) malloc(sizeof(Registro)); …

(28)

Alocação Dinâmica de Memória

 Função malloc():

 Com estruturas heterogêneas (registros) e várias posições de

memória:

struct Registro {

unsigned long int matricula; char nome[40]; char sexo;

char datanasc[11]; };

Registro* p;

void main() {

(29)

Alocação Dinâmica de Memória

Registro (

struct):

 p.nome

Registro com ponteiro:

 (*p).nome ou

(30)

Alocação Dinâmica de Memória

Função

free():

Sintaxe:

free(<ponteiro>)

Exemplo:

int *p;

p = (int *) malloc(1);

free(p);

p = NULL;

(31)

Alocação Dinâmica de Memória

Função

calloc():

Sintaxe:

(void *) calloc(<numero de posições>,<tamanho>)

Exemplo:

int *p;

p = (int *) calloc(1, sizeof(int))

 Irá alocar uma posição de memória para “p”, de forma

que nesta posição poderá ser armazenado um número inteiro (ou 4 bytes), sinalizada pelo segundo parâmetro.

(32)

Alocação Dinâmica de Memória

 Função realloc():

 Sintaxe:

(void *) realloc(<ponteiro>,<tamanho>)

 Exemplo: int *p;

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

p = (int *) realloc(p,6*sizeof(int));

 malloc irá alocar uma posição de memória para “p”, de forma

que nesta posição poderá ser armazenado um número inteiro (ou 4 bytes).

(33)

Alocação Dinâmica de Memória

 Função realloc():

x = (int *) malloc(4 * sizeof(int))

for(i=0;i<4;i++) x[i]=i;

x = (int *) realloc(x,6 * sizeof(int))

 A função realloc faz o bloco de memória alocado para a variável

(34)

Alocação Dinâmica de Memória

 Função realloc():

 Exemplo:

void main() { int a,b,c,i; int *p;

printf("\nQuantos numeros serão digitados ? "); scanf("%d",&a); p = (int *) malloc(a * sizeof(int));

printf("Digite os números : ");

for (i=0; i < a; i++) scanf("%d",&p[i]);

printf("\nQuantos numeros a mais serao digitados ? "); scanf("%d",&b); c = a + b;

Figure

Updating...

References

Updating...

Download now (34 pages)