C++ C++;对于循环/字符指针“;“黑客”;

C++ C++;对于循环/字符指针“;“黑客”;,c++,C++,我有一小段代码可以做一些有趣的事情,但我不知道它是如何做到的 int main(int argc, const char * argv[]) { char text[] = "object"; for(char *ptr = &text[0]; *ptr != '\0'; ptr+=2) { cout << ptr << endl; ptr--; } return 0; } int

我有一小段代码可以做一些有趣的事情,但我不知道它是如何做到的

int main(int argc, const char * argv[])
{
    char text[] = "object";
    for(char *ptr = &text[0]; *ptr != '\0'; ptr+=2) 
    {   
        cout << ptr << endl;
        ptr--;
    }
    return 0;
}
int main(int argc,const char*argv[]
{
字符文本[]=“对象”;
对于(char*ptr=&text[0];*ptr!='\0';ptr+=2)
{   

如果您是对的,通常会打印地址。除了有一个特殊的重载用于
char*
,它将其视为一个C字符串,并输出所有字符,从
ptr
,直到找到零(
\0

…或者,如果您的代码是正确的,则会发生这种情况,因为现在的情况是,它通过在第一次迭代时减少
ptr
ptr
超出范围),然后立即将其增加2来调用UB


如果要显示指针的地址,请将其强制转换为
void*

cout << static_cast<void *>(ptr) << endl;

cout您是对的,通常会打印地址。除了
char*
有一个特殊的重载,它将其视为C字符串并输出所有字符,从
ptr
开始,直到找到零(
\0

…或者,如果您的代码是正确的,则会发生这种情况,因为现在的情况是,它通过在第一次迭代时减少
ptr
ptr
超出范围),然后立即将其增加2来调用UB


如果要显示指针的地址,请将其强制转换为
void*

cout << static_cast<void *>(ptr) << endl;

cout这里没有真正的黑客行为。这里有一个
ostream::operator这里没有真正的黑客行为。这里有一个
ostream::operator这是未定义的行为。第一次迭代,
ptr
指向
对象
。很好,把它打印出来,然后你做
ptr--
。所以现在,
ptr
指向你不再拥有的内存。只要你不去引用它或对它做指针运算,就可以了。但是当你在循环中增加它时-
ptr+=2

为什么会这样:
在第一次迭代中,
ptr
指向
“对象”
,因此它会打印该对象。
cout::operator这是未定义的行为。第一次迭代,
ptr
指向
“对象”
。很好,把它打印出来,然后你做
ptr--
。所以现在,
ptr
指向你不再拥有的内存。只要你不去引用它或对它做指针运算,就可以了。但是当你在循环中增加它时-
ptr+=2

为什么会这样:

在第一次迭代中,
ptr
指向
对象,所以它打印。<运算符:这不是一个黑客。我认为任何C++书籍解释因果关系。@ r.MaTiHHOFNANDEANES不是它未定义的行为吗?@ LuChanGrigor为什么会这样?@第一次迭代后的@ R.M. MtHyHuffNANDES,代码“> Trp/Cuth>在数组开始之前的点1。然后,对它做指针运算。”IGOR你的评论吓唬我。这不是一个黑客。我认为任何C++书籍解释因果关系。@ r.MaTiHHOFFNANDES不是它未定义的行为吗?@鲁奇安格里格尔为什么会这样呢?@第一次迭代后的“.M.MtTiHuffnNeDes”,在开始数组之前,代码> PTR < /CUT> 1。然后你做指针运算。t吓到我了。看看这个:有关运算符的更多信息请看这个:有关运算符的更多信息请看这个:如果我将I强制转换为(int)?我假设你所说的
I
是指
ptr
。如果是这样,那么你将显示一个整数。@user1125518但你为什么要这样做呢?幸运的是,你的指针甚至与int大小不一样。因为程序正在运行UB。(我通常在不清楚原因时评论否决票,但我认为是在这种情况下——至少如果你读过其他答案的话)。@LuchianGrigore我仍然认为否决票有点苛刻。如果我把I投给(int)怎么办?我假设你所说的
I
是指
ptr
。如果是这样,那么你将显示一个整数。@user1125518但你为什么要这样做呢?幸运的是,你的指针甚至与int大小不一样。因为程序正在运行UB。(我通常在不清楚原因时评论反对票,但我认为是在这种情况下——至少如果你读过其他答案的话)@LuchianGrigore我仍然认为对它投反对票有点苛刻。我从来不知道对它进行算术运算是UB,只是取消引用。我想你每天都会学到一些新东西:pAh是的,对不起,我弄乱了代码、更改和文本[0]而且忘了把它设置回1。@克里斯,因为通常你只能在你已经拥有的数组的范围内操作。@LuchianGrigore,没错,我只是从没想过出去再回来会不好。@chris坚持这么久,你会学得非常快。我从来不知道在上面做算术是UB,只是去引用而已。我想你学到了一些每天都有新东西:pAh是的,对不起,我弄乱了代码,更改了&text[0],忘了将其设置回1。@克里斯,因为通常你只能在你已经拥有的数组的范围内操作。@LuchianGrigore,是的,我只是从来没有想过出去和回来是不好的。@chris坚持下去,你会很快学会的。