《C 和指針》的一道練習題,為什麼 char * 會導致程序崩潰?
舉個例子:
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語言程序了,回答如有誤請指出,以免誤導他人。
回答的幾位說的已經很詳細了。字面值常量是存在常量區的,指針是用來找到這個字面值的地址,從而輸出對應字元串,此時你做指針加減操作地址就飛了,當然常量區的東西是不允許修改的,所以直接報錯了;數組則是存在棧區裏的,分配了的一塊地址,你可以正常做修改行為。
剛開始就這樣記住,後面深入到內存佈局之後應該會更好理解。
推薦閱讀: