vetores e ponteiros

1. vetores e ponteiros

daniele hartmann
danielehartmann

(usa Kurumin)

Enviado em 13/03/2008 - 17:08h

Ola!!!!
Estou aqui para poder debater a respeito de ponteiros e vetores.

O que é um ponteiro

O ponteiro contem o endereço de um tipo. Exemplo.. Voce quer falar com sua mae mais nao tem o numero de telf. Entao voce sabe que a sua erma tem o numero de telf da sua mae.Entao ela e o ponteiro. Usando o ponteiro voce nao falara com sua mae, voce so vai poder obter o numero de telf dela.

Outro exempl -> O que é o ponteiro de um relógio? É o que aponta para as horas, minutos ou segundos. Um ponteiro aponta para algo. Em programação, temos as variáveis armazenadas na memória, e um ponteiro aponta para um endereço de memória.

Imagine as variáveis como documentos, a memória do computador como pastas para guardar os documentos, e o ponteiro como atalhos para as pastas.

Não se desespere caso não consiga entender num primeiro momento, o conceito fica mais claro com a prática.

Declarando e acessando ponteiros

Um ponteiro, como qualquer variável, deve ter um tipo, que é o tipo da variável para a qual ele apontaPara declarar um ponteiro, especificamos o tipo da variável para a qual ele aponta e seu nome precedido por asterisco:

int minha_mae; // declara uma variável comum do tipo inteiro
int *minha_erma; // declara um ponteiro para um inteiro

Vetores de Ponteiros

Como ponteiros também são variáveis é possível então criar vetores de ponteiros e utilizá-los. O programa exemplo c8vepon.c mostra um programa onde é utilizado um vetor de ponteiros para linhas de caracteres.


#define LINHAS 10
#define COLUNAS 60

/* prototipos das funcoes */
void alocaespaco(char *linha[]);
void lelinhas (char *linha[]);
void imprimelinhas (char *linha[]);
void ordenalinhas (char *linha[]);

void main(void)
{
char *linha[LINHAS];
alocaespaco(linha);
lelinhas(linha);
imprimelinhas(linha);
ordenalinhas(linha);
imprimelinhas(linha);
}
/* Esta rotina aloca espaco para as linhas */
void alocaespaco(char *linha[]){
int i;

for (i=0; i<LINHAS; i++){
if (!(linha[i] = malloc(COLUNAS*sizeof(int)))){
printf("Nao consegui alocar o vetor %d.\n", i);
exit(i);
}
}
}

/* Esta rotina le linhas */
void lelinhas (char *linha[]){
int i;

for (i=0; i<LINHAS; i++){
printf("Entre com a linha %d.\n", i);
gets(linha[i]);
}
}

/* Esta rotina imprime as linhas */
void imprimelinhas (char *linha[]){
int i;

for (i=0; i<LINHAS; i++){
printf("Linha %d %s.\n", i, linha[i]);
}
}

void ordenalinhas( char *linha[]){
char trocou;
char *p;
int i;

do {
trocou = 0;
for (i=0; i<LINHAS-1; i++){
if (strcmp(linha[i], linha[i+1]) >0){
p = linha[i];
linha[i] = linha[i+1];
linha[i+1] = p;
trocou = 1;
}
}
} while (trocou);


}

bom aqui tem um pouquinho sobre o assunto quem poder colaborar com mais coisas vai ser bacana.


  


2. aritmética ponteiros

João Marcos Menezes
stremer

(usa Arch Linux)

Enviado em 14/03/2008 - 13:36h

Uma outra coisa interessante em ponteiros é o assunto de aritmética de ponteiros, onde se aplicado aritmética em variaveis do tipo ponteiro, se percorre as posições da memória de acordo com o tamanho da estrutura. Com isto pode-se inclusive verificar valores da memória de outros tipos de dados. Fica mais facil vendo o exemplo em C, que no caso abaixo, mostro os valores em hexa (os bytes armazenados na memória) de um número inteiro.
Um cuidado a ser tomado que a aritmética precisa ser cuidadosamente controlado, ou pode-se passar do limite alocado pelo tipo de dado e começar a acessar outros pontos da memória e causando problema a outros aplicativos.
Vejam o código com os comentários.

#include "stdio.h"

typedef struct estrutura {
int tipo;
char valor[10];
} estrut;

char * charToHex(char carac);

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

// Vamos criar um ponteiro para um caractere alocando 10 bytes
char * string = (char *) malloc(sizeof(char) * 10);

