Forum: Mikrocontroller und Digitale Elektronik C - Übergabe und Verwendung Tabelle


von Dietmar P. (dietmar2)


Lesenswert?

Hallo,

für Anzeige eines Textes in einem Display (funktioniert mit Atmega32 mit 
der Funktion lcd_string bereits)
möchte ich Texte in einer Tabelle (array) definieren und über einen 
Index eine Zeile im Display anzeigen.

Ziele war die Anzeige mit

lcd_string (obj[i]);

Probiert habe ich:
1
main
2
.
3
.
4
  char obj[3][10] = {" "};  // Definition Tabelle Objekte
5
.
6
.
7
  initobj (&obj)                // Übergabe Tabelle für init
8
.
9
  printf ("%s \n", obj[1]);     // Test einer Zeile
10
11
//Ende main
12
13
01 // initobj                  // Initialisieren der Tabelle
14
.
15
05 void initobj(char *pobj) 
16
.
17
12    char *pobj[3][10] = {
18
13      "Zeile 1",
19
14      "Zeile 2",
20
15      "Zeile 3"
21
16            }
22
17 //Ende initobj

Fehler:

initobj.c:12:10: Fehler: »pobj« als andere Symbolart redeklariert
initobj.c:5:20: Anmerkung: Vorherige Definition von »pobj« war hier

Habe es auf dem PC probiert und kriege es nicht hin.
Bitte um einen Tipp von den C-Profis wie man das richtig macht.

Danke, Gruß

von Noname (Gast)


Lesenswert?

Naja. Der Compiler wundert (sic) sich warum Du einen Parameter noch 
einmal als lokale Variable deklarierst.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Dietmar P. schrieb:
> char *pobj[3][10] = {
> 13      "Zeile 1",
> 14      "Zeile 2",
> 15      "Zeile 3"
> 16            }


Einfach nur pobj so definieren:

char *pobj[] = { "Zeile 1", "Zeile 2", "Zeile 3", NULL };

zB dann ausdrucken:

int i;
for ( i=0; pobj[i] != NULL; i++)
  printf( pobj[i]);

von Karl H. (kbuchegg)


Lesenswert?

Viel einfacher als du denkst
1
  char obj[3][10] = {
2
    "Zeile 1",
3
    "Zeile 2",
4
    "Zeile 3"
5
  };

die ganze Funktion "initobj" brauchst du gar nicht.

von Dietmar P. (dietmar2)


Lesenswert?

OK,

danke für Eure Anregungen, werde einmal weiter testen mit Euren 
Hinweisen.

Gruß

von Dietmar P. (dietmar2)


Lesenswert?

Hallo,

muss doch nochmals um Hilfe bitten.

Habe die Tabelle im main definiert, ist ok.

Der Zugriff darauf soll allerdings in einem Unterprogramm erfolgen und 
das gelingt mir nicht.

Meine bereitsbestehende Anwendung ist schon umfangreich und 
strukturiert, sodass ich die Verarbeitung der Tabelle nicht im main 
machen sollte.

Versuch:
1
main
2
.
3
  char obj[3][10] = {"Zeile 1", "Zeile 2", "Zeile 3"};
4
.
5
  objekte(&obj)
6
.
7
// Ende main
8
9
01 // Test Objekte
10
02 void objekte(char *pobj) 
11
03 {
12
04    printf ("%s \n", *pobj[2]);  // Test anzeigen Zeile 2
13
05 }
14
06 // Ende Test

Fehler:

objekte.c: In Funktion »objekte«:
objekte.c:4:5: Warnung: Unverträgliche implizite Deklaration der 
eingebauten Funktion »printf« [standardmäßig aktiviert]
objekte.c:4:22: Fehler: ungültiger Argumenttyp in unärem »*« (haben 
»int«)

Kann ich die Tabelle zur Verarbeitung nicht wie sonst eine Variable mit 
dem Pointer übergeben?
Wo liegt mein Fehler?
Mit NULL kam ich nicht klar.

Danke für Eure Hilfe!
Gruß

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Na jam nach Dir einfach mal klar was Du definiert hast:

obj besteht aus 3 Arrays (die Schreibweise ob[3][10] halte ich
für unglücklich gewählt, ich würde es wie in meinem Beispiel
definieren - dann ist es klarer) mit je 10 Byte.

obj[0] ist die Adresse des ersten Arrays, diese sollstest Du an
objekte übergeben und direkt ausgeben. Also
1
objekte( obj[0]);
2
objekte( obj[1]);
3
...
4
5
02 void objekte(char *pobj) 
6
03 {
7
04    printf ("%s \n", pobj);  // Test anzeigen Zeile 2
8
05 }

von morgenmuffel (Gast)


Lesenswert?

Dietmar P. schrieb:
> 04    printf ("%s \n", *pobj[2]);  // Test anzeigen Zeile 2

04 printf ("%s \n", pobj[1][0]);

zeiger auf arrays

von Dietmar P. (dietmar2)


Lesenswert?

Also kann ich nicht ein mehrdimensionales array übergeben und dann im 
Unterprogramm darauf "zeilenweise" zugreifen?

von Udo S. (urschmitt)


Lesenswert?

Dietmar P. schrieb:
> Also kann ich nicht ein mehrdimensionales array übergeben und dann im
> Unterprogramm darauf "zeilenweise" zugreifen?

Kann man schon, aber schau mal WAS GENAU du übergibst:

void objekte(char *pobj)

