【问题标题】:Ambiguous behavior while incrementing pointer递增指针时的模棱两可的行为
【发布时间】:2012-10-21 16:50:26
【问题描述】:
#include<stdio.h>
main()
{

        char c = 'R';
        printf("%c\n",c);
        c++;
        printf("%c\n",c);
        char *ptr ="Ramco Systems";
        printf("%c\n",(*ptr));
        (*ptr)++;
        printf("%d\n",(*ptr));

}

第一个、第二个、第三个 printf 的输出是“R”、“S”和“R”(如预期的那样)。但是“(*ptr)++;”这一行给出运行时错误。有人能解释一下为什么吗?

【问题讨论】:

  • 看起来你并没有增加指针。您正在取消引用指针并增加值。
  • 我猜你想用的是 *ptr++ :)
  • 我相信目的是将R 递增到下一个 ansi 字符,因此代码中没有错字 - 只是指针寻址的内存是不可修改的。

标签: c pointers


【解决方案1】:

原因是因为指向ptr的内存是在编译时设置的,不可修改。

因此,通过*ptr 访问第一个字符并返回R,但尝试递增第一个字符会产生运行时错误,因为不允许修改在编译时提供的字符串。

要扩展以下 Seg Fault 的评论,编写代码的更好方法是:

const char *ptr ="Ramco Systems"; //pointer to const char
(*ptr)++; // yields compiletime error because *ptr is a const char

请注意,在这个新代码中,声明的指针类型更准确,因此编译器能够在第二行给出编译时错误(比运行时错误好得多)。

【讨论】:

  • 如果您启用了足够多的警告,那么您的编译器也应该在定义和初始化ptr 时告诉您问题(因为您将指向只读区域的指针分配给一个指向可变的指针)。
  • c 中的字符串文字不是常数..只是不允许更改..您在这里混合了 c 和 c++
  • @Fake.It.Til.U.Make.It 没错,但我建议的方式仍然是编写代码的更好方式,因为它正确地表明了意图并促进了编译时错误,而不是运行时。
【解决方案2】:

char *ptr = "Ramco 系统"

上面的语句变成了指向常量的指针,你试图修改它的无效内容,但是如果你希望编译器在编译时抛出错误,你可以使用/编写如下: const char * ptr = "Ramco 系统"

上述语句的行为方式相同。唯一的区别是当你写 (*ptr)++,你会得到一个编译时错误,比如“修改只读位置”。在手上

【讨论】:

  • 如果你想增加你可以做到的地址,像 ptr++ 这样也有效
【解决方案3】:

(*ptr)++ 应该是*(ptr++)

ptr 指向第一个字符

(*ptr) 返回实际值

(*ptr)++ 是一个错误,因为 (*ptr) 将返回一个 rvalue (在您的情况下为R),它不能被分配也不能增加..另外ptr 指向一个常量(不是const of c++) char 不能更改!

您应该首先增加ptr,然后增加dereference,即*(ptr++)

误解

字符串字面量,如 "xyz",在 C 中总是被视为 char,但不能是 modified。它们是 NOT 声明的如const 或其他人声称的常量。只是不允许更改或未定义

C++中,字符串字面量表示为const char,不能更改

【讨论】:

  • (*ptr)++ 不等于 R++。所以,那部分解释是错误的。 (*ptr) 这里有左值,但由于是字符串文字和只读,不能修改它。
  • R++ 令人困惑。 'R' 没有左值。休息很好。
  • 不,你得到的又是错误的。我说这里的 R++ 解释是错误的。 (*ptr)++ 不等于 R++。正确的第三个语句是 (*ptr)++ 尝试修改不正确的只读字符串文字。
【解决方案4】:

也许你正在尝试做这样的事情?

  #include<stdio.h>
  main()
  {

    char c = 'R';
    printf("%c\n",c);
    c++;
    printf("%c\n",c);
    char aux[] = "Ramco Systems";
    char *p = aux;
    printf("%c\n",(*ptr));
    (*ptr)++;
    printf("%d\n",(*ptr));

}

但请记住,您取消引用的以下行然后递增:

    (*ptr)++;

所以它的行为如下:“我指向哪个字母?好的,将此字母更改为下一个字母(ascii 代码高 1 个单位的字母)”在这种情况下,将 'R' 更改为 'S'。

如果你想要指向'a',你应该这样做:

  ptr++;

通过这样做,您将 ptr 指向的地址加一,传递指向下一个字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多