// Agora vamos gravar 10 bytes
strcpy(string, "ABCDEFGHIJ");

// Aqui vamos criar um outro ponteiro, que irá apontar para o mesmo
// endereço inicial
char * pontAritString = string;
// E vamos fazer um loop de 10 vezes (para imprimir os 10 caracteres)
for (int i = 0; i < 10; i++) {
printf("%c", *pontAritString);

// Aqui estaremos aplicando a aritmética de ponteiro, onde estaremos
// somando 1 do tipo do ponteiro, ou seja avançando 1 byte (pois é um ponteiro para
// caracteres)
pontAritString++;
}

// Depois que avançamos 10 posições o valor daquele endereço será um byte 0 (ou nulo)
if (*pontAritString == NULL) {
printf("\n%s\n", "NULO");
}

// CUIDADO: Se a aritmética for aplicada de maneira errada, iremos enxergar a próxima posição
// da memória que poderá ser parte de outro programa inclusive. Se você começar a mudar os valores
// é aqui que os problemas começam
pontAritString++;

// Vamos imprimir o valor inteiro do caractere para não detonar com o terminal
printf("%d", (int) *pontAritString);

// Outro exemplo legal é que a aritmética é aplicada na estrutura
// Veja o exemplo, armazenando 10 estruturas
estrut * testeEstrut = (estrut *) malloc(sizeof(estrut) * 10);

// Vamos criar uma outra variavel ponteiro para o inicio da estrutura
estrut * pontTesteEstrut = testeEstrut;
// Vamos preencher 10 valores
for (int i = 0; i < 10; i++) {
pontTesteEstrut->tipo = i;
char tmp[10];
sprintf(tmp, "String: %d", i);
strcpy(pontTesteEstrut->valor, tmp);
pontTesteEstrut++;
}

// E agora vamos imprimir os valores preenchidos
// Lembrando que temos de apontar novamente para o endereço inicial
pontTesteEstrut = testeEstrut;
for (int i = 0; i < 10; i++) {
printf("\nTipo: %d - Valor: %s", pontTesteEstrut->tipo, pontTesteEstrut->valor);
pontTesteEstrut++;
}

// Outra coisa interessante é que podemos aplicar a aritmética ou cast do tipo de dados
// a partir de outros dados (afinal tudo são bytes)
// Veja o exemplo:
signed int * pontInteiro = (signed int *) malloc(sizeof(signed int));
// Vamos armazenar o número 158255
*pontInteiro = 158255;

// Agora vamos fazer a aritmética utilizando uma estrutura de char (1 byte)
// Serão impressos os bytes do número 158255 que são: 02 6A 2F, na forma
// de armazenamento de inteiro será impresso 2F 6A 02, ou seja, os bytes
// de armazenamento do número 158255
char * pontCharInteiro = (char *) pontInteiro;
printf("\nSerão impressos os bytes do número:\n");
while (*pontCharInteiro != NULL) {
printf("%s\n", charToHex(*pontCharInteiro));

// aqui avançamos 1 byte
pontCharInteiro++;
}


return 0;
}

char * charToHex(char carac) {
// Tosco, poderia ser muitoooo melhor
char * ret = new char[2];
char hexa[16];
hexa[0] = '0';
hexa[1] = '1';
hexa[2] = '2';
hexa[3] = '3';
hexa[4] = '4';
hexa[5] = '5';
hexa[6] = '6';
hexa[7] = '7';
hexa[8] = '8';
hexa[9] = '9';
hexa[10] = 'A';
hexa[11] = 'B';
hexa[12] = 'C';
hexa[13] = 'D';
hexa[14] = 'E';
hexa[15] = 'F';
int comp = 0;
int val1;
int val2;
for (int x = 0; x < 16; x++) {
val1 = x;
for (int y = 0; y < 16; y++) {
val2 = y;
if ((char) comp == carac) {
ret[0] = hexa[val1];
ret[1] = hexa[val2];
ret[2] = NULL;
y = 16;
x = 16;
break;
}
comp ++;
}
}
return ret;
}




3. Re: vetores e ponteiros

Pirrola
pirrola

(usa Zenwalk)

Enviado em 20/03/2008 - 21:39h

acho que vc quis dar uma dica neh? bom, entaum contribuindo, uma coisa que os iniciantes em C se confundem muito é no uso da função void...para que usar uma função que não retorna valor? simples, pq array(vetor e matriz) na declaração de função é ponteiro!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts