Zeiger auf Array an Funktion übergeben



  • Hallo Leute,

    ich habe, bevor ich mich dazu entschieden habe hier meine Frage zu posten, schon Google etc. bemüht. Ich habe viele Texte dazu gefunden. Leider kann ich das Problem ohne Hilfe nicht lösen. Ich bin am verzweifeln.

    Ich habe folgendes Problem.

    typedef struct
    {
    	int	var_a;
    	int	var_b;
    
    }datentyp;
    
    main (void)
    {
    
      datentyp array[2] = {{1, 2}, {3, 4}} 
    
      testfunktion(&array[2]);
    
    }
    
    void testfunktion( datentyp* array)
    {
      int ausgabe;
    
      ausgabe = array[2].var_a
    }
    

    Ich habe also ein Array und möchte dieses an eine Funktion übergeben, ohne den kompletten Inhalt kopieren zu müssen. So wie ich das programmiert habe funktioniert es mit "normalen" Variablen. Aber mit Arrays funktioniert es nicht.

    In der Variablen "ausgabe" sollte jetzt eine 3 stehen. Doch da ist jetzt eine 0. Wenn ich statt des zweiten Elementes vom Array das erste ausgeben möchte, klappt es.

    Wo ist mein Denkfehler bzw. wie kann ich das Problem am elegantesten lösen?



  • ...
    testfunktion(array);
    ...
    


  • ...



  • Hallo,

    wieso eine Fangfrage? Ich dachte wenn ich das Array so initialisiere und deklariere, steht folgendes im Array:

    array[1]:
    var_a: 1
    var_b: 2

    array[2]:
    var_a: 3
    var_b: 4

    Wie muss ich denn vorgehen, wenn ich ein Array an eine Funktion übergeben möchte?



  • cpa87 schrieb:

    In der Variablen "ausgabe" sollte jetzt eine 3 stehen.

    Ein Index beginnt bei 0.



  • Oh sorry, Danke für den Hinweis.

    Ich habe das hier im Beispiel falsch geschrieben. In meinem Programm habe ich darauf aber geachtet und bei 0 begonnen.

    Trotzdem funktioniert es nicht.



  • Mit &array[1] würdest du einen Zeiger auf die zweite Struktur übergeben und innerhalb der Funktion kannst du mit dem -> Operator auf die Struktur-Member zugreifen.

    void testfunktion( datentyp* array)
    {
      int ausgabe = array->var_a;
    }
    


  • Genau so hatte ich das am Anfang, aber dort wurde mir dann immer nur 0 ausgegeben.

    Wenn ich aber &array[0] übergebe, dann stimmt der Wert.



  • Na dann versuche es noch einmal und wenns immer noch nicht funzen tut dann poste deinen kompletten, kompilierfähigen Code mit den richtigen Indizes.
    😉



  • Ja, weil es richtig ist.
    Alternativ ginge auch einfach array.
    Der Grund ist der bei diesem Array: foo array[2]; wird intern ein Zeiger erzeugt, der auf einen Speicherbereich zeigt, der 2 foos hintereinander aufnehmen kann.
    Mit array[0] greifst du auf den ersten zu, das wird intern zu *(array+0), aus array[1] wird intern *(array+1).
    Bei der Funktionsübergabe übergibst du die Anfangsandresse, also array.



  • Also ich habe schon alle Varianten durchprobiert.

    typedef struct
    {
    	int			TLC;
    	uint16_t	LaneCrossing;
    
    }CANmsgLKABResult;
    
    int markerLANEside = 1;
    CANmsgLKABResult currLKABMessage[2]		= {{255, 0},{255, 0}};
    
    void ctdCanControl( CCanMessage* canMsg, int newApp )
    {
    
      canMsgToLKABResult(canMsg, newLKABMessage);
      isLKABChanged(newLKABMessage,   currLKABMessage);
      memcpy( &currLKABMessage[RIGHT], &newLKABMessage[RIGHT], sizeof( CANmsgLKABResult ) );
    
      if(idxSignalChanged[NEW_LANE_TLC])
      {
        ctdCtrlLDW(newApp, currLKABMessage[markerLANEside]);
      }
    
    }
    
    void isLKABChanged(CANmsgLKABResult* newLKABMessage, CANmsgLKABResult* currLKABMessage)
    {
      if (newLKABMessage[markerLANEside].TLC != currLKABMessage[markerLANEside].TLC) {idxSignalChanged[NEW_LANE_TLC] = ON;}
    		else idxSignalChanged[NEW_LANE_TLC] = OFF;
    
      if (newLKABMessage[markerLANEside].LaneCrossing != currLKABMessage[markerLANEside].LaneCrossing) {idxSignalChanged[NEW_LANE_CROSSING] = ON;}
    		else idxSignalChanged[NEW_LANE_CROSSING] = OFF;
    }
    
    void ctdCtrlLDW(int app, CANmsgLKABResult* currLKABMessage)
    {
      if (idxSignalChanged[NEW_LANE_TLC])
      {
        if(currLKABMessage[markerLANEside].TLC)
        {
    	drawLDWONlane(app, markerLANEside);
        }
      idxSignalChanged[NEW_LANE_TLC] = OFF;
      }
    }
    


  • cpa87 schrieb:

    Also ich habe schon alle Varianten durchprobiert.

    Dann hätte doch eine funktionieren müssen. 😃
    Du versuchst(?) einen Zeiger zu übergeben, was aufgrund des fehlenden Adressoperators fehlschlägt ( currLKABMessage[markerLANEside] ).
    Wozu willst du einen per Index übergebenen Zeiger innerhalb der Funktion erneut indizieren?



  • Dann hätte doch eine funktionieren müssen.

    Das dachte ich auch 😉

    Hmm, da bin ich mir halt nicht sicher. Also ich habe ja auch schon in Büchern etc. gelesen. Aber es gelten ja andere Vorschriften für normale Variablen als für Arrays. Ich sehe den Wald vor lauter Bäumen nicht mehr.

    Also wo sollte ich das Array denn am besten indizieren? Im Funktionsaufruf oder in der Funktion selbst? Und welche Pointer Arithmetik verwende ich wann?



  • Das hatten wir vor wenigen Minuten, siehe Post 17:26:51 19.02.2013.



  • Und was ist z.B. mit der Funktion memcpy? Ist die denn so richtig?



  • prinzipiell ja



  • Ich habe mein Programm jetzt angepasst. So wie ihr es vorgegeben habt. Es funktioniert trotzdem nur mit der Übergabe array[0].

    Ich verstehe das nicht.

    typedef struct 
    { 
        int         TLC; 
        uint16_t    LaneCrossing; 
    
    }CANmsgLKABResult; 
    
    int markerLANEside = 1; 
    CANmsgLKABResult currLKABMessage[2]     = {{255, 0},{255, 0}}; 
    
    void ctdCanControl( CCanMessage* canMsg, int newApp ) 
    { 
    
      canMsgToLKABResult(canMsg, &newLKABMessage[1]); 
      isLKABChanged(&newLKABMessage[1],   &currLKABMessage[1]); 
      memcpy( &currLKABMessage[1], &newLKABMessage[1], sizeof( CANmsgLKABResult ) ); 
    
      if(idxSignalChanged[NEW_LANE_TLC]) 
      { 
        ctdCtrlLDW(newApp, &currLKABMessage[markerLANEside]); 
      } 
    
    } 
    
    void isLKABChanged(CANmsgLKABResult* newLKABMessage, CANmsgLKABResult* currLKABMessage) 
    { 
      if (newLKABMessage->TLC != currLKABMessage->TLC) {idxSignalChanged[NEW_LANE_TLC] = ON;} 
            else idxSignalChanged[NEW_LANE_TLC] = OFF; 
    
      if (newLKABMessage->LaneCrossing != currLKABMessage->LaneCrossing) {idxSignalChanged[NEW_LANE_CROSSING] = ON;} 
            else idxSignalChanged[NEW_LANE_CROSSING] = OFF; 
    } 
    
    void ctdCtrlLDW(int app, CANmsgLKABResult* currLKABMessage) 
    { 
      if (idxSignalChanged[NEW_LANE_TLC]) 
      { 
        if(20 == currLKABMessage->TLC) 
        { 
          drawLDWONlane(app, markerLANEside); 
        } 
      idxSignalChanged[NEW_LANE_TLC] = OFF; 
      } 
    }
    


  • Wie wäre es, wenn du ein kompilierfähiges Minimalbeispiel min einer main-Funktion programmierst, dass dein Problem beschreibt und es dann postest wenns nicht laufen sollte? Mit deinem Code lässt sich so nicht allzu viel anfangen.



  • ALso ich programmiere es für eien µC (AVR AT90CAN128). Die Ausgabe erfolgt auf einem Display.

    Also das Problem ist, dass in der Funktion "ctdCtrlLDW" der TLC wert nach übergabe 0 ist. Wenn ich "RIGHT" übergebe. Bei "LEFT" kommt der wert an, den ich auch ins Array geschrieben habe.

    /*
     * GccApplication1.c
     *
     * Created: 19.02.2013 19:17:04
     *  Author: cpa87
     */ 
    
    #include <avr/io.h>
    #include <string.h>
    
    #define LEFT = 0;
    #define RIGHT = 1;
    
    typedef struct
    {
    	int			TLC;
    	uint16_t	LaneCrossing;
    
    }CANmsgLKABResult;
    
    void fillArray(CANmsgLKABResult* newLKABMessage);
    void isLKABChanged(CANmsgLKABResult* newLKABMessage, CANmsgLKABResult* currLKABMessage);
    void ctdCtrlLDW( CANmsgLKABResult* currLKABMessage);
    
    CANmsgLKABResult currLKABMessage[2]		= {{255, 0},{255, 0}};
    CANmsgLKABResult newLKABMessage[2]		= {{255, 0},{255, 0}};
    
    int markerLANEside = 3;
    int idxSignalChanged = 0;
    
    int main(void)
    {
        while(1)
        {		
    		markerLANEside = RIGHT;
    
    		fillArray(&newLKABMessage[markerLANEside]);
    
    		isLKABChanged(&newLKABMessage[markerLANEside], &currLKABMessage[markerLANEside]);
    		memcpy( &currLKABMessage[markerLANEside], &newLKABMessage[markerLANEside], sizeof( CANmsgLKABResult ) );
    
    		if (idxSignalChanged)
    		{
    			ctdCtrlLDW(&currLKABMessage[markerLANEside]);
    		}
        }
    }
    
    void fillArray(CANmsgLKABResult* newLKABMessage)
    {
    	newLKABMessage->TLC = 35;
    }
    
    void ctdCtrlLDW( CANmsgLKABResult* currLKABMessage)
    {			
    	if ((RIGHT == markerLANEside) && (50 > (currLKABMessage->TLC)))
    	{		
    		// irgendeine ausgabe
    	}
    }
    
    void isLKABChanged(CANmsgLKABResult* newLKABMessage, CANmsgLKABResult* currLKABMessage)
    {
    	if (newLKABMessage->TLC != currLKABMessage->TLC) {idxSignalChanged = 1;}
    		else {idxSignalChanged = 0;}
    	if (newLKABMessage->LaneCrossing != currLKABMessage->LaneCrossing) {idxSignalChanged = 1;}
    		else {idxSignalChanged = 0;}
    }
    


  • Guck dir mal deine defines an, das ist vermutlich nicht wirklich das, was du möchtest. Ich tippe eher du willst sowas:

    #define LEFT 0
    #define RIGHT 1
    

Anmelden zum Antworten