Estrutura de Dados para
Tecnologia
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
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
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
Tipos Compostos
Referenciando:
v_data.dia = 31; v_data.ano = n;
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:
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;
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
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
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:
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;
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
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
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
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)++; }
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
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); }
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;
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;
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:
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()
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
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);
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.
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);
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 : ");
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)); …
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() {
…
Alocação Dinâmica de Memória
Registro (
struct):
p.nome
Registro com ponteiro:
(*p).nome ou
Alocação Dinâmica de Memória
Função
free():
Sintaxe:
free(<ponteiro>)
Exemplo:
int *p;p = (int *) malloc(1);
free(p);
p = NULL;
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.
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).
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
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;