Ponteiros na programação C: O que é ponteiro, tipos & Exemplos

Índice:

Anonim

O que é Pointer em C?

O Pointer em C, é uma variável que armazena o endereço de outra variável. Um ponteiro também pode ser usado para se referir a outra função de ponteiro. Um ponteiro pode ser incrementado / decrementado, ou seja, para apontar para o próximo / anterior local de memória. O objetivo do ponteiro é economizar espaço na memória e obter um tempo de execução mais rápido.

Como usar ponteiros em C

Se declararmos uma variável v do tipo int, v na verdade armazenará um valor.

v é igual a zero agora.

Porém, cada variável, além do valor, também tem seu endereço (ou, simplesmente, onde está localizada na memória). O endereço pode ser recuperado colocando um E comercial (&) antes do nome da variável.

Se você imprimir o endereço de uma variável na tela, parecerá um número totalmente aleatório (além disso, pode ser diferente de uma corrida para outra).

Vamos tentar isso na prática com o ponteiro no exemplo C

A saída deste programa é -480613588.

Agora, o que é um ponteiro? Em vez de armazenar um valor, um ponteiro irá armazenar o endereço de uma variável.

Variável de Ponteiro

Int * y = & v;

VARIÁVEL

PONTEIRO

Um valor armazenado em um endereço de armazenamento / memória nomeado

Uma variável que aponta para o endereço de armazenamento / memória de outra variável

Declarando um Ponteiro

Como as variáveis, os ponteiros na programação C devem ser declarados antes de serem usados ​​em seu programa. Os ponteiros podem ter o nome que você quiser, desde que obedeçam às regras de nomenclatura C Uma declaração de ponteiro tem o seguinte formato.

data_type * pointer_variable_name;

Aqui,

  • data_type é o tipo de base do ponteiro dos tipos de variáveis ​​do C e indica o tipo da variável para a qual o ponteiro aponta.
  • O asterisco (*: o mesmo asterisco usado para multiplicação), que é um operador de indireção, declara um ponteiro.

Vamos ver algumas declarações de ponteiro válidas neste tutorial de ponteiros C:

int *ptr_thing; /* pointer to an integer */int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */double *ptr2; /* pointer to a double */float *ptr3; /* pointer to a float */char *ch1 ; /* pointer to a character */float *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */

Inicializar um ponteiro

Depois de declarar um ponteiro, nós o inicializamos como variáveis ​​padrão com um endereço de variável. Se os ponteiros na programação C não forem inicializados e usados ​​no programa, os resultados serão imprevisíveis e potencialmente desastrosos.

Para obter o endereço de uma variável, usamos o operador E comercial (&), colocado antes do nome de uma variável cujo endereço precisamos. A inicialização do ponteiro é feita com a seguinte sintaxe.

Sintaxe de ponteiro

 pointer = &variable; 

Um programa simples para ilustração de ponteiro é fornecido abaixo:

#include int main(){int a=10; //variable declarationint *p; //pointer variable declarationp=&a; //store address of variable a in pointer pprintf("Address stored in a variable p is:%x\n",p); //accessing the addressprintf("Value stored in a variable p is:%d\n",*p); //accessing the valuereturn 0;}

Resultado:

Address stored in a variable p is:60ff08Value stored in a variable p is:10
Operador Significado
* Serve 2 propósitos
  1. Declaração de um ponteiro
  2. Retorna o valor da variável referenciada
E Serve apenas 1 propósito
  • Retorna o endereço de uma variável

Tipos de ponteiros em C

A seguir estão os diferentes tipos de indicadores em C :

Ponteiro nulo

Podemos criar um ponteiro nulo atribuindo um valor nulo durante a declaração do ponteiro. Este método é útil quando você não tem nenhum endereço atribuído ao ponteiro. Um ponteiro nulo sempre contém o valor 0.

O programa a seguir ilustra o uso de um ponteiro nulo:

#include int main(){int *p = NULL; //null pointerprintf(“The value inside variable p is:\n%x”,p);return 0;}

