関数呼び出しで複数のアスタリスクを実際に使用することは考えられません。
void foo(int a, char b)
{
}
int main(void)
{
(**************foo)(45, 'c');
//or with pointer to function:
void (*ptr)(int, char) = foo;
(******ptr)(32, 'a');
}
なぜこれがCとC++の両方で許可されているのですか?
関数呼び出しで複数のアスタリスクを実際に使用することは考えられません。
void foo(int a, char b)
{
}
int main(void)
{
(**************foo)(45, 'c');
//or with pointer to function:
void (*ptr)(int, char) = foo;
(******ptr)(32, 'a');
}
なぜこれがCとC++の両方で許可されているのですか?
CとC++の両方での標準的な変換の1つは、関数からポインターへの変換です。関数名が式に含まれている場合、その関数へのポインターに変換できます。それで:
foo
と同等です&foo
*foo
*(&foo)
、、またはと同等ですfoo
**foo
、、、**(&foo)
または*foo
と同等ですfoo
等々。
*
これは、関数名の前に、その意味を変更せずに、合法的に好きなだけ追加できることを意味します。ただし、それを行う理由はありません。
なぜこれがCとC++の両方で許可されているのですか?
私はC++について話すことはできませんが、Cの場合、少なくとも関数指定子はポインターに変換されます。
6.3.2.1-4
関数指定子は、関数型を持つ式です。sizeof演算子または単項&演算子のオペランドである場合を除き、「関数戻り型」型の関数指定子は、「<strong>関数戻り型へのポインター」型の式に変換されます。
間接演算子を適用すると、関数指定子が生成されます。
6.5.3.2-3
単項*演算子は、間接参照を示します。オペランドが関数を指している場合、結果は関数指定子になります
したがって、間接演算子を何度適用しても、同じことが得られます。つまり、すぐにポインターに変換される関数指定子です。
私の意見では、これを行うことにはほとんどまたはまったく意味がありません。
*
オペレーターはアドレス値を期待しているためです。また、(オブジェクトや関数のglvalueではなく)値が期待される場合は常に、左辺値から右辺値、関数からポインター、配列からポインターへの変換がオペランドに適用されます。したがって、逆参照された関数は、再び逆参照されるとすぐに再びポインターに変換されます。
これらはすべて、オブジェクトから値を読み取るか、配列または関数の先頭をそれぞれ参照するポインタ値を生成します。
これらの間接参照の行には、そのlulz以外の目的はありません。
私がそれを理解する方法は
* is a pointer to a memory address
& is the value at the Memory address
*foo means pointer to foo memory address
**foo means *(*foo) *(foo memory address) This is a different value from *foo
それはそのように続きます...