Wskaznik do funkcji jako argument innej funkcji

0

1.(Tak jak w temacie) Co bede miec dzieki temu ? wartosc ktora zwraca ? (przeciez nie bd mogl sie odwolac do obiektow znajdujacych sie w funkcji przeslanej jako argument ). Po co to wgl jest ?.

2.(Troszke inne pytanie ) Jezeli mam funkcje w ktorej stworzylem dynamiczna tablice a nastepnie ja zwrocilem . To jak pozniej w mainie moge sie do niej odwolac? Zeby pracowac na tym samych elementach tablicy ? tak w skrocie o takie cos mi chodzi

 
int* funkcja(int rozmiar)
{
   int* tab = new int [rozmiar];
   //cos tam robi na elementach
   return tab
}
int main()
{
int n = 10;
funkcja(n); // Czyli jak moge teraz w mainie posluzyc sie zwrocona tablica raczej nie takie cos funkcja[i] ;D
return 0;
}
6

Używa się w tego m.in. do tzw. callback'ów, czyli funkcji dostarczonych przez programistę, ale wywołanych wtedy gdy jakiś inny kod uzna to za stosowne / będzie tego wymagać.

void qsort(void *base, size_t nmemb, size_t size,
    int (*compar)(const void *, const void *));

Dobrym przykładem jest funkcja qsort z biblioteki standardowej C (oraz C++), która sortuje tablice... w zasadzie czegokolwiek. Aby wykonać sortowanie funkcja musi mieć trzy ogólne informacje - jaka jest wielkość jednego elementu, gdzie tablica danych elementów jest (tj. wskaźnik na nią) oraz ile elementów jest do posortowania. Oprócz tego funkcja musi wiedzieć, mając dwa elementy, który z nich ma być "przed" a który "po" (tj. jaka ma być kolejność tych dwóch elementów w tablicy względem siebie).
No i tu się przydaje callback - programista korzystający z qsort może podać tej funkcji pointer na stworzoną przez siebie funkcje, która rozumie te elementy i umie je porównać, a qsort gdy tylko będzie musieć porównać jakiekolwiek dwa elementy, to wywoła tą dostarczoną przez programistę funkcję.

Inne typowe użycie z C: za pomocą funkcji atexit() "rejestruje się" funkcje, które mają zostać wywołane przy zakończeniu programu. W praktyce atexit bierze od programisty wskaźnik na funkcję i dopisuje go sobie do listy, a przy zakończeniu programu wszystkie funkcje z listy są po kolei wywoływane.

Typowe użycie z C++ (nowego C++): stworzenie wątku; wątek musi "gdzieś się zacząć" - więc podczas tworzenia wątku korzystając z std::thread można podać np. adres funkcji, która ma zostać wykonana przez wątek.

Ad drugie pytanie, np. tak:

int* func(int count) { // lepiej size_t count, ale nie chce mieszać
  if (count <= 0) {
    return nullptr;  // ew w C / starym C++: return NULL;
  }

  int *array = new int[count]; // ew w C: int *array = malloc(count * sizeof(int))
  // W przypadku C tu by się przydało jakieś:
  // if (array == NULL) { 
  //  return NULL; 
  // }
  // C++ domyślnie rzuci wyjątek, ale to temat na inną dyskusję
  for(int i = 0; i < count; i++) {
    array[i] = i;
  }

  return array;
}

int main(void) {
  int *arr = func(5);
  if (arr == nullptr) { // stare C++ / C: if(arr == NULL) {
    for(int i = 0; i < 5; i++) {
      printf("%i: %i\n", i, arr[i]); // ew: std::cout << i << ": " << arr[i] << "\n";
    } 
  }
 
  delete [] arr; // C: free(arr);

  return 0;
}
0
  1. Czyli jak chce zwrocic dynamiczna tablice utworzona w funkcji to przy wywolaniu tej funkcji w mainie musze stworzyc wsk i przypisac deklaracje funkcji ?
    Jest jeszcze jakis inny sposob by zwrocic taka tablice utworzona w innej funkcji ?
2

Ad 1. Tak.

Ad 2. W zasadzie dwa.
Przez wskaźnik ;)

void func(int **p) {
  *p = new int[12];
}

int main() {
  int *p;
  func(&p);
  return 0;
}

(analogicznie można przez referencję)

Ew. przez zmienną globalną, etc. Natomiast użycie zmiennych globalnych warto ograniczać (na pewnym etapie jest z nimi więcej kłopotów niż to jest warte).

0

Dzięki wielkie ! :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1