什么是由原始指针和函数指针在C / C ++支持的操作?(What are the operatio

2019-07-17 21:43发布

什么是通过函数指针支持的所有操作从原始指针有所不同? 为>,<,<=,> =运营​​商通过原始指针支持若然有什么用?

Answer 1:

对于这两种功能和对象的指针,它们编译,但其结果只能保证是一致的相同的完整对象的子对象地址(你可以将一个类或数组的两个成员的地址),如果比较功能或对象对自身。

使用std::less<> std::greater<>等将与任何指针类型的工作,并提供一致的结果,即使结果各自内置的操作是不确定的:

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;
}

那一切都应该编译虽然(尽管编译器可以自由地警告任何代码片断就是了)。


由于功能类型没有sizeof值,在术语定义操作sizeof指针对象类型将无法工作,其中包括:

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; 

一元+适用于任何指针类型,并且将只返回它的价值,没有什么特别之处函数指针。

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

最后请注意,一个指向函数指针不是一个函数指针了:

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


Answer 2:

如果它们指向到相同的分配您可以比较指针。 例如,如果有两个指针在相同的数组的元素指向,可以在这些指针使用不等式比较运算符。 在另一方面,如果你有两个指针在不同对象的指示,则比较“不确定”,但在实践中,大多数编译器可能会只是比较地址。

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


Answer 3:

#1:函数指针可以被调用。

#2:关系运算符支持指针,因为你可以在指针算术中使用它们,并比较地址给对方。 实际的例子:遍历一个数组

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; 
}


Answer 4:

运营商<,>,<=,> =都支持指针,但只保证产生可靠的结果,如果这两个指针被比较是相同的存储器分配(如在阵列中分配两个指针进行比较来索引)的一部分。 对于这些,则表示在分配的相对位置(即,如果A <B,则所指向的数组比b在较低的指数)。 对于不是在相同的分配指针,其结果是实现定义(并且在一些结构中,可以违反严格小于所需的地图的相容性。例如,一个64位指针可用于<或>仅使用较低的比较32位,如果一个单个分配不能超过)所允许的32位指针的大小。 这些并没有真正意义的函数指针的情况下,因为它们没有解决一个连续的内存分配。

其他原始指针操作:==如果指针指向同一个对象返回true。 - 产生两个指针之间的字节数(我想好了只相同的分配?)。 +不能编译,因为这将是毫无意义的。

对于函数指针,它们可以通过*解除引用和调用。

为指针到部件的功能,有操作员 - > *和*



Answer 5:

指针被表示为正常整数值。 你可以用它的指针也允许所有其他数字类型的一切。 !+ - * / << >> == = ^&| ! 〜%。 我希望我忘了什么。

一个函数指针是仅在该方式,它可以与所述()算子被称为不同。



文章来源: What are the operations supported by raw pointer and function pointer in C/C++?