私は奇妙なタイプのプログラムを見ました here 。
int main()
{
int s[]={3,6,9,12,18};
int* p=+s;
}
上記のプログラムはGCCおよびClangコンパイラーでテストされ、正常に動作しています両方のコンパイラ。
知りたいのですが、int* p=+s;
は何をしますか?
配列s
はポインター型に減衰していますか?
組み込みの operator+
はオペランドとしてポインター型をとることができるため、配列s
を渡すと 配列からポインターへの変換 が発生し、ポインターint*
が返されます。つまり、+s
を個別に使用してポインターを取得できます。 (この場合、それは不要です。operator+
がなければ、ポインターに減衰してからp
に割り当てられます。)
(エンファシス鉱山)
組み込みの単項プラス演算子は、そのオペランドの値を返します。 no-opではない唯一の状況は、オペランドが整数型またはスコープなし列挙型であり、整数プロモーションによって変更される場合です。たとえば、charをintに変換する場合、またはオペランドが左辺値から右辺値の場合配列からポインターへ、または関数からポインターへの変換。
これをテストします:
#include <stdio.h>
int main(){
char s[] = { 'h', 'e', 'l', 'l', 'o' , ' ', 'w', 'o', 'r', 'l', 'd', '!'} ;
printf("sizeof(s) : %zu, sizeof(+s) : %zu\n", sizeof(s), sizeof(+s) ) ;
}
私のPC(Ubuntu x86-64)では次のように出力されます:
sizeof(s): 12, sizeof(+s) : 8
どこで
12 = number of elements s times size of char, or size of whole array
8 = size of pointer
これは単項プラス記号で、ここでは実用的な効果はありません。例えば:
#include <iostream>
int main() {
int a[] = {1};
std::cout << a << " " << +a << std::endl;
}
これにより、a
と+a
の両方に同じアドレスが出力されます。配列は通常どおりポインターに減衰します。
それが単項マイナス-a
であった場合、GCCはエラーを表示することに注意してください。
error: wrong type argument to unary minus
編集:OPのコードには影響しませんが、a
と+a
はまったく同じではありません。詳細については、Khurshid Normuradovとsongyuanyaoの回答を参照してください。
配列
s
はポインター型に減衰していますか?
はい
int* p=+s;
は何をしますか?
単項+
演算子は、配列をポインターに強制的に減衰させます。
C++標準、5.3.1単項演算子(P7):
単項+演算子のオペランドは、算術、スコープなし列挙、またはポインタータイプでなければならず、結果は引数の値です。積分プロモーションは、整数または列挙オペランドで実行されます。結果のタイプは、昇格されたオペランドのタイプです。
単項+
形式(+s)
は、オペランドを数値またはポインターとして強制的に評価します。
詳細については、こちらをご覧ください stack overflow answer 。
ここで、単項+は、整数配列のアドレスを指すように* pを作成しているだけです。 2つの配列s1とs2を取りましょう
int s1[]={1,5,2};
int s2[]={2,5,2};
int *p=+s1;
p=+s2;
printf("%d",(int)p[0]);
出力:2
したがって、私の観点では、単項+はポインタpを作成して配列sの開始アドレスを指すだけです。