Forum: PC-Programmierung Brauche mal hilfe bei ner Pointer Sache


von Mike M. (mikeii)


Lesenswert?

Ich habe hier einen Code bei dem voll der Wurm drin ist.

Es gibt ein 2D Array, das an eine Funktion per Pointer weiter gegeben 
werden soll und dort verändert wird.

Nur mal schnell die "Idee"
1
void funktion(int **array)
2
{
3
4
  //Mache irgendwas mit dem Array
5
  array[1][1] = 2;
6
7
}
8
9
10
11
main()
12
{
13
14
  int array[2][2];
15
  //Array wird hier mit irgendwelchen Zahlen befüllt
16
  funktion(array);
17
18
}


Sollte das vom Prinzip her nicht so funktionieren?

Der Name von dem Array ist doch die Adresse auf das erste Element, oder?
Und wenn ich die Anfangsadresse habe, kann ich doch nach dem übergeben 
damit wieder so arbeiten??

von Karl H. (kbuchegg)


Lesenswert?

Mike Mike schrieb:

> void funktion(int **array)

Das ist kein 2D Array.
Das ist ein 1D Array von Pointern, bei dem jeder Pointer wieder auf ein 
1D Array von Daten zeigt

Also sowas

   array
   +----+
   | o  |
   +-|--+
     |
     v
   +-----+                 +---+---+---+---+
   |  o------------------->|   |   |   |   |
   +-----+                 +---+---+---+---+
   |  o--------------+
   +-----+           |     +---+---+---+---+---+
   |  o-------+      +---->|   |   |   |   |   |
   +-----+    |            +---+---+---+---+---+
              |
              v
              +---+---+---+
              |   |   |   |
              +---+---+---+


>   int array[2][2];

Das hingegen ist ein echtes 2D Array. Also sowas

    array
    +---+---+
    |   |   |
    +---+---+
    |   |   |
    +---+---+

und das ist etwas ganz anderes.

> Und wenn ich die Anfangsadresse habe, kann ich doch nach dem übergeben
> damit wieder so arbeiten??

Aber das ganze Speicherlayout ist vollkommen anders.
Nur weil du auf ein int** syntaxmässig gleich wie auf ein echtes 2D 
Array zugreifen kannst, bedeutet das nicht, dass hinter einem int** ein 
echtes 2D Array steckt.


void funktion(int array[2][2])

von Mike M. (mikeii)


Lesenswert?

Danke, hatte ich auch gerade überlegt.

Folgendes ist also zu tun


void funktion(int *array)
{

  //Mache irgendwas mit dem Array
  array[x*2+y]; = 2;   //2 ist die größe

}

von Arc N. (arc)


Lesenswert?

Mike Mike schrieb:
> Danke, hatte ich auch gerade überlegt.
>
> Folgendes ist also zu tun
>
>
> void funktion(int *array)
> {
>
>   //Mache irgendwas mit dem Array
>   array[x*2+y]; = 2;   //2 ist die größe
>
> }

Kommt drauf an...
Vorziehen würde ich das schon vorgeschlagene "void funktion(int 
array[2][2])" wenn die Größen feststehen oder, je nach Anwendung, die 
Variante bei der bis auf die erste Dimension alle anderen angegeben 
werden
1
 
2
void f(int size1, int a[][2][3][4]) ...
oder wenn der Compiler C99 bzw. VLAs kennt z.B.
1
void f(int y, int x, int array[y][x * 7]) ...

Ansonsten
http://c-faq.com/aryptr/ary2dfunc3.html inkl. des schönen Tests 
http://c-faq.com/aryptr/aryptr.c

von Rolf Magnus (Gast)


Lesenswert?

Arc Net schrieb:
> Vorziehen würde ich das schon vorgeschlagene "void funktion(int
> array[2][2])" wenn die Größen feststehen oder, je nach Anwendung, die
> Variante bei der bis auf die erste Dimension alle anderen angegeben
> werden

Ob die erste Dimension angegeben wird oder nicht, spielt überhaupt keine 
Rolle. Der Compiler ignoriert das sowieos.

von Arc N. (arc)


Lesenswert?

Rolf Magnus schrieb:
> Ob die erste Dimension angegeben wird oder nicht, spielt überhaupt keine
> Rolle. Der Compiler ignoriert das sowieos.

In C, ja, in C++ ginge auch so was
1
void funktion(int (&array)[2][2])...

von Dima S. (onkelbenz)


Lesenswert?

