web-dev-qa-db-ja.com

「int * p = + s;」とは何ですか行う?

私は奇妙なタイプのプログラムを見ました here

int main()
{
    int s[]={3,6,9,12,18};
    int* p=+s;
}

上記のプログラムはGCCおよびClangコンパイラーでテストされ、正常に動作しています両方のコンパイラ。

知りたいのですが、int* p=+s;は何をしますか?

配列sはポインター型に減衰していますか?

62
msc

組み込みの operator+ はオペランドとしてポインター型をとることができるため、配列sを渡すと 配列からポインターへの変換 が発生し、ポインターint*が返されます。つまり、+sを個別に使用してポインターを取得できます。 (この場合、それは不要です。operator+がなければ、ポインターに減衰してからpに割り当てられます。)

(エンファシス鉱山)

組み込みの単項プラス演算子は、そのオペランドの値を返します。 no-opではない唯一の状況は、オペランドが整数型またはスコープなし列挙型であり、整数プロモーションによって変更される場合です。たとえば、charをintに変換する場合、またはオペランドが左辺値から右辺値の場合配列からポインターへ、または関数からポインターへの変換。

62
songyuanyao

これをテストします:

#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
24

これは単項プラス記号で、ここでは実用的な効果はありません。例えば:

#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の回答を参照してください。

11
taskinoor

配列sはポインター型に減衰していますか?

はい

int* p=+s;は何をしますか?

単項+演算子は、配列をポインターに強制的に減衰させます。

C++標準、5.3.1単項演算子(P7):

単項+演算子のオペランドは、算術、スコープなし列挙、またはポインタータイプでなければならず、結果は引数の値です。積分プロモーションは、整数または列挙オペランドで実行されます。結果のタイプは、昇格されたオペランドのタイプです。

単項+形式(+s)は、オペランドを数値またはポインターとして強制的に評価します。

詳細については、こちらをご覧ください stack overflow answer

10
msc

ここで、単項+は、整数配列のアドレスを指すように* 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の開始アドレスを指すだけです。

0
Mudassar045