Ponteiros na programação C: o que é ponteiro, tipos e exemplos

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 irá realmente 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

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

PARA variável naquela aponta para o endereço de armazenamento / memória de outro variável

O que você aprenderá: [ exposição ]

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 ser nomeados como 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,

  • tipo de dados é 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, 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 declaration int *p; //pointer variable declaration p=&a; //store address of variable a in pointer p printf('Address stored in a variable p is:%x
',p); //accessing the address printf('Value stored in a variable p is:%d
',*p); //accessing the value return 0; } 

Saída:

Address stored in a variable p is:60ff08 Value 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
EServe 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 ponteiros 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 pointer printf(The value inside variable p is:
%x,p); return 0; } 

Saída:

The value inside variable p is: 0 

Ponteiro de Vazio

Na programação C, um ponteiro void também é chamado de ponteiro genérico. 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 pointer printf('The size of pointer is:%d
',sizeof(p)); return 0; } 

Saída:

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 ponteiro curinga:

 #include int main() { int *p; //wild pointer printf('
%d',*p); return 0; } 

Saída

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

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

  • Ponteiro pendurado
  • 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('
Direct access, var = %d', var); printf('
Indirect access, var = %d', *ptr); /* Display the address of var two ways */ printf('

The address of var = %d', &var); printf('
The address of var = %d
', ptr); /*change the content of var through the pointer*/ *ptr=48; printf('
Indirect access, var = %d', *ptr); return 0;}

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

 Direct access, var = 1 Indirect access, var = 1 The address of var = 4202496 The address of var = 4202496 Indirect 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ãoExpressã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çãoint * P1, * P2 P1 = P2; P1 e P2 apontam para a mesma variável inteira
Incrementação e decrementaçãoInt * 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 initialization int *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
'); for(int i=0;i<5;i++) //loop for traversing array elements { printf('
%x',*p); //printing array elements p++; //incrementing to the next element, you can also write p=p+1 } return 0; } 

Saída

1 2 3 4 5 

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 de 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
',*p); p =p+1; printf('Next character is:%c
',*p); printf('Printing all the characters in a string
'); p=str; //reset the pointer for(int i=0;i

Saída

First character is:H Next character is:e Printing all the characters in a string H e l l o G u r u 9 9 ! 

Outra maneira de lidar com strings é com um array de ponteiros como no seguinte programa:

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

Saída:

 Please remember these materials: iron copper gold 

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 da 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.