2009-10-13 181 views
4
 

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”,交换部分工作?这是什么原因。我对这种行为感到有点困惑,当我试图运行该程序时,我总是收到消息“总线错误”。为什么*(str + i)= *(str + j)在这里不起作用?

+0

元问题...为什么一些在这个问题上有效的答案被否决?它们并不像答案最多的那样完整,但它们也不一定是错的。 – shoover 2009-10-13 20:05:16

回答

16

当您使用char *str = "Shiv";时,您不拥有指向的内存,并且不允许写入它。字符串的实际字节可以是程序代码内的常量。

当您使用char str[] = "Shiv";时,4(+1)个字节和数组本身在您的堆栈中,并且允许您尽可能多地写入它们。

+0

很好的答案,清晰准确。 – 2009-10-13 20:00:14

+0

谢谢,明白了你的观点。 – Shiv 2009-10-14 22:57:06

4

char * str =“Shiv”获取一个指向字符串常量的指针,该字符串常量可以加载到只读内存的受保护区域(例如可执行代码的一部分)。

0

char * str是指向一个字符块(字符串)的指针/引用。但它坐在一块记忆中,所以你不能像这样分配它。

4
char *str = "Shiv"; 

这应该是:

const char *str = "Shiv"; 

现在你将有一个错误;)

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指针不会。

1

字符串文字在C和C++中都是不可修改的对象。尝试修改字符串常量会导致未定义的行为。这正是您在看到“总线错误”时所观察到的情况。

char *str = "Shiv"; 

变体。在这种情况下,你的'reverse'函数会试图修改一个字符串文字。因此,行为是不确定的。

char str[] = "Shiv"; 

变体将创建该串中可修改的阵列“STR”,然后“反向”将在该拷贝操作字面的拷贝。这将工作正常。

P.S.不要创建非常量限定的字符串文字指针。你第一个变体应该是

const char *str = "Shiv"; 

(注意额外的'const')。

0

有趣的是,我从来没有注意到这一点。我能够在VS2008 C++中复制这个条件。

通常,就地修改常量是一个坏主意。

无论如何,this post都很清楚地解释了这种情况。

第一个(char [])是本地数据,您可以编辑 (因为该数组是本地数据)。

第二个(char *)是指向全局静态(常量)数据的本地指针 。您 不允许修改常数 数据。

如果你有GNU C,你可以编译 与-fwritable串保持 全局字符串被制成 不变,但不建议这样做。

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 ...如果该程序试图修改这样的阵列[字符串文字],行为是不确定的。

相关问题