我一直在用 C 撰寫一個簡單的庫來處理陣列、動態陣列和鏈表。作為一個起點,我一直在研究一個從陣列中彈出用戶定義索引的函式。對于初學者,我正在處理一個整數陣列并找到了這個解決方案。
int pop_int_array(int *array, int index, int size) {
int type = sizeof(int);
if (index >= size) return 0;
unsigned char *dst = (unsigned char*) array index type;
memmove(dst, dst type, type * (size - index - 1));
return 1;
}
int main(int argc, const char * argv[]) {
int a[5] = {1, 2, 3, 4, 5};
pop_int_array(a, 2, 5);
for (int i = 0; i < 4; i ) {
printf("%d\n", a[i]);
}
}
這會按預期產生以下輸出
1
2
4
5
如果我想彈出一個float陣列,我需要創建一個新函式,標題為pop_float_array從其中復制所有內容,pop_int_array但不是使用,而是int type = sizeof(int)將其替換為int type = sizeof(float),當然陣列資料型別將是 afloat而不是int. 然而,這違反了軟體開發的核心原則,多次重復相同的代碼,每次都是資料型別的實作。為了解決這個問題,我以以下方式重寫了函式,其中陣列被宣告為void資料型別。此外,在將陣列void *傳遞給函式之前或程序中,我將陣列轉換為主程式中的 a 。
int pop_array(void *array, int index, int size, int type) {
if (index >= size) return 0;
unsigned char *dst = (unsigned char*) array index type;
memmove(dst, dst type, type * (size - index - 1));
return 1;
}
int main(int argc, const char * argv[]) {
int a[5] = {1, 2, 3, 4, 5};
pop_array((void *)a, 2, 5);
for (int i = 0; i < 4; i ) {
printf("%d\n", a[i]);
}
float b[5] = {1.1, 2.2, 3.3, 4.4, 5.5};
pop_array((void *)a, 2, 5);
for (int i = 0; i < 4; i ) {
printf("%f\n", a[i]);
}
}
正如預期的那樣,這會產生
1
2
4
5
1.1
2.2
4.4
5.5
這使我只能創建和維護一個功能。然而,這似乎很簡單,以至于我很驚訝它不是一種更廣泛使用的技術,或者至少我在我的小經驗中意識到了這一點。void *撰寫函式 this 或將陣列轉換為我看不到的函式是否有一些后果,或者這是在 C 中使函式型別不可知的合法方法?
uj5u.com熱心網友回復:
你這樣做的方式很好。但是你確實有一個錯誤:
unsigned char *dst = (unsigned char*) array index type;
你沒有上升到適當的數量。這應該是:
unsigned char *dst = (unsigned char*) array (index * type);
void *此外,呼叫函式時不需要強制轉換為:
pop_array(a, 2, 5, sizeof(int));
該技術用于qsort可以對任意型別的陣列進行排序的函式中。它的簽名如下:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
與您的函式一樣,它需要 avoid *到陣列的開頭以及元素的數量和每個元素的大小。它還需要一個函式指標,其作業是執行特定型別的比較。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/484857.html
上一篇:嘗試在MacOS上運行Kivy應用程式,但運行時出現黑屏
下一篇:查找一維子陣列是否在二維陣列中
