據我所知,當我們創建一個陣列或字串時,它們的名字是指向它們的第一個元素的指標。在這種情況下,指標無法更改。
但是,這段代碼有效:
#include <stdio.h>
void swapString(char **str1_ptr, char **str2_ptr)
{
char *temp = *str1_ptr;
*str1_ptr = *str2_ptr;
*str2_ptr = temp;
}
int main()
{
char strings[][30] = {"Test1","Test2","Test3"};
int i;
swapString((char **)&strings[0],(char **)&strings[1]);
for(i=0;i<3;i ){
printf("%s\n",strings[i]);
}
return 0;
}
為什么這行得通?以這種方式交換字串(或一般的陣列)是一個好習慣嗎?當使用這種方法不是一個好主意時?
uj5u.com熱心網友回復:
為什么這行得通?
它不好用。它似乎運行良好,因為您對編譯器撒謊并使用了不足的測驗資料。
void swapString(char **str1_ptr, char **str2_ptr)
{
char *temp = *str1_ptr;
*str1_ptr = *str2_ptr;
*str2_ptr = temp;
}
您聲稱提供指向指標的指標。因此,該函式在兩個位置之間交換與指標所占用的位元組一樣多的位元組。在大多數系統上是 4 或 8 個位元組。
但是然后你傳遞陣列的地址,而不是指向指標的指標:
char strings[][30] = {"Test1","Test2","Test3"};
swapString((char **)&strings[0],(char **)&strings[1]);
這導致未定義的行為。您正在使用強制轉換,因為您的編譯器告訴您,如果您洗掉它們,這將是螃蟹:
test.c:15:28: warning: passing argument 2 of ‘swapString’ from incompatible pointer type [-Wincompatible-pointer-types]
15 | swapString(&strings[0],&strings[1]);
| ^~~~~~~~~~~
| |
| char (*)[30]
test.c:3:41: note: expected ‘char **’ but argument is of type ‘char (*)[30]’
結果,該函式認為它交換了一個指標,但它交換了陣列的前 8 個位元組。
要驗證這一點,您可以使用更長的字串:
#include <stdio.h>
void swapString(char **str1_ptr, char **str2_ptr)
{
char *temp = *str1_ptr;
*str1_ptr = *str2_ptr;
*str2_ptr = temp;
}
int main()
{
char strings[][30] = {"Test111111","Test222222","Test333333"};
int i;
swapString((char **)&strings[0],(char **)&strings[1]);
for(i=0;i<3;i ){
printf("%s\n",strings[i]);
}
return 0;
}
然后你會得到你應得的結果。;)
Test$ ./test
Test222211
Test111122
Test333333
如果是 32 位地址,您需要區分字串的前 4 個位元組。
如您所見,根本沒有交換指標。只是你的陣列的開頭搞砸了。
如果只想通過交換指標來交換字串,則需要更改陣列定義:
char *strings[] = {"Test111111","Test222222","Test333333"};
swapString(&strings[0],&strings[1]);
作為副作用,您還可以從函式呼叫中洗掉強制轉換,因為型別現在與預期匹配。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/314969.html
上一篇:C將char陣列傳遞給函式和指標
