C 字符ptr的值在++增量后不会更改
我希望这不是另一个愚蠢的问题: 为什么str指针的值在我增加*str++后没有改变 如果str指针值没有改变,那么每次我执行*str++时,我都应该产生相同的值,而不是l e H 为什么字母l出现在第一位而不是H 顺便说一句,我还研究了&str的值,在我做*str++之前和之后都是一样的 任何帮助都将不胜感激。感谢您通过以下方式调用了未定义的行为: 修改字符串文字。 打印指针而不将其强制转换为void*。 在两个序列点之间多次修改同一对象。 还要注意,函数调用参数的求值顺序是未指定的 调用一个未定义的行为是致命的,这意味着从它正常工作到破坏世界的一切都可能发生,您调用了三个: 另见:C 字符ptr的值在++增量后不会更改,c,string,pointers,memory,char,C,String,Pointers,Memory,Char,我希望这不是另一个愚蠢的问题: 为什么str指针的值在我增加*str++后没有改变 如果str指针值没有改变,那么每次我执行*str++时,我都应该产生相同的值,而不是l e H 为什么字母l出现在第一位而不是H 顺便说一句,我还研究了&str的值,在我做*str++之前和之后都是一样的 任何帮助都将不胜感激。感谢您通过以下方式调用了未定义的行为: 修改字符串文字。 打印指针而不将其强制转换为void*。 在两个序列点之间多次修改同一对象。 还要注意,函数调用参数的求值顺序是未指定的 调用一个未
下面是一些代码,如果您学习并编译/运行这些代码,它们将帮助您了解正在发生的事情。注意指针ptr_ucW0的值何时递增
int main(){
char* str="Hello";
// str: 0x4006db, *str++: l, str: 0x4006db, *str++: e, str: 0x4006db, *str++: H
printf("str: %p, *str++: %c, str: %p, *str++: %c, str: %p, *str++: %c\n", str, *str++, str, *str++, str, *str++);
}
C99标准在6.5.2.2、10中规定: 函数指示符的求值顺序、实际参数和 未指定实际参数中的子表达式,但在实际调用之前有一个序列点 事实上,看看我的VC2008产生的汇编程序,++的效果只有在函数调用之前才可见。在参数求值期间,它使用原始str并将++放在一个临时变量中。由于未指定求值顺序,编译器也可以使用另一种策略 例如,正如我在较旧的编译器中观察和使用的那样,参数从右到左求值,从右到左推送到堆栈上,所有中间操作都在左边的参数中可见 但是,由于在函数调用之前有一个序列点,因此在函数调用之前,所有的++操作在str中突然可见
未定义行为的好例子。您有未定义的行为。在str++中,++是后增量。因此,它将*str传递给printf,然后再递增str,它现在将指向下一个字符。参数从右到左进行评估。“我希望这不是另一个愚蠢的问题”-好吧,不幸的是…请告诉你的教授/助教停止发布此类作业,并且在构思这些作业时不要喝龙舌兰酒。这不是一个坏问题,但显然没有对类似问题进行足够的研究。还有一件事,您真的不应该弄乱字符串的基址,在本例中是str。这样做只会导致不好的事情发生。
/*
* 36130330_main.c
*/
#include <stdio.h>
#include <string.h>
unsigned int main
(
unsigned int argc,
unsigned char *arg[]
)
{
unsigned char *str="Hello";
unsigned char *ptr_ucW0;
printf("\n");
printf(" Set ptr_ucW0 = str\n");
ptr_ucW0 = str;
printf(" Text Address Text Value\n");
printf(" str : %p *str : %c\n", str, *str);
printf(" str + 1 : %p *(str + 1) : %c\n", str + 1, *(str + 1));
printf(" str + 2 : %p *(str + 2) : %c\n", str + 2, *(str + 2));
printf(" str + 3 : %p *(str + 3) : %c\n", str + 3, *(str + 3));
printf(" str + 4 : %p *(str + 4) : %c\n", str + 4, *(str + 4));
printf(" str + 5 : %p *(str + 5) : %c\n", str + 5, *(str + 5));
printf(" ptr_ucW0 : %p *ptr_ucW0 : %c\n", ptr_ucW0, *ptr_ucW0);
printf(" ptr_ucW0++: %p *ptr_ucW0++ : %c\n", ptr_ucW0++, *ptr_ucW0++);
printf(" ptr_ucW0 : %p *ptr_ucW0 : %c\n", ptr_ucW0, *ptr_ucW0);
printf(" ptr_ucW0++: %p *ptr_ucW0++ : %c\n", ptr_ucW0++, *ptr_ucW0++);
printf(" ptr_ucW0 : %p *ptr_ucW0 : %c\n", ptr_ucW0, *ptr_ucW0);
printf("\n");
printf(" Reset ptr_ucW0 = str\n");
ptr_ucW0 = str;
printf(" Text Address Text Value\n");
printf(" ptr_ucW0 : %p *ptr_ucW0 : %c\n", ptr_ucW0, *ptr_ucW0);
printf(" ptr_ucW0++: %p *ptr_ucW0 : %c\n", ptr_ucW0++, *ptr_ucW0);
printf(" ptr_ucW0++: %p *ptr_ucW0 : %c\n", ptr_ucW0++, *ptr_ucW0);
printf(" ptr_ucW0++: %p *ptr_ucW0 : %c\n", ptr_ucW0++, *ptr_ucW0);
printf(" ptr_ucW0++: %p *ptr_ucW0 : %c\n", ptr_ucW0++, *ptr_ucW0);
printf(" ptr_ucW0++: %p *ptr_ucW0 : %c\n", ptr_ucW0++, *ptr_ucW0);
}