Ist "char *pobj" denn ein mehrdimensionales Array?
Du hast die Funktion objekte so definiert daß du ihr einen String 
(character Array) übergibst, aber nicht so daß du ihr ein 2 dim. char 
Array übergibst.

2. Fehler:
Du rufst die Funktion so auf:
  objekte(&obj)

Jetzt ist aber der Name eines Arrays in C per se schon eine 
Adressvariable. Wenn du die nochmal mit dem Adressoperator referenzierst 
dann übergibst du der Funktion einen Zeiger auf die Adresse eines 
2dimensionalen Arrays. Das ist aber nicht das was du willst.

Die in der Funktion übergebene Variable und die in der 
Funktionsdefinition definierte Variable müssen vom gleichen Typ sein.

Ich würde vorschlagen daß du einen char * (Einen Zeiger auf den String) 
statt ein Array von Strings) übergibst und dann entsprechend mit einem 
Element deines Stringarrays aufrufst.

von morgenmuffel (Gast)


Lesenswert?

1
// Test Objekte
2
 void objekte(char *pobj[])
3
 {
4
    printf ("%s \n", pobj[1]);  // Test anzeigen Zeile 2
5
 }
6
 // Ende Test
7
8
9
10
11
int main()
12
{
13
  char *obj[] = {"Zeile 1", "Zeile 2", "Zeile 3"};
14
15
  objekte(obj);
16
return 0;
17
// Ende main
18
}

so klappts bei mir
ja zeiger und arrays sind für mich etwas verwirrend.

von Udo S. (urschmitt)


Lesenswert?

morgenmuffel schrieb:
> ja zeiger und arrays sind für mich etwas verwirrend.

Mehrdimensionale Arrays sind in C auch nicht unbedingt einfache Kost.

von Dietmar P. (dietmar2)


Lesenswert?

Bei mir gehts leider nicht.

Habe genau dieses Beispiel mal übernommen und bekomme folgenden Fehler:

objekte.c:4:5: Warnung: Unverträgliche implizite Deklaration der 
eingebauten Funktion »printf« [standardmäßig aktiviert]

von Udo S. (urschmitt)


Lesenswert?

Dietmar P. schrieb:
> Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »printf«
Schon mal den Fehler genau angeschaut?
Sieht aus als hättest du printf noch mal deklariert und zwar anders als 
im header.

Zeig mal dein Code

von Klaus W. (mfgkw)


Lesenswert?

oder gar nicht deklariert.
(Steht zwar in jedem C-Buch, wie es geht, aber wozu gibt es das Forum?)

von Dietmar P. (dietmar2)


Lesenswert?

printf habe ich nicht (re-)definiert, ich habe es verwendet wie es in 
den Bibliotheken steht. Compiler ist gcc für den PC und Avr-gcc für den 
Atmega32.
Code nur für Testzwecke des array:
1
 // Main
2
 
3
#include <stdio.h>
4
#include "stdint.h"
5
#include <string.h>  
6
7
8
void main(void)
9
{
10
11
  char *obj[] = {"Zeile 1", "Zeile 2", "Zeile 3"};
12
13
  objekte(obj);
14
//return 0;
15
16
} // Ende main
17
18
19
// Test
20
 void objekte(char *pobj[])
21
 {
22
    printf ("%s \n", pobj[1]);  // Test anzeigen Zeile 2
23
 }
24
// ende

Der ganze Code ist recht komplex und beinhaltet eine komplette Steuerung 
einer Leitungsauswertung und Anzeige per SPI.

von Mittesser (Gast)


Lesenswert?

Wenn man einen Zeiger auf ein mehrdimensionales Array übergeben will, 
sollte die aufgerufene Funktion schon "wissen", wie groß die inneren 
Dimensionen sind.
1
#include <stdio.h>
2
#include <string.h>
3
4
void EineFunktion(char Parameter[][10])
5
{
6
        int i;
7
        for (i=0; i<3; i++)
8
        {
9
                printf ("%s \n", Parameter[i]);
10
        }
11
}
12
13
int main(int argc, char** argv)
14
{
15
        char Textzeilen[3][10];
16
        memset(Textzeilen, 0, sizeof(char[3][10]));
17
        strcpy(Textzeilen[0], "1te Zeile");
18
        strcpy(Textzeilen[1], "2te Zeile");
19
        EineFunktion(Textzeilen);
20
        return 0;
21
}

Wenn man das etwas lesbarer und weniger geschwätzig machen will, kann 
man mit Typendefinitionen arbeiten:
1
#include <stdio.h>
2
#include <string.h>
3
4
typedef char Zeile_t[10];
5
typedef Zeile_t Dreizeiler_t[3];
6
7
void EineFunktion(Dreizeiler_t Parameter)
8
{
9
        int i;
10
        for (i=0; i<3; i++)
11
        {
12
                printf ("%s \n", Parameter[i]);
13
        }
14
}
15
16
int main(int argc, char** argv)
17
{
18
        Dreizeiler_t Textzeilen;
19
        memset(Textzeilen, 0, sizeof(Dreizeiler_t));
20
        strcpy(Textzeilen[0], "1te Zeile");
21
        strcpy(Textzeilen[1], "2te Zeile");
22
        EineFunktion(Textzeilen);
23
        return 0;
24
}

von Dietmar P. (dietmar2)


Lesenswert?

Danke für die ausführliche Beschreibung.

Jetzt habe ich die Lösung.

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.