質問

#include <cstring>
int main()
    {
    char *pName = new char[10];
    char dummy[] = "dummy";
    strcpy(pName + 0,dummy);//how this is different from -->this works
    strcpy(pName[0],dummy);//this one...--> error C2664: 'strcpy' : 
                           //cannot convert parameter 1 
                           //from 'char' to 'char *'

    }
役に立ちましたか?

解決

  • pname [0]は文字配列の最初の要素です(1 キャラクター)
  • pnameは&pname [0](アレイの最初の要素へのポインタ)へのショートカットです。

エラーが発生している理由は、STRCPYがCHAR(char *)へのポインタを想定し、CHAR値ではなく(PNAME [0]がある)からです。

他のヒント

CまたはC ++でポインタや配列を扱うとき、それは非常に異なる構成要素としてそれらを認識するのに役立ちます(私はこの区別を説明する最高の本の1つは、正しく "深いC秘密と呼ばれる本である本が"です)。どんな泥だらし、アレイ名からポインタへの配列名(言語の変数名の取り扱いの矛盾)の一連のサイレント変換があるという事実ですが、暗黙のうちにこの崩壊現象の存在を解釈しないことは非常に重要です。等価。

これについての理由を助けるために、「メモリセル」のアイデアを紹介しましょう。 2つの属性を持つものとして「メモリセル」をモデル化します。

a) value
b) address

その後、2つの属性を持つものとして単純なC ++変数をモデル化できます(この低レベルの抽象化で型は必要ありません)。

c) name  
d) memory cell

ほとんどのモデルと同様に、それはいくつかの欠陥を持っています(複数の要素を持つ配列を扱わないが、私たちの目的には十分です)。

たとえば:

// non-array variable: name 'i', and memory cell: value=3, address=0x0A
int i = 3;

// non-array variable: name 'p', and memory cell: value=0x0A, address=0x0B
int *p = &i;

// array variable: name 'a', and memory cell: vale=4, address=0x0C     
int a[1] = { 4 };

// non-array variable: name 'b', and memory cell: value=0x0C, address = 0x0D
int (*b)[1] = &a;

// non-array variable: name 's', and memory cell: value=0x0C, address = 0x0E
int *s = &a[0];


// non-array variable: name 't', and memory cell: value=0x0C, address = 0x0F
int *t = a; // Here is the key difference! read on...

これが、配列変数と非配列(ポインタ)C ++変数の主な違いです。

C ++の変数名が評価されると、常に1つの例外を持つメモリセルの値と評価されます。変数が配列変数に名前を付けている場合。
変数がそれが評価される配列の名前である場合 住所 メモリセルの。
上記の2行は再び読む価値があります。

その意味を明確にするのを助けるためのいくつかの例(上記の変数を参照):

int k = i;  // the 'i' name evaluates to the value of its cell, so 'k' is set to 3

int *q = p; // 'p' evaluates to the value of its cell, so 'q' is set to 0x0A

int *r = a; // 'a' evaluates to the *address* of its cell, so 'r' is set to 0x0C

int (*c)[1] = b; // 'c' is set to 0x0D

これは決して配列変数が 同じ ポインタ変数として。
彼らは本質的に異なる種類とそれらを扱う試みを持っています 同じ (つまり、変数名を1つの翻訳単位で配列として定義し、別の翻訳単位で定義します)は悪いことが起こります。

たとえば、これをしないでください。

// MyProj_file1.cpp int配列[100] = {0}; //ここで '配列'は、最初のメモリセル// myproj_file2.cpp extern int *配列の*アドレス*に評価されます。 //ここで '配列'は、リンカが2つの//をリンクしていると仮定して、アセンブリを読んだ場合、このようなものは次のようなものです.// Extern Int * Array =(int *)配列[0]; //しかしそれは必要ではありません、それは動作が未定義であるので何でもすることができます

これが助けを願っています。それでもさらなる説明が役立つかもしれないと感じているならば、フォローアップの質問をしてください、そしてその「Library?」のコピー(ライブラリ?)を手に入れることはありません。

--
PS関数の種類とその名前とその崩壊は、この記事のほとんどには無関係です
PS iは、配列が参照型にバインドされているときに配列からポインタへの変換が行われないことを意図的に省略しています。

技術的には strcpy(pName[0], dummy); 正しくありません。メモリが割り当てられていても。

それの訳は pName[0] 「char」型です pName + 0 char *の型です。それらは両方とも同じメモリを参照しますが、さまざまな方法で。

コンパイラは次にターンすることができます strcpy(pName[0], dummy); の中へ strcpy((char*) pName[0], dummy); それは危険な暗黙のキャストです。あなたのコンパイラが半分類の場合は、警告またはエラーが発生します(「エラーC2664」で見ているように)。

違いはありません。 PNAME用のスペースを割り当てないため、それらは両方のクラッシュします。 :)[編集:クラッシュはもうありません - 質問が編集されました

主な違いは、周囲のコードが書き込まれている方法に適合するものです。

(編集:ブライアンのボンディーが指摘されたように、本当に&pname [0]を意味すると仮定する。)

配列は単に自動的に割り当てられたメモリブロックに割り当てられたポインタです。あなたの例を取ると、次のようにも同様にダミーを宣言することができます。

char    dummy[] = "dummy";
char    *dummy = "dummy";

また、Array SyntaxまたはPointerの構文を使用してデータにアクセスすることができます。

char    ch = dummy[0];   // get the first element of the array
char    ch = *dummy;     // get the data pointed to by dummy

両方 []* DE再基準ポインタと配列を使用することができますので、次のようになります。

array[N];
*(ptr + N);

2番目のフォームを考えると、 (ptr + N) それでも配列に沿ってさらにポインタです。これがあなたの例で構文的に正しい理由です。 ptr[N] ポインタを参照し、char(このコンテキストで)です。

pName は、新しく割り当てられたメモリへのポインタです。 char *pName = new char[10];

dummy も配列/ポインターです。 char dummy[] = "dummy";

pName はポインタであり、ベース アドレスを指します。(pName + 0) を追加しても、0 を追加するだけなので、同じメモリ位置を指します。 strcpy(pName + 0,dummy);

strcpyはポインタ変数を使用し、最初の引数に値を渡すため、エラーが発生します strcpy(pName[0],dummy)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top