Resultado:

The value inside variable p is:0

Ponteiro de Vazio

Na programação C, um ponteiro void também é chamado de ponteiro genérico. Ele não possui nenhum tipo de dados padrão. Um ponteiro void é criado usando a palavra-chave void. Ele pode ser usado para armazenar um endereço de qualquer variável.

O programa a seguir ilustra o uso de um ponteiro void:

#include int main(){void *p = NULL; //void pointerprintf("The size of pointer is:%d\n",sizeof(p));return 0;}

Resultado:

The size of pointer is:4

Ponteiro selvagem

Um ponteiro é considerado um ponteiro selvagem se não estiver sendo inicializado para nada. Esses tipos de ponteiros C não são eficientes porque podem apontar para alguma localização de memória desconhecida que pode causar problemas em nosso programa e pode levar ao travamento do programa. Deve-se sempre ter cuidado ao trabalhar com ponteiros selvagens.

O programa a seguir ilustra o uso do wild pointer:

#include int main(){int *p; //wild pointerprintf("\n%d",*p);return 0;}

Resultado

timeout: the monitored command dumped coresh: line 1: 95298 Segmentation fault timeout 10s main

Outros tipos de ponteiros em 'c' são os seguintes:

  • Ponteiro pendente
  • Ponteiro complexo
  • Ponteiro próximo
  • Ponteiro distante
  • Ponteiro enorme

Indicadores de acesso direto e indireto

Em C, existem duas maneiras equivalentes de acessar e manipular um conteúdo variável

  • Acesso direto: usamos diretamente o nome da variável
  • Acesso indireto: usamos um ponteiro para a variável

Vamos entender isso com a ajuda do programa abaixo

#include /* Declare and initialize an int variable */int var = 1;/* Declare a pointer to int */int *ptr;int main( void ){/* Initialize ptr to point to var */ptr = &var;/* Access var directly and indirectly */printf("\nDirect access, var = %d", var);printf("\nIndirect access, var = %d", *ptr);/* Display the address of var two ways */printf("\n\nThe address of var = %d", &var);printf("\nThe address of var = %d\n", ptr);/*change the content of var through the pointer*/*ptr=48;printf("\nIndirect access, var = %d", *ptr);return 0;}

Depois de compilar o programa sem erros, o resultado é:

Direct access, var = 1Indirect access, var = 1The address of var = 4202496The address of var = 4202496Indirect access, var = 48

Pointer Arithmetics em C

As operações do ponteiro estão resumidas na figura a seguir

Operações de Ponteiro

Operação prioritária (precedência)

Ao trabalhar com ponteiros C, devemos observar as seguintes regras de prioridade:

  • Os operadores * e & têm a mesma prioridade que os operadores unários (a negação !, o incremento ++, o decremento--).
  • Na mesma expressão, os operadores unários *, &,!, ++, - são avaliados da direita para a esquerda.

Se um ponteiro P apontar para uma variável X, então * P pode ser usado onde quer que X possa ser escrito.

As seguintes expressões são equivalentes:

int X = 10 int * P = & Y; Para o código acima, as expressões abaixo são verdadeiras
Expressão Expressão Equivalente
Y = * P + 1 * P = * P + 10 * P + = 2 ++ * P (* P) ​​++ Y = X + 1 X = X + 10 X + = 2 ++ X X ++

No último caso, os parênteses são necessários: como os operadores unários * e ++ são avaliados da direita para a esquerda, sem os parênteses o ponteiro P seria incrementado, não o objeto para o qual P aponta.

A tabela abaixo mostra a operação aritmética e básica que pode ser usada ao lidar com ponteiros C

Operação Explicação
Atribuição int * P1, * P2 P1 = P2; P1 e P2 apontam para a mesma variável inteira
Incrementação e decrementação Int * P1; P1 ++; P1--;
Adicionando um deslocamento (constante) Isso permite que o ponteiro mova N elementos em uma tabela. O ponteiro será aumentado ou diminuído por N vezes o número de byte (s) do tipo da variável. P1 + 5;

