带字符串的指针算术

t.p*_*der 2 c pointers

我学习这些概念,请帮助我以下代码抛出分段错误的原因.我在这段代码中的意图是打印大写字母D并移到下一个地址.请解释一下.感谢你.

main()
{
    char *ptr="C programming";
    printf(" %c \n",++*ptr);    
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ang 6

您错误的原因

您正在尝试修改字符串文字,这是一个不可修改的对象.这就是你得到分段错误的原因.

即使你只是打电话ptr[0]++,也会出现分段错误.

一种解决方案是将声明更改为:

char ptr[] = "C programming"

然后你可以修改char数组.

他们看起来很相似 是的,字符串文字仍然是不可修改的,但是您声明了一个具有自己空间的数组,该数组将由字符串文字初始化,并且数组存储在堆栈中,因此可以修改.

这是一个完整的代码示例:

#include <stdio.h>

int test() {
    char str[]="C programming";
    char *ptr = str;

    while(*ptr != '\0') {
        // print original char,
        printf("%c \n", *(ptr++));

        // print original char plus 1, but don't change array,
        // printf("%c \n", (*(ptr++))+1);

        // modify char of array to plus 1 first, then print,
        // printf("%c \n", ++(*(ptr++)));
    }

    return 0;
}

int main(int argc, char * argv[]) {
    test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

提示:printf()由于++操作员的缘故,您应该只能同时启用其中一行.

更多提示

注意我们声明了a ptr和a str,因为我们不能++对数组使用操作(你不能改变数组的地址),因此++str会得到编译错误,而++ptr不会.


@Update - 关于记忆

(回答你的评论)

  • 文字串通常被存储在一个过程的只读区域; 参考C字符串文字:它们去哪里了?
  • 一个char数组,如果在方法中声明,那么它在堆栈上分配,因此你可以修改它; 当你从字符串文字初始化一个char数组时,实际上有两个相同值的副本:1是只读的; 1是可修改的; char数组从只读副本初始化.
  • 一个char指针,它存储一个地址; 在这种情况下,指针本身在堆栈上分配,您可以修改它.

您可能还想了解更多关于指针地址数组或Linux进程内存布局_或C程序的数据部分 ; 尝试在Google上搜索,或参考像C编程语言,第二版Linux编程接口这样书籍- 虽然这是关于C而不是Linux的问题.还有The Definitive C Book Guide和 Stack Over Stack上的列表.