10

理解できない理由でコンパイルできませんが、非常に単純なコードスニペットであると思ったものがあります。

次の簡略化されたコードはコンパイルされません。

char buffer[9] = "12345678";
char* pBuffer = &buffer;

コンパイラ(g ++)は次のエラーをスローします:

error: cannot convert 'char (*)[9]' to 'char*' in initialization

C ++は私の「母国語」ではありませんが、私が見たところどこでも、これでうまくいくはずだと言われています。どんなアイデアやアドバイスも大歓迎です。

4

6 に答える 6

20

配列のアドレスを取得する代わりに、

char buffer[9] = "12345678";
char *pBuffer = buffer;

編集:それはどういう意味ですか?

  • T長さのタイプの配列は、メモリ内のn(連続した) シーケンスです。n T

  • ポインタはメモリアドレスです。

たとえば次のコード

char a[5] = "hello";
char *p = "world";

メモリ内の次の状況に対応します。

配列をポインターと比較します。

あなたのコードでは、配列を作成しました

char buffer[9] = "12345678";

char a[5] = "hello"配列が作成されたのとまったく同じ方法で。上記が配列の最初の文字を指しているようchar *に、配列の最初の文字を指すポインターを作成するつもりです。char *p"world"

「型の配列」型 (ここでbufferは ) の式が使用される場合、常に最初の要素へのポインターに「減衰」します。

1.式はsizeofのオペランドとして使用されます( ではsizeof(buffer)bufferポインターに減衰しません)

2.式は単項 &のオペランドとして使用されます( では&bufferbufferポインターに減衰しません)。

また

3.式は、文字配列の文字列リテラル初期化子です (char someBuffer[3] = "ab"では、文字列リテラル"ab"、配列はポインターに減衰しません)。

これは、標準のセクション 6.2.2.1 に記載されています。

729 sizeof 演算子または単項 & 演算子のオペランドである場合、または配列の初期化に使用される文字列リテラルである場合を除き、"型の配列" 型を持つ式は、型 "型へのポインター" 型を持つ式に変換されます。これは配列オブジェクトの最初の要素を指し、左辺値ではありません。

char *pBufferその結果、配列の最初の文字へのポインターを作成するために必要なことは、書き込むだけです。

char *pBuffer = buffer;
于 2013-01-07T04:43:24.663 に答える
12
  • 宣言により、 charchar buffer[9] = "12345678";の配列が作成されます。 ここで、は最初の要素のアドレスですが、配列のアドレスではありません。 9
    buffer

  • char* pBuffer = buffer;pBufferは、 char へのポインター として正しい式であり、最初の要素をアドレス指定できます。

  • しかし、配列をアドレス指定できないため、式char* pBuffer = &buffer間違っています。pBuffer(コードのエラー、&buffer以下で説明する配列のアドレス)

bufferとの違い&buffer

&buffer配列のアドレスを意味します。とのは実際には同じですが、意味的には両方とも異なります。1 つは文字のアドレスで、もう 1 つは 9 文字の配列のアドレスです。buffer&buffer

buffer[9] = "12345678";


+----+----+----+---+---+----+----+----+---+----+ 
| '1'| '2' |'3'|'4'|'5'| '6'| '7'|'8' | 0 |  ...........
+----+----+----+---+---+----+----+----+---+---+----+  
 201   202  203 204 205 206  207   208 209 210  211
  ^     ^                                         
  |     |                                         
(buffer) (buffer + 1)                                         
|                                         |
|-----------------------------------------|--------
|201                                      | 210
  ^                                          ^
  |                                          |
(&buffer)                                 (&buffer + 1)     

アドレスに 16 進数ではなく 10 進数を使用しました

is の値とbufferis201の値です&buffer201意味は異なります。

  • buffer: 最初の要素のアドレス — その型はchar*.
  • &buffer: 完全な char 配列のアドレス — その型はchar(*)[9].

さらに、違いを観察するには、次を追加し1ます。

buffer + 1それは202 2番目の配列要素のアドレスです'2'が、次の配列のアドレス
&buffer + 1210 どちらですか。

私のシステムでは、次のコードを書きます。

int main(){
   char buffer[9] = "12345678";
   char (*pBuffer)[9] =  &buffer; 

   printf("\n %p, %p\n",buffer, buffer+1);
   printf("\n %p, %p\n",(&buffer), (&buffer+1));
}  

出力は次のとおりです。

0xbfdc0343, 0xbfdc0344

0xbfdc0343, 0xbfdc034c

[答え]

それがエラーの理由です:

エラー: 初期化で 'char ( )[9]' を 'char ' に 変換できません

'char (*)[9]'タイプ値をに割り当てようとしていchar*ます。

  • char (*ptr2)[9]; Here ptr2 is pointer to an array of 9 chars、 And this time
    ptr2=&bufferは有効な式です。

コードを修正するには?

ネイト・チャンドラーの答えのように:

char buffer[9] = "12345678";
char* pBuffer =   buffer;   

または別のアプローチ、

char buffer[9] = "12345678";
char (*pBuffer)[9] =  &buffer;       

どちらを選択するかは、必要なものによって異なります。

于 2013-01-07T09:19:15.477 に答える
4

配列はポインターに減衰します。必要なのは

char* pBuffer = buffer;

またチェックアウト: std::decay

   std::cout << "int[] -> int*; // " << std::boolalpha
              << std::is_same<int *, std::decay<int[]>::type>::value;

出力:

int[] -> int*; // true
于 2013-01-07T04:48:35.627 に答える
2

エラー メッセージは非常に明確です。&bufferchar (*)[9]、つまり、9 つの要素を持つ char の配列へのポインタです (そうです、配列は完全な型です)。

それは と同じではありませんchar*。ただし、配列は必要に応じて最初の要素へのポインターに劣化するため、...

char *pbuffer = buffer;
于 2013-01-07T04:49:02.403 に答える
0

配列の名前はベースアドレスを示しているので、単純に buffer と書くと buffer[0] のアドレスを意味します。&buffer を使用している場合は、char * ではなく char** で取得する必要があります。

そう、

char* pBuffer = buffer;

提案どおりに正しいでしょう。

于 2013-01-07T06:12:34.940 に答える
-1

コンパイラは暗黙的に char( )[] を char に変換できないためです。したがって、明示的な型変換が必要です

char buffer[9] = "12345678";
char* pBuffer = (char*)&buffer;
于 2013-01-07T04:49:11.450 に答える