12

ポインタがどのように機能するかを理解したいので、この小さなプログラムを作成しました。まず、charを指すapポインタを作成します。

最初の質問はこの時点です。ポインタを作成する場合、その値はメモリアドレスです(非ポインタオブジェクトを指す場合)が、今回は私の例では「はは」です。なぜchar*でこのように機能するのですか?そして、どうすればcin >> pでそれに価値を加えることができますか?

2番目の質問は、aq charを作成したことです。これは、作成した時点での*pポインターの値を持っています。しかし、その値とアドレスも「h」ですが、なぜですか?このcharオブジェクトのメモリアドレスである必要があります。それは無意味です:D(mingw --gcc)

#include <iostream>

int main() 
{
 /* char *p;
    cin >> p;                      //forexample: haha */

    char * p = "haha";
    char q = *p;
    std::cout << "&q = " << &q << std::endl;   //&q = h
    std::cout << "q  = " <<  q << std::endl;   //q = h

    return 0;
}

詳細:最初にchara[100]を使用してメモリを割り当てた場合。char * p = a; 次に&q = h»ŢĹなので、「h」といくつかの混乱。しかし、それはメモリアドレスでなければなりません!そして私の質問は、なぜそれがその時対処されないのかということです。

4

5 に答える 5

12

char* p;メモリ内のアドレスと考えてください。このポインタを初期化していないため、何も指していません。使用できません。

常に安全を期すために
:ポインタをゼロに初期化する:

char *p = 0; // nullptr in C++11

または自動に初期化する

void foo() {
  char a[100];
  char *p = a;
}

またはグローバルメモリ:

char a[100];
void foo() {
  char *p = a;
}

または動的メモリを取得します。

char* p = new char [100];

次に、p(NULLでない場合)を使用してデータを読み取り、pから読み取ることができます...


の誤解のためにoperator >> (std::istream&, char* p)pこの演算子は、それが何らかのメモリ(自動、グローバル、動的-関係なく)を指していることを期待します-それ自体ではメモリを割り当てません。入力ストリームから空白まで文字を読み取り、p-が指すメモリにコピーしますが、pすでに何らかのメモリを指している必要があります。


のアドレスを取るためchar q;。もちろん、あなたはq:のアドレスを取ることができます&q、そしてそれはタイプですchar* p。ただし、&qとは異なりp、これは、がq=*p指す最初の文字をコピーするだけで、のアドレスを変更pするqことはできませqん。そのアドレスは変更できません。For-はNULLで終了する文字列を指すことを期待しますcout << &q-そしてメモリを指しますが、この文字の後には誰も知らないので、画面にゴミが表示されます。1文字を印刷するために使用します。operator << (ostream&, char* p)p&q"H"cout << q

于 2012-10-13T21:31:27.127 に答える
3

ポインタについて最初に学び、常に覚えておくべきことは、ポインタにメモリを割り当てることです。そうしないと、プログラムが正しく実行されません。

「cin」がユーザー入力を割り当てられたメモリに書き込めるように、コードを実際に次のように変更してメモリを割り当てる必要があります。

int main() {
    char *p = new char[1024];      // allocate memory so cin
    cin >> p;                      //forexample: haha
    char q = *p;
    cout << "&q = " << &q << endl; 
    cout << "q = " << q << endl;   
    return 0;
}

ここで、文字ポインタは、文字セットを保持するメモリ内の位置を指す変数です(必ずしも1文字ではなく、複数の場合もありますが、特殊値nullの場合のように、文字なしの場合もあります)。文字変数は実際には保持されます。単一の文字(文字のセットではありません)。

ポインタを扱うときの基本的な演算子は、&(のアドレス)と*(の値)です。&は変数のアドレスを取得するため、[char q;]がある場合、[&q]は文字ポインターになります。一方、*は指定されたポインタの値を取得するため、[char * p;]がある場合、[*p]はpが指しているメモリ内の文字になります。

ここで例に戻り、説明のためにインラインでコメントします

int main() {
    // allocate a place of 1024 character in memory
    // and let p points to that place
    char *p = new char[1024];      

    // call cin to read input from the user and save
    // it in memory at the location pointed to by p
    // NOTE: cin would put an extra NULL character 
    // at the end to terminate the string
    cin >> p;                      //forexample: haha

    // Now p would be pointing to a piece of memory like this
    // [h] [a] [h] [a] [\0]

    // use the value at operator to de-reference the pointer
    // p, the result would be a single character which 
    // will be the first character in memory p is pointing at
    char q = *p;

    // printing the value of (the address of q)
    // Note you have a problem here as cout will
    // be handling the memory starting at the address 
    // of q as a string while it is not, so you
    // will get a string starting with "h" and followed
    // by whatever is there in memory by the time of execution
    cout << "&q = " << &q << endl;

    // printing the value of the character q
    cout << "q = " << q << endl; 
    return 0;
}

お役に立てば幸いです

于 2012-10-13T21:46:12.727 に答える
1

次のようなものが必要です。

#include <iostream>
using namespace std;

プログラムの上部にあります。または、とを省略して、とusingを参照することもできます。std::cinstd::cout

int main() {
    char *p;

pはポインタですが、初期化していないため、どこを指していても、どこを指していなくてもかまいません。たとえば、次のように初期化する必要があります。

p = new char[100];

..。

    cin >> p;                      //forexample: haha

これは、どこを指すように初期化した場合は問題ありません。pただし、入力するデータが多すぎる場合は、指すバッファをオーバーフローさせることができます。このような単純なテストプログラムでは問題ありませんが、実際には、それを回避するための対策を講じる必要があります。

    char q = *p;
    cout << "&q = " << &q << endl; //&q = h

&qタイプchar*は、へのポインタcharです。char*に値を送信してcoutも、ポインタの値(メモリアドレス)は出力されません。指している文字列を出力します。(自分で実行すると奇妙な結果が得られますが、何かが足りない可能性があります。)ポインター値を確認したい場合は、次のようにキャストしますvoid*

count << "&q = " << (void*)&q << endl;

(または、C ++固有のキャストの1つを使用することもできます。どちらが最適かはわかりません。)

    cout << "q = " << q << endl;   //q = h

qこれは単なるchar、なので、これはその値を文字として出力します:h

    return 0;
}
于 2012-10-13T21:45:32.167 に答える
0

文字列literateは.rdataセクションに格納され、読み取り専用になるため、stdcinを使用して文字列を読み取るとプログラムがクラッシュします。

あなたがこれを書くとき、2番目のこと:

char *p = "some text";

次に、ポインタpは、割り当てられた読み取り専用メモリを指します。これは、rdataセクションがWindowsローダーによって確実に割り当てられて準備されるためですが、前述したように、.rdataは変更できません。

次に、これを書くとき:

char q = *p;

*はポインタが現在指している値を返すため、pの最初の文字にのみqを割り当てます。これを試した場合:

++p;
q = *p;

ポインタは最初の文字から始まるいくつかの文字を指すアドレスであるため、qは「a」ではなく「a」を保持します。したがって、1を増やすと、ポインタは2番目の文字を指し、qはこの値を保持します。

于 2018-07-21T08:15:10.070 に答える
0

それを行うためのより良い方法は次のとおりです。

    int arraySize;
    cin>>arraySize;
    char *a=new char[arraySize];
    cin >> a;
于 2018-10-09T11:13:17.470 に答える