Forum: Compiler & IDEs Struktur an Funktion übergeben, ändern und wieder zurükgeben


von Michael (Gast)


Lesenswert?

Hallo,

ich stehe im Moment voll auf dem Schlauch.

Ich will an eine Funktion eine mehrdimensionale Funktion übergeben.
In dieser Funktion möchte ich diese sortiern.

Normalerweise wird nur eine Kopie der Funktion übergeben (auf bei 
Zeigern)
und die Änderungen werden nach Beendigung der Funktion verworfen.

Wie bekomme ich die Werte der geänderten Struktur wieder zurück in die
Hauptfunktion ?

Ich möchte ungern ein einfaches Array nutzen, da geht es ohne Probleme.


Michael

von TestX .. (xaos)


Lesenswert?

einfach nen pointer verwenden und gut...

von Sven '. (--j)


Lesenswert?

> Ich möchte ungern ein einfaches Array nutzen, da geht es ohne Probleme.
Ja, warum einfach...
Wie Andi sagte, übergib deiner Funktion einen Zeiger auf die Struktur. 
Da kannste dann drin 'rumsauen wie dir beliebt. Zurück in der 
Hauptfunktion greifst du wiederum auf den referenzierten Speicher zu.

von Michael (Gast)


Lesenswert?

Hallo,

genau das mache ich ja.

Aber ich habe den Fehler gefunden.

main:

// Struktur
struct timer timer_1 [64];

// Funktionsaufruf 1
sort_timer (&timer_1);


// Funktion 1

sort_timer(struct timer *timer_1)

{
// Funktionsaufruf 2
tausch_timer (&timer_1);
}


Ich übergebe die Adresse der Struktur der Funktion1 (per &).
In dieser Funktion rufe ich die Funktion 2 auf und reiche die Struktur 
weiter.Dabe hatte ich wieder den & Operator verwendet.

Ich denke, der muß rauß, weil ich ja schon die Adresse der Struktur 
habe,oder ?

Michael

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Dabe hatte ich wieder den & Operator verwendet.
>
> Ich denke, der muß rauß, weil ich ja schon die Adresse der Struktur
> habe,oder ?

So ist es, es sei denn, "tausch_timer" erwartet einen Pointer auf einen 
Pointer auf die Struktur.

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
struct timer timer_1 [64];

ist in erster Linie ein Array. jedes Arrayelement für sich ist ein 
struct timer Objekt. Aber das spielt erst mal keine Rolle: timer_1 ist 
ein Array.

Und Arrays werden grundsätzlich in C IMMER an eine Funktion übergeben, 
indem die Adresse des ersten Arrayelements (was immer das auch sein mag: 
ein int, ein double oder auch eine Struktur) an die Funktion übergeben 
wird, die sie in einer Pointervariablen auffängt.

Beim Aufruf gibst du nur den Namen des Arrays an und erhältst damit die 
Startadresse des Arrays.

Um das zu verdeutlichen benutzt man gerne eine etwas allgemeine Notation
1
T array[10];
2
3
void foo( T* daten )
4
{
5
  benutze das Array, von dem die Startadresse in daten steht
6
}
7
8
void bar()
9
{
10
  foo( daten );
11
}

Das T steht für irgendeinen Datentyp. Es spielt keine Rolle welcher. T 
kann int sein, kann aber auch long, char oder double sein. Oder auch, 
wie bei dir, ein struct timer

von Matthias L. (Gast)


Lesenswert?

>void foo( T* daten )
>{
>  benutze das Array, von dem die Startadresse in daten steht
>}
>
>void bar()
>{
>  foo( daten );
>}


Und wenn foo nun nicht das gesamte Array, sondern nur ein Element 
bedienen soll, dann doch so, oder?
1
void bar()
2
{
3
  foo( daten[5] );
4
}

von Karl H. (kbuchegg)


Lesenswert?

Matthias Lipinsky schrieb:
>>void foo( T* daten )
>>{
>>  benutze das Array, von dem die Startadresse in daten steht
>>}
>>
>>void bar()
>>{
>>  foo( daten );
>>}
>
>
> Und wenn foo nun nicht das gesamte Array, sondern nur ein Element
> bedienen soll, dann doch so, oder?
>
>
1
> void bar()
2
> {
3
>   foo( daten[5] );
4
> }
5
>

In dem Fall wird dann daten[5] als Kopie an foo übergeben (welche dann 
klarerweise ein T bekommt
1
void foo( T wert )
2
{
3
  mach was
4
}

Bei Strukturen kann das in Ordnung sein, meist übergibt man jedoch einen 
Pointer auf das Strukturelement um sich die oft unnötige Kopie eines 
Strukturelements zu ersparen
1
void foo( T * wert )
2
{
3
  // mach was mit *wert
4
}
5
6
void bar()
7
{
8
  foo( &daten[5] );
9
}

Möchte man zum Ausdruck bringen, dass nur deswegen ein Pointer übergeben 
wird, weil man den Aufrufer nicht dazu zwingen will eine Kopie seiner 
Daten zu erstellen aber ansonsten hat die Funktion nicht die Absicht die 
Daten selbst zu verändern, dann sollte man const benutzen
1
void foo( const T * wert )
2
{
3
  // mach was mit *wert
4
  // aber jeden Versuch hier *wert zu verändern wird
5
  // der Compiler mit einem Error quittieren.
6
  // -> ergo: solange hier nicht wie wild rumgecastet wird
7
  //   hat der Aufrufer die Absicherung, dass sich seine Daten
8
  //   nicht verändern, selbst wenn er einen Pointer darauf
9
  //   herausrückt
10
}
11
12
void bar()
13
{
14
  foo( &daten[5] );
15
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.