Ponteiros C e matrizes com exemplos

Tradicionalmente, acessamos os elementos do array usando seu índice, mas esse método pode ser eliminado usando ponteiros. Os ponteiros facilitam o acesso a cada elemento da matriz.

#include int main(){int a[5]={1,2,3,4,5}; //array initializationint *p; //pointer declaration/*the ptr points to the first element of the array*/p=a; /*We can also type simply ptr==&a[0] */printf("Printing the array elements using pointer\n");for(int i=0;i<5;i++) //loop for traversing array elements{printf("\n%x",*p); //printing array elementsp++; //incrementing to the next element, you can also write p=p+1}return 0;}

Resultado

12345

Adicionar um determinado número a um ponteiro moverá a localização do ponteiro para o valor obtido por uma operação de adição. Suponha que p seja um ponteiro que atualmente aponta para a localização da memória 0 se realizarmos a seguinte operação de adição, p + 1, então ele será executado desta maneira:

Adição / incremento de ponteiro

Como p atualmente aponta para a localização 0 após adicionar 1, o valor se tornará 1 e, portanto, o ponteiro apontará para a localização 1 da memória.

Ponteiros C e Strings com Exemplos

Uma string é uma matriz de objetos char, terminando com um caractere nulo '\ 0'. Podemos manipular strings usando ponteiros. Este ponteiro no exemplo C explica esta seção

#include #include int main(){char str[]="Hello Guru99!";char *p;p=str;printf("First character is:%c\n",*p);p =p+1;printf("Next character is:%c\n",*p);printf("Printing all the characters in a string\n");p=str; //reset the pointerfor(int i=0;i

Resultado

First character is:HNext character is:ePrinting all the characters in a stringHelloGuru99!

Outra maneira de lidar com strings é com uma matriz de ponteiros como no seguinte programa:

#include int main(){char *materials[ ] = { "iron", "copper", "gold"};printf("Please remember these materials :\n");int i ;for (i = 0; i < 3; i++) {printf("%s\n", materials[ i ]);}return 0;}

Resultado:

Please remember these materials:ironcoppergold

Vantagens dos ponteiros em C

  • Os ponteiros são úteis para acessar os locais da memória.
  • Os ponteiros fornecem uma maneira eficiente de acessar os elementos de uma estrutura de array.
  • Ponteiros são usados ​​para alocação de memória dinâmica, bem como desalocação.
  • Ponteiros são usados ​​para formar estruturas de dados complexas, como lista vinculada, gráfico, árvore, etc.

Desvantagens dos ponteiros em C

  • Os ponteiros são um pouco complexos de entender.
  • Os ponteiros podem levar a vários erros, como falhas de segmentação, ou podem acessar um local de memória que não é necessário.
  • Se um valor incorreto for fornecido a um ponteiro, ele pode causar corrupção de memória.
  • Os ponteiros também são responsáveis ​​pelo vazamento de memória.
  • Os ponteiros são comparativamente mais lentos do que as variáveis.
  • Os programadores acham muito difícil trabalhar com os ponteiros; portanto, é responsabilidade do programador manipular um ponteiro com cuidado.

Resumo

  • Um ponteiro nada mais é que um local da memória onde os dados são armazenados.
  • Um ponteiro é usado para acessar o local da memória.
  • Existem vários tipos de ponteiros, como ponteiro nulo, ponteiro selvagem, ponteiro void e outros tipos de ponteiros.
  • Ponteiros podem ser usados ​​com array e string para acessar elementos de forma mais eficiente.
  • Podemos criar ponteiros de função para invocar uma função dinamicamente.
  • As operações aritméticas podem ser feitas em um ponteiro, que é conhecido como aritmética de ponteiro.
  • Os ponteiros também podem apontar para uma função, o que torna mais fácil chamar funções diferentes no caso de definir um array de ponteiros.
  • Quando você quiser lidar com diferentes tipos de dados variáveis, você pode usar um ponteiro void typecast.