können Sie absolut sicher einen Zeiger auf ein beliebiges Objekt an eine Funktion wie diese void *
Verwendung übergeben. Das Problem besteht darin, dass Sie etwas mit diesem Objekt machen müssen, sobald Sie in dieser Funktion sind, und Sie müssen den Typ wissen, um dies zu tun, also auch, wenn Sie den Typ nicht benötigen Um einen Zeiger auf das Array zu übergeben, brauchen Sie es auf irgendeine Art und Weise, um die tatsächliche Arbeit erledigen zu können.
Sie können es mit C11-Generika tun, wie eine andere Antwort angibt, aber eine andere Möglichkeit besteht darin, nicht nur einen Zeiger auf das Array, sondern auch einen Zeiger auf den Code, der ausgeführt werden soll, mit einem Funktionszeiger zu übergeben.
Zum Beispiel wird der folgende Code zwei beliebigen numerischen Array zu jedem Element hinzufügen (ich habe es nur für int
, implementiert long
und double
, aber es ist trivial für die übrigen Standard numerischen Typen zu implementieren). Die add_two()
Funktion selbst hat nie eine Vorstellung davon, welche Art von Array es bekommt.Aber um dies zu erreichen, haben Sie es auch auf eine Funktion einen Zeiger übergeben, die tut wissen:
#include <stdio.h>
void add_two(void * array, size_t sz, void (*add_func)(void *, size_t));
void add_two_int(void * array, size_t idx);
void add_two_long(void * array, size_t idx);
void add_two_double(void * array, size_t idx);
int main(void)
{
int n[] = {1, 2, 3, 4, 5};
add_two(n, 5, add_two_int);
for (size_t i = 0; i < 5; ++i) {
printf("%zu: %d\n", i, n[i]);
}
long l[] = {1L, 2L, 3L, 4L, 5L};
add_two(l, 5, add_two_long);
for (size_t i = 0; i < 5; ++i) {
printf("%zu: %ld\n", i, l[i]);
}
double d[] = {1.0, 2.0, 3.0, 4.0, 5.0};
add_two(d, 5, add_two_double);
for (size_t i = 0; i < 5; ++i) {
printf("%zu: %f\n", i, d[i]);
}
return 0;
}
void add_two(void * array, size_t sz, void (*add_func)(void *, size_t))
{
for (size_t i = 0; i < sz; ++i) {
add_func(array, i);
}
}
void add_two_int(void * array, size_t idx)
{
int * n = array;
n[idx] += 2;
}
void add_two_long(void * array, size_t idx)
{
long * l = array;
l[idx] += 2;
}
void add_two_double(void * array, size_t idx)
{
double * d = array;
d[idx] += 2;
}
mit Ausgang:
[email protected]:~/src/sandbox$ ./genarray
0: 3
1: 4
2: 5
3: 6
4: 7
0: 3
1: 4
2: 5
3: 6
4: 7
0: 3.000000
1: 4.000000
2: 5.000000
3: 6.000000
4: 7.000000
[email protected]:~/src/sandbox$
Natürlich in diesem einfachen Beispiel gibt es nicht viel ist in die Art und Weise des echten Nutzen für das Schreiben der add_two()
Funktion im Vergleich zu nur Schreiben add_two_int()
und Freunde und die Verwendung von ihnen direkt. Aber in einem komplexeren Beispiel, in dem Sie zB add_two()
in einer Bibliothek haben möchten, ist dies eine Möglichkeit für Sie, mit beliebigen und neuen Typen umgehen zu können, ohne add_two()
ändern oder Ihre Bibliothek neu erstellen und implementieren zu müssen.
Auch ich habe die Funktion add_two()
benannt, aber es führt offensichtlich nur, was Sie an jedem Element der Reihe nach liefern. So könnten Sie beispielsweise die Funktion subtract_two_int(void * array, size_t idx)
schreiben, diese an add_two()
übergeben, und sie wird tatsächlich zwei von jedem Element subtrahieren, trotz des Namens.
Da Sie den Zeiger in Ihrer Funktion dereferenzieren müssen, warum nicht den richtigen Typ übergeben? Zeigen Sie Ihren Code und geben Sie weitere Informationen an. Entweder ist dies ein XY-Problem, oder Ihre Absicht ist nicht klar. – Olaf
Was ist eine Ordenation? – EOF
Und das ist nicht mit Zeigern verwandt, aber weil C statisch typisiert ist. Der Versuch, generischen Code in C zu schreiben, ist eine sehr schlechte Idee. Verwenden Sie eine dynamisch typisierte Sprache wie Python, wenn Sie möchten. – Olaf