Quais são as operações apoiadas pelo ponteiro bruto e ponteiro de função em C / C ++?

StackOverflow https://stackoverflow.com/questions/1418068

Pergunta

O que são todas as operações apoiadas por função difere ponteiro de ponteiro bruto? É>, <, <=,> = operadores suportados por ponteiros crus se assim o que é o uso?

Foi útil?

Solução

Para ambos os ponteiros de função e objeto, eles compilar mas o seu resultado só é garantido para ser consistente para endereços de sub-objetos de um mesmo objeto completo (você pode comparar os endereços dos dois membros de uma classe ou array) e se você comparar uma função ou objeto contra si mesmo.

Usando std::less<>, std::greater<> e assim por diante vai funcionar com qualquer tipo de ponteiro, e vai dar resultados consistentes, mesmo se o resultado do respectivo operador interno não é especificado:

void f() { }
void g() { }

int main() {
  int a, b;

  ///// not guaranteed to pass
  assert((&a < &b) == (&a < &b));

  ///// guaranteed to pass
  std::less<int*> lss1;
  assert(lss1(&a, &b) == lss1(&a, &b));
  // note: we don't know whether lss1(&a, &b) is true or false. 
  //       But it's either always true or always false. 

  ////// guaranteed to pass
  int c[2];
  assert((&c[0] < &c[1]) == (&c[0] < &c[1]));
  // in addition, the smaller index compares less:
  assert(&c[0] < &c[1]);

  ///// not guaranteed to pass
  assert((&f < &g) == (&f < &g));

  ///// guaranteed to pass
  assert((&g < &g) == (&g < &g));
  // in addition, a function compares not less against itself. 
  assert(!(&g < &g));

  ///// guaranteed to pass
  std::less<void(*)()> lss2;
  assert(lss2(&f, &g) == lss2(&f, &g));
  // note: same, we don't know whether lss2(&f, &g) is true or false.

  ///// guaranteed to pass
  struct test {
    int a;
  // no "access:" thing may be between these!
    int b;

    int c[1];
  // likewise here
    int d[1];

    test() {
      assert((&a < &b) == (&a < &b));
      assert((&c[0] < &d[0]) == (&c[0] < &d[0]));

      // in addition, the previous member compares less:
      assert((&a < &b) && (&c[0] < &d[0]));
    }
  } t;
}

Tudo isso deve compilar embora (embora o compilador é livre para avisar sobre qualquer trecho de código que quer).


Uma vez que os tipos de funções não têm valor sizeof, operações que são definidas em termos de sizeof do tipo pointee não trabalho, que incluem:

void(*p)() = ...;
// all won't work, since `sizeof (void())` won't work.
// GCC has an extension that treats it as 1 byte, though.
p++; p--; p + n; p - n; 

O + unário funciona em qualquer tipo de ponteiro, e só vai retornar o valor do mesmo, não há nada especial sobre ele para ponteiros de função.

+ p; // works. the result is the address stored in p.

Finalmente, note que um ponteiro para uma função ponteiro não é um ponteiro de função mais:

void (**pp)() = &p;
// all do work, because `sizeof (void(*)())` is defined.
pp++; pp--; pp + n; pp - n;

Outras dicas

Você pode comparar os ponteiros se eles apontam para a mesma destinação. Por exemplo, se você tem dois ponteiros apontando para elementos da mesma matriz, você pode usar a desigualdade operadores de comparação sobre os ponteiros. Por outro lado, se você tem dois ponteiros apontando para diferentes objetos, então a comparação é "indefinido", embora, na prática, a maioria dos compiladores provavelmente só irá comparar o endereço.

char *text[] = "hello";
const char *e_ptr = strchr(text, 'e');
const char *o_ptr = strchr(text, 'o');
if (e_ptr < o_ptr) { ... }  // this is legal
char *other_text[] = "goodbye";
const char *b_ptr = strchr(other_text, 'b');
if (b_ptr > o_ptr) { ... }  // not strictly legal

# 1 :. Ponteiros de função pode ser chamado

# 2 : Os operadores relacionais são suportados para ponteiros, porque você pode usá-los em aritmética de ponteiro e comparar os endereços para o outro. Exemplo prático: Atravessando um array

int data[5] = { 1, 2, 3, 4, 5 };

// Increment pointer until it reaches the end-address. 
for (int* i = data; i < data + 5; ++i) {
    std::cout << *i << endl; 
}

Os operadores <,>, <=,> = são suportados para os ponteiros, mas só são garantidos para produzir resultados confiáveis ??se os dois ponteiros estão sendo comparados são parte da mesma alocação de memória (como comparar dois ponteiros para índices em uma matriz alocação). Para estes, que indica a posição relativa na atribuição (isto é, se a usando apenas a parte inferior 32 bits, se um único atribuição não pode exceder o tamanho permitido para um apontador de 32 bits). Estes realmente não faz sentido no contexto de ponteiros de função, uma vez que não abordam a alocação de memória contínua.

Outras operações de ponteiro bruto: == retorna true se os ponteiros estão apontando para o mesmo objeto. - produz o número de bytes entre os dois ponteiros (eu acho bom apenas para a mesma alocação?). + Não compila, como seria sem sentido.

Para ponteiros de função, eles podem ser dereferenced com * e chamado.

Para ponteiro-para-membro-funções, há os operadores -.> * E *

Um ponteiro é representado como um valor normal número inteiro. Você pode fazer tudo com ponteiros que também é permitido em todos os outros tipos numéricos. ! + - * / << >> == = ^ & | ! ~%. Espero que eu esqueci nada.

Um ponteiro função só é diferente dessa forma que ele pode ser chamado com o operador ().

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top