Sei sulla pagina 1di 9

18/05/2011

Lógica e Estrutura de Dados Fundamentais

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

Ponteiros são usados em situações em que é necessário conhecer


o endereço onde está armazenada a variável e não o seu
conteúdo.

Um ponteiro é uma variável que contém um endereço de memória


e não o conteúdo da posição.

A figura abaixo mostra um mapa de um trecho de memória que


contém duas variáveis (num, res) inteiras de tipo longo (4 bytes
cada uma).

Professor: Eduardo O. Teles

1
18/05/2011

Lógica e Estrutura de Dados Fundamentais

DECLARAÇÃO

Exemplo:

int *res; /* ponteiro para uma variável inteira */


float *div; /* ponteiro para uma variável de ponto flutuante */

OPERADORES

O operador & devolve o endereço de memória do seu operando.


pint = &soma; /* o endereco de soma e carregado em pint */

O operador * é o complemento de &. O operador * devolve o valor


da variável localizada no endereço que o segue.

Por exemplo, o comando num = *res; 3

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

Por exemplo, no trecho de programa abaixo o endereço do


terceiro elemento do vetor v é carregado em p1 e o endereço da
variável i é carregado em p2.
Além disso, no final o endereço apontado por p1 é carregado em
p2. Os comandos printf imprimem os valores apontados pelos
ponteiros respectivos.
void main(void)
{
int vetor[ ] = { 10, 20, 30, 40, 50 };
int *p1, *p2;
int i = 100;
p1 = &vetor[2];
printf("%d\n", *p1);
p2 = &i;
printf("%d\n", *p2);
p2 = p1;
printf("%d\n", *p2); 4
}
Professor: Eduardo O. Teles

2
18/05/2011

Lógica e Estrutura de Dados Fundamentais

INCREMENTANDO E DECREMENTANDO PONTEIROS

O exemplo abaixo mostra que operações de incremento e


decremento podem ser aplicadas em operandos.
O primeiro printf imprime 30 o segundo 40 e o terceiro 50.

void main(void)
{
int vetor[ ] = { 10, 20, 30, 40, 50 };
int *p1;
p1 = &vetor[2];
printf("%d\n", *p1);
p1++;
printf("%d\n", *p1);
p1 = p1 + 1;
printf("%d\n", *p1);
}
5

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

A diferença entre ponteiros fornece quantos elementos do tipo do


ponteiro existem entre os dois ponteiros. No exemplo abaixo é
impresso o valor 3.

void main(void)
{
float vetor[ ] = { 1.0, 2.0, 3.0, 4.0, 5.0 };
float *p1, *p2;
p1 = &vetor[2]; /* endereco do terceiro elemento */
p2 = &vetor; /* endereco do primeiro elemento */
printf("Diferenca entre ponteiros %d\n", p1-p2);
}

Não é possível multiplicar ou dividir ponteiros, e não se pode


adicionar ou subtrair o tipo float ou o tipo double a ponteiros.
6

Professor: Eduardo O. Teles

3
18/05/2011

Lógica e Estrutura de Dados Fundamentais

COMPARAÇÃO DE PONTEIROS

É possível comparar ponteiros em uma expressão relacional. Só é


possível comparar ponteiros de mesmo tipo. O trecho de programa
abaixo ilustra um exemplo deste tipo de operações.

char *c, *v;


scanf("%c %c", c, v);
if (c == v)
printf("As variáveis estao na mesma posicao.\n");
Else
printf("As variaveis nao estao na mesma posicao.\n");

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

v[i] == *(v+i)
&v[i] == v+i

