舉個例子:

char* p = "Hello";

p[1] = M; // Undefined behavior

這是不行的。因為這裡的的"Hello"是一個string literal,不可修改(通常創建在.rodata段)。這裡的p指向它,但修改string literials是未定義行為。

再舉個例子:

char a[] = "Hello";

a[1] = M; // OK: a is not a string literal

這是可以的。因為這裡的"Hello"用於初始化一個大小為6的字元數組a,各個元素分別為 H e l l o 。那也就自然能修改它的元素。

想了解更詳細可以看看這個http://en.cppreference.com/w/c/language/string_literal


指針指向不能寫的空間。

用[]會聲明一塊可寫的空間來保存字元串。

也就說這個兩個語法不並等價。



"ABCDEFGH"是字元串字面值,也就是一個字元串常量。char *source = "ABCDEFGH"表示創建了一個指針變數,它指向該字元串常量的首地址,所以從形式上可以用[]來訪問,但它指向的是一個只讀的字元串,所以不能用[]當作左值來進行修改字元串中的值。而char[]創建的是字元串變數,所以可以作為左值進行修改

你指的是

char source[] = "ABCDEFGH";
//和
char *source = "ABCDEFGH";

嗎?

如果是這樣的話,

那麼第一種:

首先,聲明瞭一個char類型的數組,這個數組是編譯器自動分配在棧空間上的,它的長度是sizeof("ABCDEFGH")+1 .然後,將"ABCDEFGH"保存到這個自動分配的區域

第二種:

直接聲明瞭一個指針,然後讓它指向儲存在常量區的"ABCDEFGH"

問題所在就是因為你試圖更改你無法更改的東西.

由題主的問題可知,應該是對於指針和數組的概念有些混淆,確實他們的概念比較相近.

但是純粹意義上的指針只是指向一塊存儲區域的東西,(我們也可以通過sizeof(一個指針)得到:不管指針的類型是什麼樣的,它所佔的內存大小都是一樣的).或者就如大多數c語言書上所講,他就是一個類似於別名的東西.

而數組是不一樣的,數組是有長度不等的存儲空間的,它本身就是存儲了值的.

推薦閱讀:

C程序設計新思維(第2版)-圖書 - 非同步社區

其中第二部分的對於指針的講解我覺得應該能對你有所幫助


沒有調試,看了一下代碼。猜測是這個原因:

解引str相當於一個字元串了(以str為首地址,至 的字元串),不是一個單字元,導致

*str !=

這個表達式恆不成立,變數i一直在加,到後面應該是讀取了非法的內存地址,導致崩潰。

你可以改成

str[i]

這種表達式來試試:)


指針和數組不是一個東西。

好久沒寫過c語言程序了,回答如有誤請指出,以免誤導他人。

回答的幾位說的已經很詳細了。字面值常量是存在常量區的,指針是用來找到這個字面值的地址,從而輸出對應字元串,此時你做指針加減操作地址就飛了,當然常量區的東西是不允許修改的,所以直接報錯了;數組則是存在棧區裏的,分配了的一塊地址,你可以正常做修改行為。

剛開始就這樣記住,後面深入到內存佈局之後應該會更好理解。


推薦閱讀:
相關文章