0

私はウェブ上に多くのCポインターチュートリアルがあることを知っており、それらを読みました。ただし、ポインターの一部についてはまだ混乱しています。たとえば、私は unsigned 配列char M[10000]を持っています。今は index を指定する代わりにポインターを使用して配列に値を格納したいのですが、以下のコードにはエラーがあります。

//starting to put value into M[0]
*(char*)&M='1';
//increase the address to M[1]
&M++;
//input value at M[1]
*(char*)&M='a';

私の理解では&M++、アドレスを 1 バイトに増やしていますが、スタンドの場所はどこですM[1]が、エラーがあります。私はcが初めてです、助けてくれてありがとう。

詳細なコード - 更新:

#include <stdio.h>
#include <stdlib.h>

int eax,ebx,ecx,edx,esi,edi,ebp,esp;
unsigned char M[10000];

void exec(void){
    *M= 'a';
    M++ ;
    //append space behind a
    *(char*)&M += ' ' ;
    *(char*)&M += 'b' ;
}

int main() {
    exec();
    print(M);
}

gccとコードブロックを使用しています

4

3 に答える 3

2

配列変数名は、定数ポインターと見なすことができます。ポインターとして扱うことはできますが、変数名の値を変更することはできません。

たとえば、配列を作成し、添字を使用するか、ポインター演算とアスタリスク (*) 記号を使用した逆参照を使用して、配列の要素にアクセスできます。

char myArray[20];    // an array of 20 characters

myArray[2] = 'C';    // assigning a value of the letter C to the third element of the array
*(myArray + 2) = 'K';  // assigning a value of the letter K to third element of the array


char *pmyArray;      // a pointer to one or more characters, not yet initialized though.
pmyArray = myArray;  // assigning the address of the first element of the array to my pointer
*(pmyArray + 2) = 'J';     // assigning a value of the letter J to third character after the character pointed to by pmyArray

ポインタの値はインクリメントできます。例えば:

pmyArray++;    // increment by one position
pmyArray = pmyArray + 1;    // increment by one position
pmyArray += 1;       // increment by one position

ただし、配列名は真のポインター変数ではなく、ポインター定数に似ているため、ポインター変数をインクリメントできる方法で配列名をインクリメントすることはできません。インクリメントされるポインタの良い点は、型の次のメモリ アドレスのアドレスにポインタを移動するために必要なバイト数だけ、実際のアドレスが増加することです。

例えば:

char myArray[48];
char *pmyChar = myArray;
short *pmyShort = (short *)myArray;  // use cast to assign address of array to pointer
long  *pmyLong = (long *)myArray;

これらのステートメントでは、3 つの異なるポインターはすべて同じメモリ アドレス、つまり文字配列 myArray が始まるアドレスを指します。ただし、これらの各ポインターを次のようにインクリメントすると、次のようになります。

pmyChar++;      // increment by one to next character
pmyShort++;     // increment by one to next short
pmyLong++;      // increment by one to next long

これらの各ポインターには、異なるアドレスが含まれるようになります。ポインター pmyChar には、文字配列 myArray の 2 番目の要素のアドレスが含まれます。これは、myArray が char 配列であるのと同様に、pmyChar が char ポインターであるためです。

ポインター pmyShort は、文字配列 myArray の 3 番目の要素のアドレスを含みます。これは、pmyShort が short ポインターであり、short には 2 バイト (各 char は 1 バイト) が含まれ、pmyShort のインクリメントは、配列に含まれるアドレスを増やすことによって行われるためです。 char のサイズではなく、short のサイズによるポインタ変数。

ポインター pmyLong には、文字配列 myArray の 5 番目の要素のアドレスが含まれます。これは、pmyLong が long ポインターであり、long には 4 バイトが含まれているためです。 long であり、char のサイズではありません。

次のようなポインタへのポインタを持つこともできます。

char myArray[48];
char *pmyArray;
char **pmyPointerToMyArray;

pmyArray = myArray;                 // pointer to myArray
pmyPointerToMyArray = &pmyArray;    // address of pointer to myArray

次に、次のようなことができます。

pmyArray++;   // increment to second element of myArray
*(pmyArray) = 'J';  // set the second element of myArray to letter J
*(*pmyPointerToMyArray) = 'K';  // set the second element of myArray to letter K

この最後のステートメントが行うことは、変数 pmyArray のアドレスである pmyPointerToMyArray が指す値を取得し、その値を文字 K を配置する文字のアドレスとして使用することです。

于 2012-10-18T02:54:01.933 に答える
0

新しいポインターを宣言し、その値を &M に割り当ててから、&M を直接増やすのではなく、この新しいポインターを増やす必要があります。

C配列では名前はポインタですが、その値は変更できません。

于 2012-10-18T02:26:49.910 に答える
0

を操作しようとするのではなく、別のポインター変数を宣言する必要がありますMMC では、直接割り当てたり変更したりすることはできません。

char M[1000];
char *p = M; // or &M[0]
...
*p++ = 'a';  // M[0] = 'a'
*p++ = 'b';  // M[1] = 'b'

sizeof_Alignof、または単項演算子のオペランドである場合、または&宣言で別の配列を初期化するために使用される文字列リテラルである場合を除いて、型 "N 要素配列 " のTは変換 ("decay") されます。タイプ「ポインター」の式Tであり、式の値は配列の最初の要素のアドレスになります。

でも...

結果のポインター式を逆参照することはできますが*(たとえば、式*MandM[0]は同じ型を持ち、同じ値を生成します)、それは++or--演算子のオペランドではない可能性があり、代入演算子のターゲットではない可能性があります。M++したがって、またはのようなことはできませんM += ...

また、

私の理解では、&M++ を実行すると、アドレスが 1 バイトに増えます。

いいえ。 でポインターを進めるときはいつでも、ポイント先の型のサイズ++だけアドレスを増やします。型を指している場合、yesは、次のバイトである次の値のアドレスに進みます。型を指している場合は、プラットフォームに応じて、現在のアドレスから 2、4、または 8 バイト の次の値のアドレスに進みます。pcharp++charpintp++int

&M++いくつかの理由で機能しないことに注意してください。1 つ目は、 は配列型であるためM、 のオペランドではない可能性があることを既に指摘しました。++2 つ目は、 postfix++は unary よりも優先順位が高い&ため、式は として解析され&(M++)、 の結果は++lvalue&はありません。つまり、アドレスそのものがないため、演算子を適用できません。3 つ目は、この式は、個々の ではなく、()の配列&Mのポインターを生成します。次の宣言を想定します。charchar (*)[1000]char

char *p = M;
char (*ap)[1000] = &M;

p++;  // points to M[1];
ap++; // points to the char following M[999];

p++p次へ進みcharます。 の次の1000 要素配列にap++進みます。 apchar

于 2012-10-18T03:51:27.237 に答える