Große Datenmengen verarbeiten

Gast #3710511
Lesenswert?

Nabend,

ich habe ein Array, bestehend aus 20.000 Messwerten, die ich einer 
Funktion übergeben möchte. Da sich die Funktion in einer anderen 
Übersetzungseinheit befindet, würde ich gern einen Pointer übergen, da 
ich das Array nicht gern global hätte. Die Funktion soll mir 6 Werte 
zurückgeben, auch in ein Array.

Könnte das so funktionieren? Habe weder Buch noch sonst was zur Hand.


1
//main.c
2

3
struct Daten_s{
4
 uint_t Messwerte[50000];
5
 uint_t Rueckgabe[6]
6
};
7

8
Daten_s Daten;
9

10
int main (void)
11
{
12
  ...
13
  Daten.Rueckgabe = foo (&Daten.Messwerte);
14
  ...
15
}
16

17
// Auswertung.c
18

19
uint16_t *p_Rueck foo ( uint16_t *pDaten )
20
{
21
   // *pDaten verarbeiten; 
22
   ...
23

24
   // Rückgabewerte
25
   *p_Rueck->Rueckgabe[0]  = 5
26
   *p_Rueck->Rueckgabe[1]  = 10
27
   ...
28
   *p_Rueck->Rueckgabe[5]  = 30;
29
 
30
}

Danke schonmal



Ingo
Gast #3710576
Lesenswert?

Ich würde das mit einem Ausgabeparameter lösen. Damit spart man sich das 
Allokieren und Freigeb von dynamischen Speicher. Dazu sollten die 
Arraylängen der Funktion mitgeteilt werden um das ganze ein wenig 
robuster zu machen.
1
//main.c
2

3
#define N_MESSWERTE 50000
4
#define N_RUECKGABE 6
5

6
struct Daten_s{
7
 uint_t Messwerte[N_MESSWERTE];
8
 uint_t Rueckgabe[N_RUECKGABE];
9
};
10

11
Daten_s Daten;
12

13
int main (void)
14
{
15
  ...
16
  foo (Daten.Messwerte, N_MESSWERTE, Daten.Rueckgabe, N_RUECKGABE);
17
  ...
18
}
19

20
// Auswertung.c
21
void foo ( uint16_t *pDaten, long nDaten, uint16_t *p_Rueck, long nRueck )
22
{
23
   // *pDaten verarbeiten; 
24
   ...
25

26
   // Rückgabewerte
27
   p_Rueck->Rueckgabe[0]  = 5
28
   p_Rueck->Rueckgabe[1]  = 10
29
   ...
30
   p_Rueck->Rueckgabe[5]  = 30;
31
 
32
}
Gast #3710580
Lesenswert?

Ingo schrieb:
> Habe weder Buch noch sonst was zur Hand.

Auch kein Internet?

Ingo schrieb:
> struct Daten_s{
>  uint_t Messwerte[50000];
>  uint_t Rueckgabe[6]
> };

Wenn du schon eine Struktur hast, warum übergibst du die nicht komplett?
1
void foo ( struct Daten_s *pDaten )

Bist du sicher dass dein Controller genug RAM für das ganze hat?
#3710601
Lesenswert?

1
// Auswertung.h
2

3
typedef struct {
4
 uint_t Messwerte[50000];
5
 uint_t Rueckgabe[6]
6
} Daten_s;
7

8
void foo ( Daten_s *pDaten );
9

10
//main.c
11

12
Daten_s Daten;
13

14
int main (void)
15
{
16
  ...
17
  foo (&Daten);
18
  ...
19
}
20

21
// Auswertung.c
22

23
void foo ( Daten_s *pDaten )
24
{
25
   // *pDaten verarbeiten; 
26
   ...
27

28
   // Rückgabewerte
29
   *pDaten->Rueckgabe[0]  = 5
30
   *pDaten->Rueckgabe[1]  = 10
31
   ...
32
   *pDaten->Rueckgabe[5]  = 30;
33
 
34
}
Gast #3710617
Lesenswert?

Mit einem Pointer auf die Struktur Daten könnte die Funktion direkt in 
das originale Rückgabefeld schreiben. Bei deinem Beispiel wird ein 
Pointer zurückgegeben und soll eine Referenz auf ein Feld überschreiben? 
Nicht wirklich sinnvoll. Sollte p_Rueck nur in der Funktion existieren 
und nicht als static deklariert sein, so sind die Inhalte mit dem 
Beenden der Funktion verloren.

Oftmals eine gute Idee:
Die Struktur in einem Modul mit allen Funktionen die darauf zugreifen. 
Dann kann man die Variable Daten auch als static deklarieren und sie ist 
von außerhalb des Moduls nicht mehr sichtbar.
Bei deinem Beispiel ist es prinzipiell immer noch möglich, von überall 
auf die Variable zuzugreifen.

Wenn ich mich recht erinnere:
In dieser Variante wäre es

struct Daten_s Daten;

um die Variable anzulegen oder

struct Daten_struct{
 uint_t Messwerte[50000];
 uint_t Rueckgabe[6]
} Daten_s;

Daten_s Daten;
Gast #3710627
Lesenswert?

1
#include <vector>
2
#include <cstdint>
3
#include <iostream>
4

5
std::vector<uint16_t> foo (const std::vector<uint16_t>& input) {
6
  // Array aus 6 Zahlen zurückgeben
7
  return { 1, 2, 3, 4, 5, 6 };
8
}
9

10
int main () {
11
  // Eingabearray anlegen...
12
  std::vector<uint16_t> eingabe (50000);
13
  // Array füllen...
14
  for (size_t i = 0; i < eingabe.size (); i++)
15
    eingabe [i] = i;
16
  
17
  // Funktion aufrufen und Rückgabe speichern
18
  auto ausgabe = foo (eingabe);
19
  
20
  // Rückgabe ausgeben
21
  for (uint16_t x : ausgabe) {
22
    std::cout << x << ", ";
23
  }
24
}

Christian H. schrieb:
> Was ist eine Übersetzungseinheit?
Eine Quellcodedatei, auf der man den Compiler aufruft und aus der eine 
Object File erzeugt wird. Die einzelnen Übersetzungseinheiten werden 
seperat kompiliert.
Gast #3710698
Lesenswert?

Kein globales Array ? Bedeutet ein dynamisches Array ? Das wuerd ich 
eher sein lassen. Man sollte sowieso keine dynamischen Variablen 
verwenden. Dh keine mit new() oder getmem() allozierten.
Gast #3710770
Lesenswert?

Weg mit dem Troll. schrieb:
> Kein globales Array ? Bedeutet ein dynamisches Array ? Das wuerd
> ich
> eher sein lassen. Man sollte sowieso keine dynamischen Variablen
> verwenden. Dh keine mit new() oder getmem() allozierten.
getmem()? In Pascal?
Genau, dynamischen Speicher sollte man vermeiden, wer will schon dass 
sein Programm flexibel mit verschiedenen Eingabedaten umgehen kann?!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren