Forum: Mikrocontroller und Digitale Elektronik Array als pointer in Funktion übergeben, dort beschreiben und wieder zurück


von Frank (Gast)


Lesenswert?

Guten morgen,
ich möchte einen Array einer Funktion übergeben. In dieser Funktion soll 
in diesem Array dann werte gesetzt werden, welch ich dann in der 
main-funktion wieder verwende. Die Elemente des arrays (dort sollen dann 
nur nullen und einsen drinn stehen) sehe ich mir dann über UART an. Doch 
leider bekomme ich nur kryptische Zeichen heraus
1
generate_array(&Array);
2
for (n=0; n<110; n++)
3
{
4
  if(Array[n]==1) uart_transmit(signs[n][0]);
5
  else uart_transmit(' ');
6
}
7
uart_sendString("\n\r");
in einer anderen c-file ist dann die Funktion
1
void generate_clock(uint8_t *array[])
2
{
3
  uint8_t n;
4
  for (n=0; n<110; n++)
5
  {
6
    if(signs[n][1]==1) *array[n] = 1;
7
    else *array[n] = 0;
8
  }
9
}

Später möchte ich in der hauptfunktion dann nicht mehr auf signs 
zugreifen, sondern einen LED-Streifen ansteuern. Momentan lasse ich mir 
das ergebnis aber über uart am pc ausgeben, damit ich die Fehler 
einfacher sehen kann. Der UART an sich funktioniert. Dort gibt es keine 
Probleme

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Frank schrieb:
> generate_array(&Array);
> generate_clock(uint8_t *array[])
_clock oder _array?

> generate_array(&Array);
Lass da mal das & weg. Array selbst ist schon ein Zeiger auf ein Array. 
Wie ist Array definiert?

: Bearbeitet durch Moderator
von Rolf M. (rmagnus)


Lesenswert?

Frank schrieb:
> generate_array(&Array);

Es wäre sehr hilfreich, zu wissen, wie Array definiert ist.

Frank schrieb:
> void generate_clock(uint8_t *array[])

Das ist ein Zeiger auf einen Zeiger auf uint8_t. Du kannst daran ein 
Array aus Zeigern übergeben. Wolltest du das?

von Frank (Gast)


Lesenswert?

Lothar M. schrieb:
>> generate_array(&Array);
>> generate_clock(uint8_t *array[])

_array ist richtig. die funktion heißt auch so.

Rolf M. schrieb:
> Es wäre sehr hilfreich, zu wissen, wie Array definiert ist.

uint8_t Array[110];

Lothar M. schrieb:
> Lass da mal das & weg.

Mhh, dann kommen erst kryptische Zeichen und dann irgendwann gar nichts 
mehr

von derjaeger (Gast)


Lesenswert?

Wie wärs wenn du mal den kompletten Code anbietest? Was ist signs, wo 
ist generate_array .....

von devzero (Gast)


Lesenswert?

generate_array(uint8_t *array);

von Dirk (Gast)


Lesenswert?

Ich "rate" mal, dass dem TO das hier vielleicht hilft:
1
#include <stddef.h>
2
#include <stdint.h>
3
#include <stdio.h>
4
5
#define NUMBER_OF_ELEMENTS 110
6
7
#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
8
9
uint8_t array [NUMBER_OF_ELEMENTS] = {0};
10
11
void generate_stuff (uint8_t* array_ptr, size_t array_size)
12
{
13
  for (size_t i = 0; i < array_size; ++i)
14
  {
15
    uint8_t fancy_value_to_assign = i; 
16
    
17
    *(array_ptr + i) = fancy_value_to_assign;
18
    
19
    // or
20
    // array_ptr[i] = fancy_value_to_assign;
21
  }
22
}
23
24
int main ()
25
{
26
  generate_stuff (array, ARRAY_SIZE (array));
27
  
28
  for (size_t i = 0; i < ARRAY_SIZE (array); ++i)
29
  {
30
    printf ("array[%lu] =  %u\n", i, array[i]);
31
  }
32
  
33
  return 0;
34
}

Schönen Sonntag!

von Stefan F. (Gast)


Lesenswert?

Wenn du im Quelltext den Namen eines Arrays verwendest, dann wird 
bereits ein Pointer übergeben. Deswegen kann die Funktion den Inhalt des 
Arrays auch verändern.
1
char[] text1="Hallo"; // 6 Bytes, wegen der abschließenden 0.
2
3
char* zeiger1=text1; // Das ist valide
4
5
char* text2="Welt!" // wieder 6 Bytes
6
7
char[] array2=text2; // Auch das ist valide
8
9
function text_ausgeben(char* text)
10
{
11
    while (*text != 0)
12
    {
13
       char c=*text;
14
       ausgeben(c);
15
       text++;
16
    }
17
}
18
19
// Oder so:
20
21
function text_ausgeben(char* text)
22
{
23
    for (i=0; i<strlen(text); i++)
24
    {
25
        char c=text[i];
26
        ausgeben(c);
27
    }
28
}
29
30
// Oder so:
31
32
function text_ausgeben(char[] text)
33
{
34
    int i=0;
35
    while (*(text+i) != 0)
36
    {
37
       char c=*(text+i);
38
       ausgeben(c);
39
       i++;
40
    }
41
}
42
43
function text_ausgeben(char* text)
44
{
45
    for (i=0; text[i]!=0; i++)
46
    {
47
        char c=text[i];
48
        ausgeben(c);
49
    }
50
}

