如果我想遍历一个字符串(在本例中为“ test”),则可以像这样使用指针算法来获取下一个字符:
char *c = "test";
*c++;
putchar(*c);
这将打印第二个字母“ e”。
但是,如果我想转到第三个字符,为什么我不能说:
char *c = "test";
c = *c + 2; //*c = *c + 2; also doesn't work
putchar(*c); //Exception thrown: write access violation.
?
据我所知,使用指针算法获得第三个字符的唯一方法是像这样强制转换:
char *c = "test";
c = (char *) c + 2;
putchar(*c);
有人可以向我解释为什么吗?
答案 0 :(得分:5)
c
是一个指针,用于保存内存位置的地址。
*c
称为取消引用指针,该指针将给出存储在c
所指向的存储位置中的值。
所以
c = *c + 2
将是
c = (value stored at c) + 2;
不会给出类似的存储位置
c = c + 2;
答案 1 :(得分:3)
在第一个示例中,c++;
只是将一个添加到c
中,没有取消引用,那么为什么要在添加2时尝试取消引用?只需在指针值上加2:
char * c = "test";
c = c + 2; //*c = *c + 2; also doesn't work
putchar(*c);//Exception thrown: write access violation.
答案 2 :(得分:2)
您的第一个代码片段是
char * c = "test";
*c++;
putchar(*c);
,正如您所指出的,它会打印e
。但是需要注意的是,在第二行中,*
是完全多余的。您已经递增c
,和提取了指向字符的字符,然后将指向字符扔掉了。
如果您改为说的话,它本来可以完全一样-并且更加清晰,没有令人困惑的额外运算符
char * c = "test";
c++;
putchar(*c);
接下来,您想知道为什么不能将指针增加2。但是,您当然可以 将指针增加2-您可以说
char * c = "test";
c++;
c++;
putchar(*c);
或
char * c = "test";
c += 2;
putchar(*c);
或
char * c = "test";
c = c + 2;
putchar(*c);
但是你写了
c = *c + 2;
那没有用,也就不足为奇了-再次,您有一个不必要的*
,在这里,它并不是那么无害。在这里,您不必要地获取c
所指向的字符,但是您不必将其扔掉,而是向其添加2,,然后尝试将该字符分配给原始指针变量。您的编译器可能对此有所抱怨-将字符分配给指针毫无意义。就像你说的那样
c = 'x';
您似乎不确定*
在C语言中的含义。它不是不是只是一个标记,上面写着“此变量是一个指针”。这是一个运算符,它主动获取指针所指向的值。
无论何时使用指针,都必须牢记指针值与指针所指向的值。
回到您的原始示例时,
char * c = "test";
指针c
的值是“指向字符串的第一个字符的指针”,而指针指向的值是“字符t
”。
如果你说
c++
您增加指针的值。现在它指向字符串的第二个字符,指向的值是字符e
。
如果c
是一个指针,那么每当我在表达式中单独提及c
时,我都是在指指针的值。但是,每当我将运算符*
放在其前面时,我都指的是指针所指向的值。
答案 3 :(得分:0)
让我们理解以下代码:
char * c = "test";
c = *c + 2; //*c = *c + 2; also doesn't work
putchar(*c);//Exception thrown: write access violation.
第一个语句说您有一个字符数组,其起始地址存储在变量c中。 Char作为ASCII值存储在内存中。
第二条语句说,取c所指向的地址中的地址值('e'的ASCII为0x65),然后在其中加2并将其另存为新地址。变量c现在包含0x67。
第三条语句显示打印值作为存储在c中的地址(现在为0x67)。由于我们无权访问此内存位置,因此引发了异常。
您需要增加c指向的内存位置并打印内容。为此,您需要执行以下操作:
char * c = "test";
c = c + 2; //Moves the pointer by 2 bytes
putchar(*c); //Print the character at that memory location