2 dimensionale arrays kanns am besten als char** vorstellen

z.B. wenn du parameter übernimmst mit char** argv, dann hast du unter
*argv[0] die adresse vom ersten element des ersten arrays (d.h. duch 
cout << *argv[0] bekommst "name" als ausgabe) und unter **argv[2][2] 
hast den buchstaben 'a'
wieso? --> weil es so aussieht
[n]|[p]|...|[p]
[a]|[a]|...|[a]
[m]|[r]|...|[r]
[e]|[a]|...|[a]
   |[m]|...|[m]
   |[1]|...|[n]

d.h. durch die erste reihe besteht aus pointern auf das erste element 
des jeweiligen arrays, und du kannst darüber iteriren wie in jedem array 
(z.B. cout << **argv[1][1+3] wird 'a' ausgeben

D.h. wenn du in int** array auf die stelle [2][2] zugreifen wilst, dann 
brauchst du 2 mal dereffenzierten zugriff **array[2][2]

Das ist aber nicht das Hauproblem bei arrays aus pointern - das 
wirkliche Problem liegt in der Speicherreservierung ... wenn du 
versuchst mit malloc & co. dynamisch speicher dafür zu verwalten, wirst 
einfach nur verrückt. Und wenn du die größe im vorfeld kennst, oder 
kannst es zumindest begrenzen und dann auf maximum setzen, dann benutzt 
keine pointer arrays.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Dima Schmitt schrieb:
> 2 dimensionale arrays kanns am besten als char** vorstellen

sinns abba net

von Karl H. (kbuchegg)


Lesenswert?

Dima Schmitt schrieb:
> 2 dimensionale arrays kanns am besten als char** vorstellen

und dabei hab ich weiter oben eine so schöne Zeichnung gemacht.
Nein: 2d Arrays kann man sich nicht als char** vorstellen.

Und für den Rest deiner Ausführungen: Da sind dir ein paar Pointer 
Dereferenzierungen und Indexoperationen durcheinander gekommen. Das ist 
alles falsch.


(Es bringt nix, wenn du du einem Anfänger Unsinn erzählst. Das müssen 
dann andere erst wieder mühsam auseinanderklamüsern und richtigstellen)



> wenn du versuchst mit malloc & co. dynamisch speicher dafür
> zu verwalten, wirst einfach nur verrückt.
Das spricht Bände.

von Udo S. (urschmitt)


Lesenswert?

Karl Heinz Buchegger schrieb:
> und dabei hab ich weiter oben eine so schöne Zeichnung gemacht.
Da gibst du dir so eine Riesenmühe (Hut ab!) und dann kommt da so ein 
Besserwisserkobold und verwirrt mit seinem Blödsinn die Anfänger.
Heul

von Simon K. (simon) Benutzerseite


Lesenswert?

Dabei steht die Antwort in der ersten Antwort in der letzten Zeile. 
Unfassbar ;-)

von Heinz L. (ducttape)


Lesenswert?

Simon K. schrieb:
> Dabei steht die Antwort in der ersten Antwort in der letzten Zeile.
> Unfassbar ;-)

nö, ganz normal. Da C++ flexibel genug ist um für so ziemlich jedes 
Problem 100 Wege zum Ziel zu haben gibt's auch entsprechend immer das 
Hickhack welcher denn nun der vergoldete ist. Wenn ich mir anguck was in 
einigen C++-Foren so an Flamewars abgeht (insbesondere im 
"Philosophiebereich Vererbung"), da sind das fünf Sekunden von das war 
noch gar nix. :)

von Simon K. (simon) Benutzerseite


Lesenswert?

Ich kenne das. Programmiere regelmäßig in C++ Desktop Applikationen und 
häufig in C Mikrocontroller.
Dabei schreibe ich fast lieber in C. Ganz einfach weil man da nicht so 
viele Möglichkeiten hat irgendwas (falsch) zu machen.
In C++ hat man immer viele Wege, die man gehen kann. Entscheidet man 
sich für einen, bereut man es unter Umständen später beim Erweitern um 
eine bestimmte Funktionalität.
Von daher muss man in C++ gewissermaßen einen großen Erfahrungsschatz 
haben und abschätzen können, was für jeden bestimmten Einsatzfall die 
"beste" Realisierung einer Funktionalität ist.

Wie auch immer, ich glaube nicht, dass hier in C++ programmiert wird, 
sondern in C. Und da ist die von Karl Heinz in der 1. Antwort genannten 
Lösung die "eigentlich Richtige".

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.