使用字符串

时间:2016-02-17 04:57:13

标签: c pointers

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

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

4 个答案:

答案 0 :(得分: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;
}

提示:由于printf()运营商,您应该只能同时启用其中一条++行。

更多提示

请注意,我们声明了ptrstr,因为我们无法在阵列上使用++操作(您无法更改地址数组),因此++str将获得编译错误,而++ptr赢了。

@Update - 关于内存

(回答你的评论)

  • 字符串文字通常存储在进程的只读区域中;参考C string literals: Where do they go?
  • char数组,如果在方法中声明,则在堆栈上分配,因此您可以修改它;当你从字符串文字初始化一个char数组时,实际上有两个相同值的副本:1是只读的; 1是可修改的; char数组从只读副本初始化。
  • 字符指针它存储单个地址;在这种情况下,指针本身在堆栈上分配,你可以修改它。

您可能还想了解有关指针地址数组或Linux进程内存layout_或数据部分的更多信息。 C程序;尝试在Google上搜索,或参考像The C Programming Language, 2nd EdnThe Linux Programming Interface这样的书籍 - 虽然这是关于C而不是Linux的问题。 Stack Overflow上还有The Definitive C Book Guide and List

答案 1 :(得分:3)

这将打印D然后将指针递增到下一个字符。

#include <stdio.h>

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

您不能在内存中增加字符值,因为它是字符文字,因此很可能存储在二进制可执行文件的数据部分中。它是只读的,任何改变它的尝试都会导致不确定的行为(段错误可能是~100%的时间)。

你应养成宣称这些文字const的习惯。事实上,如果启用了任何额外级别的警告,c ++将为您提供支持。

上面的代码是有效的,因为它不会改变内存,只是为了传递给printf而将值加1。

另一种选择是使用数组语法而不是指针语法,您声明字符串在堆栈上,因此它是可写的。

为此,语法为

char ptr[]="C programming";

你可以想到指向任何地方的指针,你给编译器一个选项,把它放在任何地方,所以它把它放在只读存储器中。当您使用数组语法时,必须在那里声明它。

答案 2 :(得分:0)

假设您尝试将C的ascii值递增1并打印并将指向前移的字符移动,则需要使用*ptr++ + 1

答案 3 :(得分:0)

  

以下代码导致分段错误的原因

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

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