0

みんな私はポインタにいくつかのクエリがあります。親切にそれらを解決するのを手伝ってください

char a[]="this is an array of characters"; // declaration type 1 
char *b="this is an array of characters";//  declaration type 2

question.1:これら2種類の宣言の違いは何ですか?

    printf("%s",*b); // gives a segmentation fault
    printf("%s",b); // displays the string

質問2:どのように機能するのかわかりませんでした

    char *d=malloc(sizeof(char)); // 1)
    scanf("%s",d); // 2)
    printf("%s",d);// 3)

question.3ポインタcに割り当てられているバイト数は?文字列を入力しようとすると、文字列全体ではなく単語だけが必要になります。なぜそうなのか ?

    char c=malloc(sizeof(char)); // 4)
    scanf("%c",c); // 5)
    printf("%c",c);// 6)

question.4文字を入力しようとすると、なぜセグメンテーション違反が発生するのですか?

よろしくお願いします。

4

5 に答える 5

2
printf("%s",*b); // gives a segmentation fault
printf("%s",b); // displays the string

%sは、charの配列へのポインタを想定しています。

char *c=malloc(sizeof(char)); // you are allocating only 1 byte aka char, not array of char!
scanf("%s",c); // you need pass a pointer to array, not a pointer to char
printf("%s",c);// you are printing a array of chars, but you are sending a char

あなたはこれをする必要があります:

int sizeofstring = 200; // max size of buffer
char *c = malloc(sizeof(char))*sizeofstring; //almost equals to declare char c[200]
scanf("%s",c);
printf("%s",c);

question.3ポインタcに割り当てられているバイト数は?文字列を入力しようとすると、文字列全体ではなく単語だけが必要になります。なぜそうなのか ?

あなたのコードでは、sizeof(char)= 1byte = 8bitであるため、1バイトしか割り当てていません。sizeof(char)* Nを割り当てる必要があります。ただし、Nは「文字列」サイズです。

于 2012-11-22T21:19:49.683 に答える
1

コードにいくつかの問題があります。

質問1:違いは次のとおりです。

  • a書き込み可能なメモリ、いわゆるdataセグメントに割り当てられます。ここでは、好きなだけ読み書きできます。sizeof a文字列の長さに1を加えたもの、いわゆる文字列ターミネータ(単なるヌルバイト)です。
  • bただし、は、にある文字列へのポインタにすぎませんrodata。つまり、読み取り専用のデータ領域にあります。sizeof bシステムのポインタサイズは何でもかまいません。PCの場合は4または8、多くの組み込みシステムの場合は2です。

質問2:printf()フォーマットは文字列へのポインタを必要とします。を使用*bして、使用しているポインタを逆参照し、データの最初のバイトt(ASCII 84など)を指定します。ただし、呼び出し先はそれをポインターとして扱い、それとBAMを逆参照します。

ただし、を使用bすると、正確に正しい呼び出しであるため、すべてがうまくいきます。

質問3:malloc(sizeof(char))正確に1バイトを割り当てます。sizeof(char)1定義上、呼び出しは事実上malloc(1)です。%sそのように定義されているため、入力は単語を取ります。

質問4:

char c=malloc(sizeof(char)); // 4)

shoundはあなたに警告を与えます:malloc()あなたが入れようとしているポインタを返しますchar。ITYM char *..。

続行すると、そのポインタをに与えます。これは、たとえば、単なるscanf()の代わりに、それをポインタとして解釈し、再びBAMを受け取ります。0x800432140x14

正しい方法は

char * c=malloc(1024);
scanf("%1024s", c);
printf("%s", c);

なんで?さて、あなたは文字列を読みたいです。1バイトが小さすぎるので、より多く割り当ててください。

ではscanf()、バッファが保持できる以上の読み取りを許可しないように注意する必要があります。したがって、フォーマット指定子の制限があります。

%sまた、印刷時には、最初の文字だけでなく文字列全体を印刷するため、を使用する必要があります。(少なくとも、そうだと思います。)

于 2012-11-22T21:18:51.433 に答える
1
char a[]="this is an array of characters"; // declaration type 1 
char *b="this is an array of characters";//  declaration type 2