Alle diese Funktionen kannst du wahlweise mit text1, zeiger1, text2, 
array2 und einem String-Literal (z.B. "blabla") aufrufen.

In allen Fällen ist der Übergabeparameter "text" ein Zeiger auf Zeichen. 
Die Deklaration "char[]" deutet an, dass es viele Zeichen sind, im 
Gegensatz dazu sagt "char*" nicht aus, ob es nun ein oder viele Zeichen 
sind. Beide Schreibweisen sind gegeneinander austauschbar. Wie du an den 
obigen Quelltexten siehst, kann man die Zugriffe auch wild mischen.

Man kann als Funktionsparameter einen char* benutzen, und dann mit Array 
index zugreifen. Umgekehrt herum kann der Funktionsparameter auch ein 
char[] sein, aber man inkrementiert ihn als sei es ein Pointer.

Technisch gesehen ist beides identisch. Du kannst das am 
Assembler-Listing sehen.

von Dirk (Gast)


Lesenswert?

Stefanus F. schrieb:

> function text_ausgeben(char* text)

Ob der Compiler das mag? Ansonsten hast Du natürlich Recht :-)

von Stefan F. (Gast)


Lesenswert?

Dirk schrieb:
> Stefanus F. schrieb:
>
>> function text_ausgeben(char* text)
>
> Ob der Compiler das mag? Ansonsten hast Du natürlich Recht :-)

Ok, das void für den Rückgabewert fehlt.

von Rolf M. (rmagnus)


Lesenswert?

Stefanus F. schrieb:
> Ok, das void für den Rückgabewert fehlt.

Ja, und das "function" existiert nicht.

von Stefan F. (Gast)


Lesenswert?

Rolf M. schrieb:
> Stefanus F. schrieb:
>> Ok, das void für den Rückgabewert fehlt.
>
> Ja, und das "function" existiert nicht.

Ich fange an, die Programmiersprachen durcheinander zu werfen. Kommt 
davon, wenn man immer mit IDE arbeitet, die einem das Denken teilweise 
abnimmt.

von J. Zimmermann (Gast)


Lesenswert?

Stefanus F. schrieb:
> Ok, das void für den Rückgabewert fehlt.

Nur für Leute, die sich gern selbst beim Schreiben zusehen, fehlendes 
void erzeugt höchstens eine Warnung.
mfg
Achim

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Stefanus F. schrieb:
> function text_ausgeben(char[] text)
> {
>     int i=0;
>     while (*(text+i) != 0)
>     {
>        char c=*(text+i);
>        ausgeben(c);
>        i++;
>     }
> }

oder so

//c99!
void text_ausgeben(const char text[const]) {
   uint8_t i=0;
   while (char c=*(text+i++), c) putc(c);
}


mt

von Stefan F. (Gast)


Lesenswert?

Apollo M. schrieb:
> void text_ausgeben(const char text[const]) {
>    uint8_t i=0;
>    while (char c=*(text+i++), c) putc(c);
> }

Ist sicher richtig, ich wollte den TO allerdings nicht durch derart 
komplexe Ausdrücke verwirren.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Apollo M. schrieb:
> oder so
>
> //c99!
> void text_ausgeben(const char text[const]) {
>    uint8_t i=0;
>    while (char c=*(text+i++), c) putc(c);
> }

oder gleich als einzeiler!

//c99!
void text_ausgeben(const char text[const]) {
   while (char c=*(text++), c) putc(c);
}

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

J. Zimmermann schrieb:
> Stefanus F. schrieb:
>> Ok, das void für den Rückgabewert fehlt.
>
> Nur für Leute, die sich gern selbst beim Schreiben zusehen, fehlendes
> void erzeugt höchstens eine Warnung.

Wenn du nichts hinschreibst, ist es aber nicht implizit void, sondern 
int. Man muss also einen Wert zurückgeben, sonst ist das Verhalten 
undefiniert. Und ein "return 0;" ist länger als ein "void ". Lohnt sich 
also auch für Schreibfaule eigentlich nicht. Abgesehen davon, dass man 
Code warnungsfrei schreibt.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Apollo M. schrieb:
> //c99!
> void text_ausgeben(const char text[const]) {
>    while (char c=*(text++), c) putc(c);
> }

now without bugs!

//c99!
void text_ausgeben(const char text[]) {
   char c;
   while (c=*(text++), c) putc(c);
}

: Bearbeitet durch User
von Dirk (Gast)


Lesenswert?

Apollo M. schrieb:

> void text_ausgeben(const char text[]) {
>    char c;
>    while (c=*(text++), c) putc(c);
> }

Damit das funktioniert, muss text ein "valider C-String" sein, also mit 
einer NULL als letztem Element. Der TO hat einen Fall mit bekannter 
Länge.

Apropos TO... liest Du noch mit?

von Stefan F. (Gast)


Lesenswert?

Es geht doch nur darum, die Varianten zu beleuchten, wie man Arrays an 
Funktionen übergibt. Ihr beschäftigt euch lieber mit Nebensachen, die 
vom Thema ablenken.

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.