13

ここにコードがあります -

  1 int main(int argc, char *argv[])
  2 {
  3     signed char S, *psc;
  4     unsigned char U,  *pusc;
  5     char C, *pc;
  6 
  7     C = S;
  8     C = U;
  9 
 10     pc = psc;
 11     pc = pusc;
 12 
 13     return 0;
 14 }

$ gcc test.cpp -o a
test.cpp: In function ‘int main(int, char**)’:
test.cpp:10:7: error: invalid conversion from ‘signed char*’ to ‘char*’ [-fpermissive]
test.cpp:11:7: error: invalid conversion from ‘unsigned char*’ to ‘char*’ [-fpermissive]

これは、Intel 32 ビット マシン上の Ubuntu 12.10 の gcc バージョン 4.6.3 でコンパイルされます。

charそのタイプがunsigned charx86にあることを考慮してください。-

ポインター以外の型に対する 7 行目と 8 行目の割り当てが OK の場合、10 行目と 11 行目のポインター型でエラーがスローされるのはなぜですか?

また、C = Uキャストを必要とせずに成功する必要がありますか?

4

4 に答える 4

7

まず、charsigned char、およびunsigned charがすべて異なる型であるという事実を強調することが重要です。C++11 標準のセクション 4.10 では、異なる型のポインター間で可能な 3 つの標準ポインター変換が定義されています。

1. null ポインター定数は、0 に評価される整数型の整数定数式 (5.19) prvalue、または型 std::nullptr_t の prvalue です。null ポインター定数はポインター型に変換できます。結果はその型の null ポインター値であり、オブジェクト ポインターまたは関数ポインター型の他のすべての値と区別できます。このような変換をヌルポインタ変換と呼びます。同じ型の 2 つのヌル ポインター値は、比較すると等しくなります。null ポインター定数から cv 修飾型へのポインターへの変換は単一の変換であり、ポインター変換の後に修飾変換 (4.4) が続くシーケンスではありません。整数型の null ポインター定数は、std::nullptr_t 型の prvalue に変換できます。[ 注: 結果の prvalue は null ポインター値ではありません。—終わりのメモ]

ここにはタイプの null ポインターがないため、これは関係ありませんnulltptr_t

2. 「cv T へのポインター」型 (T はオブジェクト型) の prvalue は、「cv void へのポインター」型の prvalue に変換できます。「cv T へのポインター」を「cv void へのポインター」に変換した結果は、オブジェクトが型 T の最派生オブジェクト (1.8) であるかのように、型 T のオブジェクトが存在する格納場所の先頭を指します。 (つまり、基本クラスのサブオブジェクトではありません)。null ポインター値は、変換先の型の null ポインター値に変換されます。

宛先タイプが ではないため、これは適用できませんvoid。ついに、

3. タイプ「cv D へのポインター」の prvalue (D はクラス タイプ) は、タイプ「cv B へのポインター」の prvalue に変換できます。ここで、B は D の基底クラス (条項 10) です。アクセスできない (11 節) またはあいまいな (10.2) D の基本クラス、この変換を必要とするプログラムは形式が正しくありません。変換の結果は、派生クラス オブジェクトの基本クラス サブオブジェクトへのポインターです。null ポインター値は、変換先の型の null ポインター値に変換されます。

signed charの基本クラスではないcharため、これも当てはまりません。

したがって、 からsigned charへの暗黙的な標準ポインタ変換はchar実行できません。

一方、整数型の値間の変換は、4.7 項で指定されている内容に従って許可されます。

于 2013-02-23T21:57:18.943 に答える
3

C++ には自動ポインター変換がありません。代入の両側のポインター型が何であるかは問題ではありません。それらが異なる場合は、キャストが必要です。

于 2013-02-23T21:55:38.163 に答える
2

charunsigned charは ととは異なるタイプsigned charです。それらの1つと同等の値表現を持つことが保証されているだけですが、それでも異なるタイプです。unsigned char*したがって、 からまたはsigned char*に変換することはできませんchar*(つまり、 a を使用しない限りreinterpret_cast)。C++ では、このような異なる型間のポインター変換は許可されていません。これは、ある型が別の型になりすます可能性があるためです。

ただし、どちらかからunsigned charまたはsigned charcharの変換は、その値の変換のみを含むため、まったく問題ありません。

このように考えてください: を に変換することはできますが、intを に変換するfloatことはできません。int*float*

于 2013-02-23T21:55:51.493 に答える
0

私は間違っているかもしれませんが、上記のように、「C = S; C = U;」を割り当てた場合、「char x = "h"; printf("%i", x );」。ただし、ポインターはメモリ内の特定の場所を指し、その場所にはサイズがあります。そのため、さまざまな角度から値を見るだけの変換では、異なる値を指すと、指している値のサイズを変更する必要がある場合があります。

于 2013-02-23T22:01:13.357 に答える