ここでは、2 つの変数 と を宣言しabそれらを初期化しています。"this is an array of characters"文字列リテラルであり、C では char 型の配列を持ちます。achar の型配列を持ちます。この特定のケースでは、配列はポインターに変換されず、a配列で初期化され"this is an array of characters"ます。bchar へのポインター型を持ち、配列はポインターに変換され、配列へのポインターでb初期化されます"this is an array of characters"

printf("%s",*b); // gives a segmentation fault
printf("%s",b); // displays the string

式で*bは、ポインターを逆参照するbため、 が指す文字b、つまり:に評価されますT。これはアドレスではない ("%s" が期待するもの) ため、未定義の動作が発生し、おそらくクラッシュします (ただし、組み込みシステムでこれを実行しようとしないでください。不思議な動作や破損したデータが発生する可能性があります。クラッシュよりも悪い)。2 番目のケースで%sは、char へのポインタを期待して取得し、処理を続行できます。

char *d=malloc(sizeof(char)); // 1)
scanf("%s",d); // 2)
printf("%s",d);// 3)

C ではsizeof、オブジェクト (= ストレージの領域) のサイズをバイト単位で返します。C では、char はバイトと同じであると定義されており、少なくとも 8 ビットを持ちますが、それ以上のビットを持つこともできます (ただし、いくつかの標準では、追加の制限があります。たとえば、POSIX では 8 ビット バイトが必要です。したがって、1バイトを割り当てています。を呼び出すとscanf()、 が指すメモリdに制限なく書き込み、目に見えるすべてのものを上書きします。scanf()最大フィールド幅を許可するため、次のようになります。

  • 少なくとも必要なもの + 1 終了 ASCII NUL に十分な、より多くのメモリを割り当てます。
  • 停止scanf()するように指示します。たとえばscanf("%19s")、最大 19 文字 (終了する ASCII NUL を数えて、それを格納するには 20 バイトが必要です)。

そして最後に(マークダウンが許せば):

char c=malloc(sizeof(char)); // 4)
scanf("%c",c); // 5)
printf("%c",c);// 6)

cはポインターではないため、アドレスを格納すべきではない場所に格納しようとしています。ではscanf"%c"指定されたフィールド幅 (デフォルトでは 1) に十分なスペースを持つオブジェクト (= ストレージの領域) を指す必要がある char へのポインターが必要です。はポインターではないためc、上記は一部のプラットフォームでクラッシュする可能性があります (他のプラットフォームではさらに悪い結果を引き起こします)。

于 2012-11-22T22:26:46.170 に答える
0

広告Q1:1つ目は、それを指す 固定ポインターを持つ文字の配列です。sizeof(a)20()のようなものを返しますstrlen(a)+1a = baが修正されているため、(のような)に何かを割り当てようとすると失敗します。

2つ目は、charの配列を指すポインターであるため、sizeof(b)は通常32ビットでは4、64ビットでは8です。ポインタは新しい値を取ることができるので、bに何かを割り当てることは機能します。

もちろん、*aまたは*bは両方で機能します。

広告Q2:printf()%s引数を使用すると、charへのポインターを取得します(これらはCの「文字列」です)。したがって、printf("%s", *b)printf()で使用される「ポインタ」には* bのバイト値が含まれるため、クラッシュします。

できることはですがprintf("%c", *b)、それでは最初の文字しか印刷されません。

Ad Q3:sizeof(char)は(定義上)1であるため、1バイトを割り当てます。scanfは、ほとんどの場合、複数のバイトを読み取ります(各文字列は、1文字を占めるヌル文字で終了することに注意してください)。したがって、scanfはメモリを破棄し、後でメモリを発生させる可能性があります。

広告4:たぶんそれはゴミ箱の記憶です。

于 2012-11-22T21:29:59.763 に答える
-1

両方の宣言は同じです。bは最初のバイトを指すので、*bと言うと最初の文字になります。printf( "%s"、* b)%sは文字列へのポインタを受け入れるため、失敗します。charは1バイトです。

于 2012-11-22T21:16:31.697 に答える