int main(void)
{
float v[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
int i;
for (i=0; i<9; i++)
printf("%.1f ", v[i]);
printf("\n");
for (i=0; i<9; i++)
printf("%.1f ", *(v+i));
printf("\n");
system("pause");
}
8

Professor: Eduardo O. Teles

4
18/05/2011

Lógica e Estrutura de Dados Fundamentais

Existe uma diferença fundamental entre declarar um conjunto de


dados como um vetor ou através de um ponteiro.

Na declaração de vetor a compilador automaticamente reserva um


bloco de memória para que o vetor seja armazenado.

Quando apenas um ponteiro é declarado a única coisa que o


compilador faz é alocar um ponteiro para apontar para a memória,
sem que espaço seja reservado.

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

PERCORRER VETOR

int main(void)*
{

float v[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
int i;
float *p;

for (i=0; i<9; i++) printf("%.1f ", v[i]);


printf("\n");
for (i=0; i<9; i++) printf("%.1f ", *(v+i));
printf("\n");
for (i=0, p=v; i<9; i++, p++) printf("%.1f ", *p);
system("pause");
10
}
Professor: Eduardo O. Teles

5
18/05/2011

Lógica e Estrutura de Dados Fundamentais


int main(void)
{
float *v; A função calloc() aloca um bloco
int i, tam; de tamanho (numitens*tamanho) e
armazena zeros em todas as
printf("Qual o tamanho do vetor? "); posições.
scanf("%d", &tam);
v = calloc(tam, sizeof(float));
if (v)
{
for (i=0; i<tam; i++){
printf("Elemento %d ?", i);
scanf("%f", v+i);
printf("Li valor %f \n", *(v+i));
}
free(v);
}
else
printf("Nao consegui alocar memoria.");
printf("\n");
system("pause"); 11
}
Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

STRUCT

Um registro (= record) é uma coleção de várias variáveis,


possivelmente de tipos diferentes. Na linguagem C, registros são
conhecidos como structs (abreviatura de structures).

O exemplo abaixo declara um registro x com três campos (ou


membros) inteiros:

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

12

Professor: Eduardo O. Teles

6
18/05/2011

Lógica e Estrutura de Dados Fundamentais

É uma boa ideia dar um nome ao tipo de registro. No nosso


exemplo, dma parece um nome apropriado:

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

struct dma x; /* um registro x do tipo dma */


struct dma y; /* um registro y do tipo dma */

É fácil atribuir valores aos campos de um registro:


x.dia = 31;
x.mes = 8;
x.ano = 1998;;
13

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

struct dma *p; /* p é um ponteiro para registros dma */


struct dma x;
p = &x; /* agora p aponta para x */
(*p).dia = 31; /* mesmo efeito que x.dia = 31 */

A expressão p->mes é uma abreviatura muito útil para a


expressão (*p).mes :

p->mes = 8; /* mesmo efeito que (*p).mes = 8 */


p->ano = 1998;

Registros podem ser tratados como um novo tipo-de-dados. Por


exemplo:

typedef struct dma data;

data x; data *p; p = &x; 14

Professor: Eduardo O. Teles

7
18/05/2011

Lógica e Estrutura de Dados Fundamentais

Exemplo:
Declaração de um Struct endereço que guarda os elementos
nome, rua, cidade, estado e cep:

struct T_endereco{
char nome[30];
char rua[30];
char cidade[20];
char estado[2];
long int cep;
{;

15

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

#include <stdio.h>
#include <string.h>

struct endereco {
char rua[40];
int num;
int apt;
char cidade[20];
char estado[2];
char cep[10];
{;

int main()
{
struct endereco e1; // declaração de variáveis do
struct endereco e2; // tipo "endereco" compilador
// aloca memoria para todos os campos
16

Professor: Eduardo O. Teles

8
18/05/2011

Lógica e Estrutura de Dados Fundamentais

#include <iostream.h>

struct endereco{
char nome[30];
char rua[40];
char cidade[20];
char estado[3];
long int cep;
{;

main() {
struct endereco info_end[100];
// Imprime todos os nomes do vetor
for(int i = 0; i < 100; i++)
Printf(“Endereço: %c “, info_end[i].nome);
...
17

Professor: Eduardo O. Teles

Lógica e Estrutura de Dados Fundamentais

Evoluindo...

Defina um registro empregado para guardar os dados (nome,


sobrenome, data de nascimento, RG, data de admissão, salário) de
um empregado de sua empresa. Defina um vetor de empregados
para armazenar todos os empregados de sua empresa.

Criar uma estrutura chamada superior, que armazena o nome e


idade de um aluno do curso superior. Na função main: crie uma
variável que é uma estrutura superior; leia nome e idade do aluno e
armazene na variável que você definiu; exiba na tela o nome e a
idade do aluno.

Após ter concluído o exercício 2, crie uma variável vetor da


estrutura superior. O programa deve obter o nome e a idade de 5
alunos. Depois, exiba os dados digitados.

18

Professor: Eduardo O. Teles