C 带字符串的指针算术

C 带字符串的指针算术,c,pointers,C,Pointers,我正在学习这些概念,请帮助我为什么下面的代码会抛出分段错误。 我在本代码中的意图是打印大写字母D,并移动到下一个地址。请给我解释一下。谢谢你 main() { char *ptr="C programming"; printf(" %c \n",++*ptr); } 假设您试图将C的ascii值增加1,然后打印该值并向前移动指向的字符,您希望使用*ptr+++1这将打印D,然后增加指向下一个字符的指针 #include <stdio.h> main() {

我正在学习这些概念,请帮助我为什么下面的代码会抛出分段错误。 我在本代码中的意图是打印大写字母D,并移动到下一个地址。请给我解释一下。谢谢你

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

假设您试图将
C
的ascii值增加1,然后打印该值并向前移动指向的字符,您希望使用
*ptr+++1
这将打印
D
,然后增加指向下一个字符的指针

#include <stdio.h>

main()
{
    char *ptr="C programming";
    printf(" %c \n",(*ptr++) + 1);    
}
你可以想象一个指针指向任何地方,你给编译器一个选项,把它放在它喜欢的任何地方,所以它会把它放在只读内存中。当您使用数组语法时,它必须在您声明它的地方。

错误原因 您正在尝试修改字符串文字,它是不可修改的对象。 这就是为什么会出现分割错误

即使您只需调用
ptr[0]++
,也将是一个分段错误

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

char ptr[]=“C编程”

然后可以修改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;
}
#包括
int测试(){
char str[]=“C编程”;
char*ptr=str;
而(*ptr!='\0'){
//打印原始字符,
printf(“%c\n”,*(ptr++”);
//打印原始字符加1,但不更改数组,
//printf(“%c\n”,(*(ptr++)+1);
//首先将数组的字符修改为+1,然后打印,
//printf(“%c\n”,++(*(ptr++));
}
返回0;
}
int main(int argc,char*argv[]){
test();
返回0;
}
提示:由于使用了
++
运算符,您应该同时只启用一行
printf()

更多提示 请注意,我们声明了一个
ptr
和一个
str
,因为我们不能对数组使用
++
操作(您不能更改数组的地址),因此
++str
将得到编译错误,而
++ptr
不会


@更新-关于内存 (回答您的评论)

  • 字符串文本通常存储在进程的只读区域中;指
  • 一个字符数组,如果在一个方法中声明,那么它在堆栈上被分配,因此您可以修改它;从字符串文字初始化字符数组时,实际上有两个相同值的副本:1是只读的;1是可修改的;字符数组是从只读副本初始化的
  • 字符指针存储单个地址;在这种情况下,指针本身是在堆栈上分配的,您可以修改它
您可能还想了解更多关于指针、地址、数组、Linux进程内存布局或C程序数据部分的信息;尝试在谷歌上搜索,或者参考像和这样的书——尽管这是一个关于C而不是Linux的问题。还有堆栈溢出

为什么下面的代码抛出分段错误

++*ptr
表示
*ptr=*ptr+1


在C语言中,字符串文字是不可修改的对象。您正在尝试取消对
ptr
的引用,并为
ptr
指向的地址设置值。

ya。。谢谢你。我得到了它。但是我的代码有一个分段错误,因为我试图增加ascii值,如果C,它将给出D,然后移动到下一个地址位置。“你能给我解释一下吗?”王家祥已经解释过了。我不会重复他的回答。你能提供一些材料来澄清这些概念吗。谢谢你。@t.purnaChander有一些非常深入、高级的书,比如[这]()。根据您的经验水平,您可能会发现它有用,也可能不会有用。除此之外,您可以学习汇编程序的基础知识,或者网上可能有文章。我不确定入门c级的书会涵盖这一点。这接近正确答案,但不完全正确。海报上说他想让它在打印前增值。这已经变得有点混乱了。你能给我解释一下这些,ptr[]”和,,*ptr“”。@t.purnaChander我更新了一点答案,但我想你需要使用谷歌或阅读书籍来更好地理解这些概念。@KurtStutsman是的,我明白了,然后需要将printf行更改为
printf(“%c\n”,(*(ptr++)+1);
#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;
}