C 字符ptr的值在++增量后不会更改

C 字符ptr的值在++增量后不会更改,c,string,pointers,memory,char,C,String,Pointers,Memory,Char,我希望这不是另一个愚蠢的问题: 为什么str指针的值在我增加*str++后没有改变 如果str指针值没有改变,那么每次我执行*str++时,我都应该产生相同的值,而不是l e H 为什么字母l出现在第一位而不是H 顺便说一句,我还研究了&str的值,在我做*str++之前和之后都是一样的 任何帮助都将不胜感激。感谢您通过以下方式调用了未定义的行为: 修改字符串文字。 打印指针而不将其强制转换为void*。 在两个序列点之间多次修改同一对象。 还要注意,函数调用参数的求值顺序是未指定的 调用一个未

我希望这不是另一个愚蠢的问题:

为什么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);
}