flavio m. strelow linguagem c udesc - sbs departamento de sistemas de informação lpg - i:...
Post on 17-Apr-2015
127 Views
Preview:
TRANSCRIPT
Flavio M. StrelowLinguagem C
UDESC - SBSUDESC - SBS
Departamento de Sistemas de InformaçãoDepartamento de Sistemas de Informação
LPG - I: Ponteiros e LPG - I: Ponteiros e Vetores/MatrizesVetores/Matrizes
Prof. Flavio Marcello StrelowProf. Flavio Marcello Strelowflavio@sbs.udesc.brflavio@sbs.udesc.br
Flavio M. StrelowLinguagem C
PonteirosPonteiros
• ponteiro é uma variável que contém o endereço de um dados, normalmente uma outra variável. Daí o nome, pois ele aponta para outra variável.
• Ex: quando você anota o endereço de sua casa, você cria um ponteiro para ela.
• declaração: "*" indica que a variável é um ponteiro• sintaxe: tipo_dado *nome_ponteiro;• Ex:
int x; /*variável declarada como inteiroint *pi; /* compilador sabe que pi é ponteiro */
/* pi é um ponteiro para inteiro */
Flavio M. StrelowLinguagem C
PonteirosPonteiros
• espaço ocupado pelas variáveis
1 byte
(int *)
1 byte
(float *)
(char *)
2 bytes
1 byte
4 bytes
Flavio M. StrelowLinguagem C
PonteirosPonteiros
• o operador "&" quando aplicado sobre uma variável retorna o seu endereço
• Ex:
#include <stdio.h>
void main (){
int x = 10, *pi;
pi = &x;
printf("&x: %p pi: %p", &x, pi);
}
R: => &x: 19BC pi: 19BC Obs.: Os valores apresentados são endereços de mémoria.
Flavio M. StrelowLinguagem C
PonteirosPonteiros
• funcionamento de um ponteiro na memória• Ex:void main () {
int var;int *ptr;var = 10;ptr = &var;
}
Flavio M. StrelowLinguagem C
PonteirosPonteiros
A Fig 1 dá uma noção gráfica do funcionamento de ponteiros. E está considerando que o endereçamento do sistema é dado por 2 bytes.
Assim ptr ocupará 2 bytes; var também 2 bytes, por ser uma variável int.
O número 4052 da posição de memória do primeiro byte de var é apenas ilustrativo e, na prática, dependerá do local da memória onde o programa foi carregado. Mas supomos que seja este. Portanto, após a execução de ptr = &var; o conteúdo de ptr será 4052, ou seja, o primeiro byte da variável apontada.
Com ptr apontando para var, podemos ler ou modificar o valor desta última de forma indireta através de ptr.
Flavio M. StrelowLinguagem C
PonteirosPonteiros
• o operador "*" quando aplicado sobre um ponteiro em uma expressão aritmética retorna o dado apontado
• Ex:
void main () { int *tmp_ptr; int x, y; x = 10; tmp_ptr = &x; // tmp_ptra ponta para x y = *tmp_ptr; // conteúdo tmp_ptr = 10;
portanto, y = 10.}
tmp_ptr
x
y
0xABA0
0xABA2
0xABA0
10
10
Flavio M. StrelowLinguagem C
PonteirosPonteiros
• Ex.2:void main () {
int x, *px;float y, *py;double largura, *altura;x=1;px = &x; /* px aponta para x */*px = 0; /* conteúdo de px = 0 (x=0) */x = *px + 1; /* x = conteúdo de px + 1 */
}
Flavio M. StrelowLinguagem C
PonteirosPonteiros
• ponteiros são variáveis tipadas: possuem tipos diferentes para guardar endereços diferentes. Então um ponteiro para um tipo de dado int possui representação diferente de um ponteiro para tipo de dado float.
(int *) ≠ (float *) ≠ (char *)• Ex: main() {
int *ip, x; float *fp, z; ip = &x; /* OK */ fp = &z; /* OK */ ip = &z; /* erro */ fp = &x; /* erro */ }
Flavio M. StrelowLinguagem C
Utilizando PonteirosUtilizando Ponteiros
• modificando valores de variáveis de forma indireta através de ponteiros.
Ex:#include <stdio.h>void main() {int x = 10;int *pi;pi = &x; /* pi aponta para endereço de x *pi == 10 */(*pi)++; /* conteúdo de pi + 1 *pi == 11 */printf("%d", x);
}R: ==> 11
ao alterar *pi estamos alterando o conteúdo de x
Flavio M. StrelowLinguagem C
Utilizando PonteirosUtilizando Ponteiros
Ex:#include <stdio.h>void main() {
int x = 10;int *pi, *pj;pi = &x; /* *pi = 10 */pj = pi; /* *pj = 10 */
(*pi)++; /* conteúdo de pi + 1 (*pi, *pj, x) = 11 */
(*pj)++; /* conteúdo de pj + 1 (*pi, *pj, x) = 12 */printf("%d", x); /* ==> 12 */
}
Flavio M. StrelowLinguagem C
Exercício 1Exercício 1
• Pratique a declaração e utilização de ponteiros. – defina e inicialize uma variável inteira– defina um ponteiro para inteiro– modifique o valor da variável através do ponteiro– verifique os novos valores da variável usando
printf
Flavio M. StrelowLinguagem C
Vetores e PonteirosVetores e Ponteiros
• ponteiros oferecem um eficiente e prático meio de acesso e manipulação dos elementos de uma array.
• EX.:void main () {
int ar[] = {10, 50, 20, 30}; int *ptr;ptr = &ar[0]; // ou
ptr = ar;
}
Quando for executado, ptr estará associado ao primeiro byte da array conforme Fig 2.
Flavio M. StrelowLinguagem C
Vetores e PonteirosVetores e Ponteiros
• em float m[10] m é uma constante que endereça o primeiro elemento do vetor
• portanto, não é possível mudar o valor de m
• Ex: void main ( ) {
float m[10], n[10];
float *pf;
m = n; //erro: m é constante!
pf = m; //ok }
m:
m[0] m[1] m[9]
4 BYTES
pf:
Flavio M. StrelowLinguagem C
Referenciando ElementosReferenciando Elementos
• pode-se referenciar os elementos do vetor através do seu nome e o índice entre os colchetes:
• Ex:#include <stdio.h>
void main () {
m[5] = 5.5;
if (m[5] == 5.5)
printf("Exito");
else
printf("Falha");
}
Flavio M. StrelowLinguagem C
Referenciando ElementosReferenciando Elementos
• Pode-se referenciar os elementos de um vetor através de ponteiros:
• Ex:#include <stdio.h>
void main () {
float m[] = { 1.0, 3.0, 5.75, 2.345 };
float *pf;
pf = &m[2];
printf("%f", *pf); /* ==> 5.75 */ }
Flavio M. StrelowLinguagem C
Referenciando ElementosReferenciando Elementos• Pode-se utilizar ponteiros e colchetes:• Ex.:
#include <stdio.h>void main () { float m[] = { 1.0, 3.0, 5.75, 2.345 };float *pf;pf = &m[2];printf("%f", pf[0]); /* ==> 5.75 */ }
• Note que o valor entre colchetes é o deslocamento a ser considerado a partir do endereço de referência: pf[n] => indica enésimo elemento a partir de pf
Flavio M. StrelowLinguagem C
Vetores - Aritmética de PonteirosVetores - Aritmética de Ponteiros
• É possível fazer operações aritméticas e relacionais entre ponteiros e inteiros
• Soma: ao somar-se um inteiro n a um ponteiro, endereçamos n elementos a mais (n positivo) ou a menos (n negativo)pf[2] equivale a *(pf+2)
*(pf + n) endereça n elementos a frente
*(pf - n) endereça n elementos atrás
pf++ endereça próximo elemento vetor
pf-- endereça elemento anterior vetor
Flavio M. StrelowLinguagem C
ExemploExemplo
#include <stdio.h>
void main () {
int arint[] = { 1,2,3,4,5,6,7 };
int size = 7; /* tamanho do vetor */
int i, *pi;
for (pi=arint, i=0; i < size; i++, pi++)
printf(" %d ", *pi);
} R: ==> 1 2 3 4 5 6 7
Flavio M. StrelowLinguagem C
Exemplo - VariaçãoExemplo - Variação
#include <stdio.h>void main () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7; /* tamanho do vetor */ int i, *pi;
for (pi=arint, i=0; i < size; i++)printf(" %d ", *pi++);
}
R: ==> 1 2 3 4 5 6 7
Flavio M. StrelowLinguagem C
Exemplo - VariaçãoExemplo - Variação
#include <stdio.h>void main () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7;/* tamanho do vetor */ int i, *pi;
pi = arint;printf(" %d ", *pi); pi += 2;printf(" %d ", *pi); pi += 2;printf(" %d ", *pi); pi += 2;printf(" %d ", *pi);
}R: ==> 1 3 5 7
Flavio M. StrelowLinguagem C
Operações Válidas Sobre PonteirosOperações Válidas Sobre Ponteiros
• É valido:– somar ou subtrair um inteiro a um ponteiro (pi ± int)– incrementar ou decrementar ponteiros (pi++, pi--)– subtrair ponteiros (produz um inteiro) (pf - pi)– comparar ponteiros ( >, >=, <, <=, == )
• Não é válido:– somar ponteiros (pi + pf) – multiplicar ou dividir ponteiros (pi*pf, pi/pf)– operar ponteiros com double ou float (pi ± 2.0)
Flavio M. StrelowLinguagem C
Exercício 2Exercício 2
• Escreva um programa que imprima um vetor de inteiros na ordem inversa endereçando os elementos com um ponteiro
Flavio M. StrelowLinguagem C
Cuidados...Cuidados...
• C não controla os limites dos vetores, o programador deve fazê-lo
• Ex: encontre o erro!!#include <stdio.h>void main () { int arint[] = { 1,2,3,4,5,6,7 }; int size = 7, i, *pi; for (pi=arint, i=0; i < size; i++, pi += 2)
printf(" %d ", *pi); }
Flavio M. StrelowLinguagem C
Cuidados...Cuidados...
void main ()
{
int arint[] = { 1,2,3,4,5,6,7 };
int size = 10;
int i;
for (pi=arint, i=0; i < size; i++)
printf(" %d ", arint[i]);
}
Flavio M. StrelowLinguagem C
Cuidados...Cuidados...
• Um ponteiro deve sempre apontar para um local válido antes de ser utilizado
• Ex: #include <stdio.h> void main () { int i=10, *pi; *pi = i; /*erro ! pi nao tem endereco valido*/
}
Flavio M. StrelowLinguagem C
Ponteiros GenéricosPonteiros Genéricos
• Um ponteiro genérico é um ponteiro que pode apontar para qualquer tipo de dado
• Define-se um ponteiro genérico utilizando-se o tipo void:
#include <stdio.h> void main (){ void *pv; nt x=10;float f=3.5;pv = &x; /* aqui pv aponta para um inteiro */pv = &f; /* aqui, para um float */
}
Flavio M. StrelowLinguagem C
Ponteiros GenéricosPonteiros Genéricos
• O tipo de dado apontado por um void pointer deve ser controlado pelo usuário
• Usando um type cast (conversão de tipo) o programa pode tratar adequadamente o ponteiro #include <stdio.h> void main (){ void *pv;pv = &x;
printf("Inteiro: %d\n", *(int *)pv); /*=> 10*/ pv = &f; printf("Real: %f\n", *(float *)pv); /*=> 3.5*/ }
type cast
Flavio M. StrelowLinguagem C
Ponteiros e StringsPonteiros e Strings
• strings são vetores de caracteres e podem ser acessados através de char *
EX.: void main () { char str[]="abcdef", *pc; for (pc = str; *pc != ‘\0’; pc++ )
putchar(*pc); }
R: ==> abcdef• o incremento de pc o posiciona sobre o próximo
caracter (byte a byte)
Flavio M. StrelowLinguagem C
Ponteiros e StringsPonteiros e Strings
• operações sobre strings com ponteiros• Ex.:
void StrCpy (char *destino, char *origem){// *origem==0 encerra while while (*origem) { *destino=*origem; origem++; destino++; }*destino='\0';} // na condição do while (*origem) e (*origem != ‘\0’) são equivalentes
a b c d e \0
a b
origem
destino
Flavio M. StrelowLinguagem C
Ponteiros e StringsPonteiros e Strings
• variação de strcpy:
void strcpy (char *destino, char *origem)
{
while ((*destino = *origem) != ‘\0’)
destino++, origem++;
}
*destino='\0';
Flavio M. StrelowLinguagem C
Vetores MultidimensionaisVetores Multidimensionais
• vetores podem ter diversas dimensões, cada uma identificada por um par de colchetes na declaração
• Ex.: char matriz[5][10];• declara uma matriz de 5 linhas e 10 colunas:
• na memória, entretanto, os caracteres são armazenados linearmente:
[0,0] [4,9][0,9] [1,9]
[0,0]
[4,9]
Flavio M. StrelowLinguagem C
Vetor de CaracteresVetor de Caracteres
• Percorrendo vetor com ponteiro:#include <stdio.h>#define L 5#define C 10void main () {char matriz[L][C];char *pc;int i;for (i=0, pc=matriz[0]; i < (L * C) ; i++, pc++)
*pc = 'P';
for (i=0, pc=matriz[0]; i < (L * C) ; i++, pc++) printf("%c", *pc);
}
Flavio M. StrelowLinguagem C
Vetor de CaracteresVetor de Caracteres
• Percorrendo vetor com índices:#include <stdio.h>
#define L 5
#define C 10
void main () {
char matriz[L][C];
int i, j;
for (i=0, j=0; i<L; i++)
for (j=0; j<C; j++)
matriz[i][j] = 'P';
for (i=0, j=0; i<L; i++)
for (j=0; j<C; j++)
printf("%c", matriz[i][j]);
} //as colunas (dimensões mais a direita) mudam mais rápido
Flavio M. StrelowLinguagem C
Vetor de StringsVetor de Strings
• Neste caso, cada elemento do vetor é um ponteiro para um caracter
• Declaração:
char *arstr[] = {"Joao", "Maria", "Antonio", "Zacarias", "Carlos"};
• arstr é um vetor de ponteiros para char, iniciado com os strings indicados
Flavio M. StrelowLinguagem C
Vetor de StringsVetor de Strings
• Comparando vetor de string com matriz de char
char *as[]={"Joao","Maria","Antonio","Zacarias","Carlos"};
char ma[5][10]= {"Joao","Maria","Antonio","Zacarias","Carlos"};
“Joao”
“Maria”
“Antonio”
“Zacarias”
“Carlos”
Ponteiros (as)J o a o
M a r i aA n t o n i oZ a c a r i a sC a r l o s
\0
\0\0
\0\0
Matriz (ma)
Flavio M. StrelowLinguagem C
Cuidados com StringsCuidados com Strings
• É comum esquecer de alocar uma área para armazenamento de caracteres
void main() {
char *pc; char str[] = "Uma string";
strcpy(pc, str); /* erro! pc indeterminado */...}
Flavio M. StrelowLinguagem C
Ponteiros para PonteirosPonteiros para Ponteiros
• É possível definir ponteiros para ponteiros até um nível arbitrário de indireção
• Ex: #include <stdio.h>
void main () {char *pc; /* ponteiro para char */char **ppc; /* ponteiro para ponteiro para
char */
pc = "teste";ppc = &pc;putchar(**ppc); /* ==> ‘t’ */
}
Flavio M. StrelowLinguagem C
Exemplo:Troca Variáveis - PonteirosExemplo:Troca Variáveis - Ponteiros
#include <stdio.h>void troca(int *, int *);int main(void){
int x, y;x = 3; y = 4;printf("main - x = %d, y=%d \n", x, y);troca(&x, &y);printf("main - x = %d, y=%d \n", x, y);
}void troca(int *x, int *y){
int z;printf("troca - x = %d, y=%d \n", *x, *y);z = *x; *x = *y; *y = z;printf("troca - x = %d, y=%d \n", *x, *y);
}
Flavio M. StrelowLinguagem C
Exercício 3 - PonteirosExercício 3 - Ponteiros
Escreva uma função que receba três números reais (float) e reordene-os de forma decrescente. Teste sua implementação.
Sugestão para protótipo da função:
void ordena(float *a, float *b, float *c);
top related