1. Introdução
Recentemente, eles me abordaram com a pergunta “o que é e como usá-lo?”, Mostrando o seguinte código:
extern "C" { void byteMaskDowngrade(byte***const byteMask, const byte *const *const && source) {
Esse colega era meu colega de trabalho e não entendemos imediatamente o que exatamente os parâmetros significam na declaração da função (para aqueles que estão interessados em onde esse anúncio pode ser necessário: em criptografia).
E, antecipando possíveis problemas dos colegas do workshop, decidi criar este artigo, colocando-o como uma folha de dicas, ou seja, as respostas para duas perguntas:
- Como escrever esses anúncios aqui?
- E como lê-los corretamente?
"*"
O caso com um asterisco é o mais comum, no entanto, mal-entendidos também são possíveis aqui:
- Como:
- Então:
const byte p;
- Ou então:
byte const p;
- Ou no caso da entrada '*':
- Então:
byte *const p;
- Ou então:
const byte *p;
Estritamente falando, do ponto de vista do compilador, a presença de um asterisco e sua posição na expressão colocam uma questão de ponta porque o significado final da entrada será diferente. A presença do especificador const no caso acima não faz nenhuma diferença ao considerar sua posição em relação ao tipo de dados; no entanto, a situação muda drasticamente quando os ponteiros aparecem: um, dois, três ... bem, você entende:
void p() {
Tudo isso parece mais interessante quando o segundo ponteiro aparece (aqui uma regra de leitura eficiente para a escrita já está começando a ser rastreada):
void pp() {
Como você pode ver, um ponteiro duplo pode ser representado em até 8 maneiras diferentes, cada uma das quais define uma maneira especial de usar os dados de destino.
As regras para a leitura de tais expressões são as seguintes:
- procure o sinal '=' na expressão e leia a expressão da direita para a esquerda;
- pule o nome da variável;
- reuniões adicionais ou '*', que significa um ponteiro regular, ou '* const' - um ponteiro constante;
- assim, lemos até que o tipo de dados (byte) seja encontrado;
- e a última palavra à esquerda do tipo de dados pode ser const, cuja presença significa que toda essa construção se refere a dados que não podem ser alterados; se const não for, então é possível.
Essa forma de escrever e ler facilita a leitura e a compreensão mesmo das expressões mais sofisticadas.
Aqui está um exemplo de um conjunto
completo de expressões com um ponteiro triplo:
"***"
void ppp() {