Ich verwende qsort(), um ein 2D-Array von ganzen Zahlen lexiographisch zu sortieren, wobei jede Zeile eine Eingabe ist, aber Probleme mit Zeigerarithmetik beim Überqueren einer Zeile im Array hat.Sortiere ein Array von ganzen Zahlen lexikografisch
Idee ist, jede Spalte in einer Zeile in eine Zeichenfolge zu verketten, und strcmp
mit anderen Zeichenfolgen, die ähnlich aus anderen Zeilen berechnet werden.
Der Eingang ist nur auf positive ganze Zahlen beschränkt. Einige sortieren Beispiele unten,
{1, 1, 10}
vor {1, 2, 0}
{3, 1, 5}
vor {3, 11, 5}
{1, 19, 2}
vor {1, 2, 1}
#define COL_SIZE 3
int cmp_func (const void *a, const void *b) {
char str1[100], str2[100], temp[10];
int i;
const int **ia = (const int **)a;
const int **ib = (const int **)b;
printf("(a: %p), (b: %p)\n", a, b);
str1[0] = '\0';
str2[0] = '\0';
for (i = 0; i < COL_SIZE; i++) {
printf("(ia+%d: %p), (ib+%d: %p)\n", i, (ia + i), i, (ib + i));
sprintf(temp, "%d", (int)*(ia + i));
strcat(str1, temp);
sprintf(temp, "%d", (int)*(ib + i));
strcat(str2, temp);
}
printf("a: %s, b:%s\n", str1, str2);
return(strcmp(str1, str2));
}
int main (void) {
int i, len;
int A[][COL_SIZE] = {{1,2,3},
{1,1,5},
{1,0,1},
{1,2,1},
{1,2,0}};
len = sizeof(A)/sizeof(A[0]);
printf("sizeof(int): %ld, sizeof(int *): %ld\n", sizeof(int), sizeof(int *));
for (i = 0; i < len; i++) {
printf("Address of A[%d][0]: %p\n", i, A[i]);
}
qsort(A, len, COL_SIZE * sizeof(int *), cmp_func);
return 0;
}
Unterhalb der Ausgang ist:
sizeof(int): 4, sizeof(int *): 8
Address of A[0][0]: 0x7fff58e9fb30
Address of A[1][0]: 0x7fff58e9fb3c
Address of A[2][0]: 0x7fff58e9fb48
Address of A[3][0]: 0x7fff58e9fb54
Address of A[4][0]: 0x7fff58e9fb60
(a: 0x7fff58e9fb30), (b: 0x7fff58e9fb48)
(ia+0: 0x7fff58e9fb30), (ib+0: 0x7fff58e9fb48)
(ia+1: 0x7fff58e9fb38), (ib+1: 0x7fff58e9fb50)
(ia+2: 0x7fff58e9fb40), (ib+2: 0x7fff58e9fb58)
a: 131, b:112
(a: 0x7fff58e9fb48), (b: 0x7fff58e9fb60)
(ia+0: 0x7fff58e9fb48), (ib+0: 0x7fff58e9fb60)
(ia+1: 0x7fff58e9fb50), (ib+1: 0x7fff58e9fb68)
(ia+2: 0x7fff58e9fb58), (ib+2: 0x7fff58e9fb70)
Abort trap: 6
Die Zeigerarithmetik für *(ia + 1)
verursacht die Adresse in jedem Iteration zum Springen um 8 (sizeof(int *))
von 0x7fff58e9fb30
bis 0x7fff58e9fb38
, wobei der nächste Wert in A [0] bei 0x7fff58e9fb34
(Größe von int) gespeichert wird.
Wie kann ich das beheben, so dass ich einen Offset von 4 statt 8 bekommen kann?
Wie möchten Sie das Array sortieren? Nach Zeilen oder nach allen Elementen? –
'int [3]' ist nicht 'int *'. 'qsort (A, len, COL_SIZE * sizeof (int *), cmp_func);' -> 'qsort (A, len, Größevon (* A), cmp_func);' ... – BLUEPIXY
'const int ** ia = (const int **) a; '->' const int * ia = (const int *) a; ' – BLUEPIXY