我学习这些概念,请帮助我以下代码抛出分段错误的原因。 我在此代码中的意图是打印大写字母 D 并移至下一个地址。请解释一下。谢谢你。
main()
{
char *ptr="C programming";
printf(" %c \n",++*ptr);
}
答案 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()
运营商,您应该只能同时启用其中一条++
行。
请注意,我们声明了ptr
和str
,因为我们无法在阵列上使用++
操作(您无法更改地址数组),因此++str
将获得编译错误,而++ptr
赢了。
(回答你的评论)
您可能还想了解有关指针或地址或数组或Linux进程内存layout_或数据部分的更多信息。 C程序;尝试在Google上搜索,或参考像The C Programming Language, 2nd Edn和The 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
指向的地址设置值。