C語言指標如何實現字串逆序反轉
指標實現字串逆序反轉
#include<stdio.h> #include<string.h> void rec(char* arr) { //int len = sizeof(arr); // 判斷字串長度需要用strlen。 int len = strlen(arr); printf("字串長度len = %dn", len); char* p1 = arr; char* p2 = &arr[len - 1]; while (p1 < p2) { char temp = *p1; *p1 = *p2; *p2 = temp; p1++; p2--; } } int main() { char arr[] = "hello world"; rec(arr); printf("逆序之後輸出為:%sn", arr); system("pause"); return 0; }
知識點
- 判斷字串長度需要用到string.h下的strlen函數方法。
- 演演算法層面:
逆序就是頭尾逐位交換,所以選定兩個指標,一個在首,一個在尾。
指標可以直接比較大小。所以才有了while(p1<p2)來將演演算法執行的終點找到。
- 因為傳入函數方法rec的是地址,所以可以直接修改了原始資料。為了如果為了保護原始資料,需要複製一份另用。
字串逆序的幾種寫法
提示:將字串逆序與將其逆序列印出來是兩碼事,逆序是將內容倒著改變了,逆序列印雖然列印結果也是倒著的,不過儲存字串的陣列內容並沒有改變。
非遞迴寫法
1. 將一個給定的字串abcdef逆序
#include <stdio.h> int main() { char arr[] = "abcdef"; int sz = sizeof(arr) / sizeof(arr[0]); //求的是陣列包含的元素個數,' '也包括在內 int left = 0; int right = sz - 2; //減2是因為求得的sz包含了' '這個元素。 while (left < right) { char tmp = arr[left]; arr[left] = arr[right]; arr[right] = tmp; left++; right--; } printf("%s", arr); return 0; }
列印結果為fedcba。
逆序思路為:將一字串最左端與最右端的字元交換,交換過後,通過陣列下標將左邊第二個字元與右邊第二個字元交換,依次類推,知道陣列下標通過left++與right–,使得left>=right。
2. 自己輸入一串字串,將其逆序
#include <stdio.h> #include <string.h> int main() { char arr[101] = { 0 }; //要給字元陣列一定的記憶體大小,如果寫成char arr[] = { 0 };,當在給陣列輸入的時候就會造成越界存取。 scanf("%s", arr); int sz = strlen(arr); //在給定字元陣列的大小為101的情況下,只能用strlen求輸入字串長度。 //用sizeof(arr)/sizeof(arr[0])求出來的是陣列大小,為101。 int left = 0; int right = sz - 1; while (left < right) { char tmp = arr[left]; arr[left] = arr[right]; arr[right] = tmp; left++; right--; } printf("%s", arr); return 0; }
隨便輸入一串字元,例如:12345gf,列印結果為fg54321。
注意:對於自己給陣列輸入資料,再將其逆序這種情況下,在定義陣列時,要給字元陣列一定的記憶體大小。如果寫成char arr[] = { 0 };,說明這個陣列的容量只有一個位元組,只能輸入一個字元,當在給陣列輸入的時候就會造成越界存取。
3. 將逆序封裝成函數
#include <stdio.h> #include <string.h> void reverse(char arr[]) { int left = 0; int right = strlen(arr) - 1; //封裝成函數只能用庫函數求字串長度,不能用sizeof(arr)/sizeof(arr[0])-1這種方式。 //因為陣列形參就是個地址。sizeof(arr)與sizeof(arr[0])的大小都是四個位元組或者八個位元組。 while (left < right) { char tmp = arr[left]; arr[left] = arr[right]; arr[right] = tmp; left++; right--; } } int main() { char arr[] = "abcdef"; reverse(arr); printf("%s", arr); return 0; }
與sizeof 兩者用來求字串長度時的場合區別。
這裡值得注意的是,在自定義函數中求字串長度時,不要用sizeof(arr)/sizeof(arr[0])-1這種方式。直接使用庫函數 strlen。因為陣列在傳參的時候,傳過去的是陣列首元素的地址,也就是說形參雖說寫的是陣列的形式char arr[],但是形參其實是個指標變數char*。
對於指標變數來說,其大小根據編譯器環境,都是四個位元組或者都是八個位元組。sizeof運運算元就是獲取資料型別和表示式的尺寸的(單位:位元組)。sizeof(arr)與sizeof(arr[0])的大小都是四個位元組或者八個位元組。
所以sizeof(arr)/sizeof(arr[0])-1=4/4-1=0,或者8/8-1=0。
遞迴寫法
1. 方法一
#include <stdio.h> #include <string.h> void reverse(char str[]) //用陣列接收實參,也可用指標接收實參,如void reverse(char* str) { char tmp = *str; int len = strlen(str); *str = *(str + len - 1); *(str + len - 1) = ' '; if (strlen(str + 1) >= 2) //首尾交換後,剩下的元素構成的陣列,長度要大於1,才逆序,只剩下一個元素,表明其是最中間的元素,放在原位就好。 { reverse(str + 1); } *(str + len - 1) = tmp; } int main() { char arr[101] = { 0 }; scanf("%s", arr); reverse(arr); printf("%sn", arr); return 0; }
思路:假設一個陣列有 n 個元素。
交換str[0]與 str[n-1],再逆序 str[1] 與 str[n-2]
交換 str[1] 與 str[n-2],再逆序 str[2] 與 str[n-3]。依次類推
······
操作步驟:
- 1.先將第一個字元,即 str[0] 位置上的字元放在一個臨時變數中。
- 2.將最後一個元素交換到 str[0] 的位置去。
- 3.將字串中的’