如果我們使用下標符號而不是*(pt+i)
來重寫函數,可能會更容易看到問題。
void sort_strlen(char (*pt)[81]){
char (*temp)[81];
int i, j;
for(i = 0; i < 10 && pt[i] != NULL; i++)
for(j = i + 1; j < 10 && pt[j] != NULL; j++)
if(strlen(pt[i]) < strlen(pt[j])){
temp = pt[i];
pt[i] = pt[j];
pt[j] = temp;
}
for(i = 0; i < 10 && pt[i] != NULL; i++)
puts(pt[i]);
}
所以,當你想換pt[i]
和pt[j]
,首先你嘗試指派char*
(這是該char[81]
pt[i]
自動轉換這裏)向char(*)[81]
在temp = pt[i];
線。
類型不兼容性應在此處明確。但通常,這只是一個警告,並且「按預期工作」,因爲pt[i]
被轉換爲該字符串中第一個字節的地址,該字符串也是數組pt[i]
的地址。如果通過分配&pt[i]
或pt + i
來調整右側的類型,該警告將消失。
錯誤在下一行。在pt[i] = pt[j];
行中,嘗試將char*
分配給char[81]
,並在pt[j] = temp;
行中嘗試將char(*)[81]
分配給char[81]
。
數組是不可轉讓的,所以寫
pt[i] = ...
始終是一個錯誤。不幸的是,海灣合作委員會的報告,截至
sort_strlen.c:13:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char *’
sort_strlen.c:14:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char (*)[81]’
,而不是更直接指向根源
sort_strlen.c:13:18: error: array type 'char [81]' is not assignable
*(pt + i) = *(pt + j);
~~~~~~~~~^
sort_strlen.c:14:18: error: array type 'char [81]' is not assignable
*(pt + j) = temp;
~~~~~~~~~^
那鏗鏘發出。 gcc報告主要是不可修復的「不兼容類型」,因爲沒有類型在右側與賦值左側的數組類型兼容。
I solved the problem by creating an array of pointers. I wanted to sort the strings directly by changing their addresses inside the array. Does anybody knows if it possible ? What is the best way to do it ?
這取決於你想要做什麼。你不能改變字符串的地址不走動字符串本身,你會做的,例如與
char temp[81];
...
strcpy(temp, pt[i]);
strcpy(pt[i], pt[j]);
strcpy(pt[j], temp);
如果您不希望移動琴絃,你的確會最好創建一個數組指針
char *strings[10];
for(int i = 0; i < 10; ++i) {
strings[i] = pt[i]; // make it &pt[i][0] if you don't like the implicit conversion
}
和strings
陣列由字符串長度排序的:
char *temp;
...
if (strlen(strings[i]) < strlen(strings[j])) {
temp = strings[i];
strings[i] = strings[j];
strings[j] = temp;
}
到數組的指針的使用是在慣用的C編程趨於零罕見。你的最終目標是什麼? –
@CarlNorum謝謝,函數向上的目的是按照它們的長度對字符串數組進行排序。在檢查存儲在「*(pt + i)」指向的地址處的字符串是否大於後面的字符串(「*(pt + j)」)後,我想交換兩個指針指向的地址至。但是,gcc不接受它。我只能通過添加指向char的指針數組來解決問題,我在這裏存儲每個字符串的地址,然後在該數組內交換地址。有沒有更好的方式來完成這項工作? – colibrisson
歡迎來到SO。除了通過評論(如@JonathanWood建議)指出導致錯誤的那一行外,最好的問題是那些刪除了任何不需要的代碼來引起錯誤的問題。即使錯誤發生在三條線上,但如果錯誤是一樣的,那麼縮小到一個實例通常足以自己修復其餘的錯誤。有關此策略的更多信息,請參閱:[sscce.org](http://sscce.org/) – HostileFork