简体   繁体   English

C / C ++中原始指针和函数指针支持的操作是什么?

[英]What are the operations supported by raw pointer and function pointer in C/C++?

What are all operations supported by function pointer differs from raw pointer? 函数指针支持的所有操作与原始指针有什么不同? Is > , < , <= , >=operators supported by raw pointers if so what is the use? 是>,<,<=,> =原始指针支持的运算符如果有,有什么用?

For both function and object pointers, they compile but their result is only guaranteed to be consistent for addresses to sub-objects of the same complete object (you may compare the addresses of two members of a class or array) and if you compare a function or object against itself. 对于函数和对象指针,它们都会编译,但只保证它们的结果对于同一个完整对象的子对象的地址是一致的(你可以比较一个类或数组的两个成员的地址),如果你比较一个函数或反对自己。

Using std::less<> , std::greater<> and so on will work with any pointer type, and will give consistent results, even if the result of the respective built-in operator is unspecified: 使用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;
}

Everything of that should compile though (although the compiler is free to warn about any code snippet it wants). 这一切都应该编译(虽然编译器可以自由地警告它想要的任何代码片段)。


Since function types have no sizeof value, operations that are defined in terms of sizeof of the pointee type will not work, these include: 由于函数类型没有sizeof值,因此根据pointee类型的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; 

The unary + works on any pointer type, and will just return the value of it, there is nothing special about it for function pointers. 一元+适用于任何指针类型,并且只返回它的值,对于函数指针没有任何特殊之处。

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

Finally note that a pointer to a function pointer is not a function pointer anymore: 最后请注意,指向函数指针的指针不再是函数指针:

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

You can compare pointers if they point into the same allocation. 如果指针指向相同的分配,则可以比较指针。 For example, if you have two pointers pointing at elements of the same array, you can use inequality comparison operators on those pointers. 例如,如果有两个指针指向同一个数组的元素,则可以在这些指针上使用不等式比较运算符。 On the other hand, if you have two pointers pointing at different objects, then comparison is "undefined", though, in practice, most compilers will probably just compare the addresses. 另一方面,如果你有两个指针指向不同的对象,那么比较是“未定义的”,但实际上,大多数编译器可能只是比较地址。

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 : Function pointers can be invoked. #1 :可以调用函数指针。

#2 :The relational operators are supported for pointers because you can use them in pointer arithmetics and compare addresses to each other. #2 :指针支持关系运算符,因为你可以在指针算术中使用它们并将地址相互比较。 Practical example: Traversing an 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; 
}

The operators <, >, <=, >= are supported for pointers, but are only guaranteed to produce reliable results if the two pointers being compared are part of the same memory allocation (like comparing two pointers to indexes in an array allocation). 指针支持运算符<,>,<=,> =,但如果被比较的两个指针是相同内存分配的一部分(比如在数组分配中比较两个指针的指针),则只能保证产生可靠的结果。 For these, it indicates relative position in the allocation (ie, if a < b, then a is pointing to a lower index in the array than b). 对于这些,它表示分配中的相对位置(即,如果a <b,则a指向阵列中的下部索引而不是b)。 For pointers that are not in the same allocation, the result is implementation defined (and in some architectures, can violate strict less than compatibility needed for maps. For instance, a 64-bit pointer could be compared for < or > using only the lower 32 bits, if an single allocation cannot exceed the size allowed for a 32-bit pointer). 对于不在相同分配中的指针,结果是实现定义的(并且在某些体系结构中,可能违反严格的地图所需的兼容性。例如,可以仅使用较低的比较来比较<或>的64位指针32位,如果单个分配不能超过32位指针允许的大小)。 These don't really make sense in the context of function pointers since they don't address a continuous memory allocation. 这些在函数指针的上下文中没有意义,因为它们不能解决连续的内存分配问题。

Other raw pointer operations: == returns true if the pointers are pointing to the same object. 其他原始指针操作:==如果指针指向同一个对象,则返回true。 - produces the number of bytes between the two pointers (I think good for the same allocation only?). - 产生两个指针之间的字节数(我认为仅适用于相同的分配?)。 + doesn't compile, as it would be meaningless. +不编译,因为它没有意义。

For function pointers, they can be dereferenced by * and called. 对于函数指针,可以通过*取消引用它们并调用它们。

For pointer-to-member-functions, there are the operators ->* and .* 对于指向成员函数的指针,有运算符 - > *和。*

A pointer is represented as a normal integer value. 指针表示为正常整数值。 You can do everything with pointers which is also allowed on all other numeric types. 您可以使用指针执行所有操作,这也适用于所有其他数字类型。 + - * / << >> == != ^ & | + - * / << >> ==!= ^&| ! ~ %. 〜%。 I hope I forgot nothing. 我希望我什么也没忘记。

A function pointer is only different in that way that it can be called with the () operator. 函数指针的不同之处在于可以使用()运算符调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM