void reverse(char *str){ int i,j; char temp; for(i=0,j=strlen(str)-1; i<j; i++, j--){ temp = *(str + i); *(str + i) = *(str + j); *(str + j) = temp; printf("%c",*(str + j)); } }
int main (int argc, char const *argv[]) { char *str = "Shiv"; reverse(str); printf("%s",str); return 0; }
当我使用char * str =“Shiv”时,我的反向函数的交换部分中的行,即str [i] = str [j]似乎不起作用,但是如果我将str声明为char str [] =“ Shiv“,交换部分有效吗?这是什么原因。我对这种行为感到有点困惑,当我试图运行该程序时,我不断收到“Bus error”消息。
答案 0 :(得分:16)
当您使用char *str = "Shiv";
时,您不拥有指向的内存,并且您不允许写入它。字符串的实际字节可以是程序代码中的常量。
当你使用char str[] = "Shiv";
时,4(+ 1)个char字节和数组本身就在你的堆栈上,你可以随意给它们写信。
答案 1 :(得分:4)
char * str =“Shiv”获取一个指向字符串常量的指针,该字符串常量可以加载到只读的受保护的内存区域(例如可执行代码的一部分)。
答案 2 :(得分:4)
char *str = "Shiv";
这应该是:
const char *str = "Shiv";
现在你会有错误;)
答案 3 :(得分:1)
尝试
int main (int argc, char const *argv[])
{
char *str = malloc(5*sizeof(char)); //4 chars + '\0'
strcpy(str,"Shiv");
reverse(str);
printf("%s",str);
free(str); //Not needed for such a small example, but to illustrate
return 0;
}
代替。这将使您在使用指针时读/写内存。使用[]表示法直接在堆栈中分配空间,但使用const指针则不会。
答案 4 :(得分:1)
字符串文字是C和C ++中不可修改的对象。尝试修改字符串文字总是会导致未定义的行为。当您使用
获得“总线错误”时,这正是您所观察到的char *str = "Shiv";
变体。在这种情况下,您的“反向”函数将尝试修改字符串文字。因此,行为未定义。
在
char str[] = "Shiv";
variant将在可修改的数组'str'中创建字符串文字的副本,然后'reverse'将对该副本进行操作。这样可以正常工作。
P.S。不要为字符串文字创建非const限定的指针。你的第一个变种应该是
const char *str = "Shiv";
(注意额外的'const')。
答案 5 :(得分:1)
字符串文字(您的“Shiv”)不可修改 您为指针指定了此类字符串文字的地址,然后尝试通过取消引用指针值来更改字符串文字的内容。这是一个很大的NO-NO。
将str声明为数组:
char str[] = "Shiv";
这将str创建为5个字符的数组,复制字符'S','h','i','v'和'\ 0'到str [0],str [1],...,str [4]。 str
的每个元素中的值都是可修改的。
当我想使用指向字符串文字的指针时,我通常会将其声明为const
。这样,当我的代码想要更改字符串文字的内容时,编译器可以通过发出消息来帮助我
const char *str = "Shiv";
想象一下,你可以对整数做同样的事情。
/* Just having fun, this is not C! */
int *ptr = &5; /* address of 5 */
*ptr = 42; /* change 5 to 42 */
printf("5 + 1 is %d\n", *(&5) + 1); /* 6? or 43? :) */
标准引用:
6.4.5字符串文字
...
6 ...如果程序试图修改这样的数组[字符串文字],则行为是未定义的。
答案 6 :(得分:0)
char * str是指向一个字符块(字符串)的指针/引用。但它坐在一块内存中,所以你不能像那样分配它。
答案 7 :(得分:0)
有趣的是我从未注意到这一点。我能够在VS2008 C ++中复制这个条件。
通常,对常量进行就地修改是个坏主意。
无论如何,this post非常清楚地解释了这种情况。
第一个(char [])是您可以编辑的本地数据 (因为数组是本地数据)。
第二个(char *)是一个本地指针 全局,静态(常量)数据。您 不允许修改常量 数据
如果你有GNU C,你可以编译 用-fwritable-strings来保持 全局字符串 不变,但不建议这样做。