2009-10-13 104 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 ...如果該程序試圖修改這樣的陣列[字符串文字],行爲是不確定的。

相關問題