0

我知道网上有很多 c 指针教程,我确实阅读了它们。但是我仍然对指针的某些部分感到困惑。例如,我有一个数组 unsigned char M[10000],现在我想使用指针方式将值存储在数组中,而不是指定索引,我下面的代码有错误。

//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;

使用这些语句,三个不同的指针都将指向同一个内存地址,即字符数组 myArray 开始的地址。但是,如果我们像这样递增这些指针中的每一个:

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

现在,这些指针中的每一个都将包含不同的地址。指针 pmyChar 将包含字符数组 myArray 的第二个元素的地址,因为 pmyChar 是一个 char 指针,就像 myArray 是一个 char 数组一样。

指针 pmyShort 将包含字符数组 myArray 的第三个元素的地址,因为 pmyShort 是一个短指针,一个 short 包含两个字节(每个 char 为一个字节),而 pmyShort 的递增是通过增加包含在指针变量由 short 的大小而不是 char 的大小。

指针 pmyLong 将包含字符数组 myArray 的第五个元素的地址,因为 pmyLong 是一个 long 指针,一个 long 包含四个字节,而 pmyLong 的递增是通过将指针变量中包含的地址增加 a 的大小来完成的长而不是一个字符的大小。

您还可以有一个指向指针的指针,如下所示:

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

最后一条语句的作用是获取 pmyPointerToMyArray 所指向的值,即变量 pmyArray 的地址,然后将该值用作字符的地址来放置字母 K。

于 2012-10-18T02:54:01.933 回答
0

您需要声明一个新指针并将其值分配给 &M 然后增加这个新指针而不是直接增加 &M 。

在 C 中,数组名称是指针,但它的值不能更改。

于 2012-10-18T02:26:49.910 回答
0

您将需要声明一个单独的指针变量,而不是试图操纵M. C 将不允许您M直接分配或修改。

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

除非它是、 或一元运算符的操作数sizeof,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of”类型的表达式将被转换(“decay”)为“指针”类型的表达式,表达式的值将是数组第一个元素的地址。_Alignof&TT

然而...

虽然您可以取消引用生成的指针表达式*(例如,表达式*MM[0]具有相同的类型并产生相同的值),但它可能不是++or--运算符的操作数,也可能不是赋值运算符的目标。所以你不能做类似M++or的事情M += ...

还,

据我了解,当我执行 &M++ 时,我将地址增加到 1 个字节,

不。每当你用 推进一个指针时++,你都会将地址增加指向类型的大小。如果p指向一个char类型,那么是的,p++将前进到下一个char值的地址,也就是下一个字节。如果p指向一个int类型,p++将前进到下一个int值的地址,可能是当前地址的 2、4 甚至 8 个字节,具体取决于平台。

请注意,&M++由于多种原因,这不起作用。一,我已经指出它M可能不是 的操作数++,因为它是一个数组类型。二、 postfix++的优先级高于 unary &,所以表达式被解析为&(M++),结果++不是lvalue,也就是说它本身没有地址,所以不能&对它应用操作符。第三,表达式&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到下一个charap++前进ap到 的下一个1000 元素数组char

于 2012-10-18T03:51:27.237 回答