Forum: Mikrocontroller und Digitale Elektronik Parameterübergabe an eine Funktion


von Peter D. (pdiener) Benutzerseite


Lesenswert?

Hallo zusammen,

ich möchte an eine Funktion, die strings in einer besonderen Weise 
vergleicht, zwei Parameter übergeben. Und zwar einmal einen Pointer auf 
ein Array von char und der andere Parameter soll direkt im Aufruf 
stehen.

Leider wird der andere string nicht korrekt übergeben.

Mein Programm sieht so aus:
1
int Funktion (char* string1, char* string2)
2
{
3
char str1[30], str2[30];
4
5
strcpy(str1, string1);
6
strcpy(str2, string2);
7
8
//hier werden str1 und str2 verarbeitet und return-Wert erzeugt
9
10
}
11
12
void main()
13
{
14
  char inBuf[30];
15
  int a;
16
17
  strcpy(inBuf, "hallo");
18
19
  a = Funktion(&"hallo", inBuf);
20
}

Das ganze läuft auf einem Pic mit CCS compiliert, aber das dürfte 
eigentlich für das Problem egal sein.

Das Problem ist, dass die Übergabe des Konstantenarray nicht 
funktioniert, in der Funktion steht in str2 dann hallo drin und str1 ist 
leer.

Hat jemand eine Idee, woran das liegen kann? Wie übergibt man in C 
Pointer auf implizit definierte Konstanten richtig?

Am liebsten wäre mir eine so einfache Übergabe wie an printf.

Etwa so: Funktion("hallo", inBuf);

Wie muss dann die Funktion aussehen?

Grüße,

Peter

von Matthias N. (vbchaos)


Lesenswert?

Lass das "&" beim String mal weg in der Übergabe

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Dann bekomme ich einen Fehler vom Compiler:
Attempt to make Pointer to a constant.

Peter

von Sven P. (Gast)


Lesenswert?

Peter Diener wrote:
> [...] zwei Parameter übergeben. Und zwar einmal einen Pointer auf
> ein Array von char
Nein, das möchtest du sicherlich nicht :-]

Du willst ja nicht den Zeiger selbst, also die 'Adressvariable' haben, 
sondern das, wodrauf sie zeigt, entsprechend reicht ein einfaches 
'Verzeigern'.

> Hat jemand eine Idee, woran das liegen kann? Wie übergibt man in C
> Pointer auf implizit definierte Konstanten richtig?
Garnicht. In deinem Fall: Wenn du eine Konstante à la "ABC" angibst, ist 
das schon ein Zeiger (naja, fast), nämlich einer, der irgendwo auf eine 
Stelle im Speicher zeigt, an der ABC steht.

> Am liebsten wäre mir eine so einfache Übergabe wie an printf.
> Wie muss dann die Funktion aussehen?
Genau so :-)

von Matthias N. (vbchaos)


Lesenswert?

Also, bei mir mit dem GCC geht das so ohne Probleme...
1
void sendString (char * string1, char * string2,  char * string3)
2
{
3
// blablabla
4
}
5
6
sendString ("Hallo", "Welt", "!");

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Den Compiler stört meiner Ansicht nach eher, dass die Konstante vom Typ 
const ist, aber Funktionsparameter nicht const sein dürfen. Ich habe 
auch schon ein Typcasting ausprobiert, compiliert auch, funktioniert 
aber genausowenig:

Funktion( (char*) "hallo", inBuf);

Grüße,

Peter

von Sven P. (Gast)


Lesenswert?

Peter Diener wrote:
> Den Compiler stört meiner Ansicht nach eher, dass die Konstante vom Typ
> const ist, aber Funktionsparameter nicht const sein dürfen.
Wo hast du denn das her?

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Aus der Fehlermeldung, die kommt, wenn ich schreibe

int Funktion(const char* string1, char* string2)
{
usw...
}

Peter

von STK500-Besitzer (Gast)


Lesenswert?

>&"hallo"

Welche Adresse hat "hallo" denn?

>> Den Compiler stört meiner Ansicht nach eher, dass die Konstante vom Typ
>> const ist, aber Funktionsparameter nicht const sein dürfen.

deine Schlußfolgerung ist falsch.

von holger (Gast)


Lesenswert?

>Dann bekomme ich einen Fehler vom Compiler:
>Attempt to make Pointer to a constant.

Das ist ein RAM/Flash Problem. Kenn ich vom C18.

  a = Funktion("hallo", inBuf);

Übergibt vermutlich einen Zeiger auf die Konstante
"hallo" die im Flash liegt! Also anders als beim AVR-GCC
wo "hallo" im RAM liegen würde.

int Funktion (char* string1, char* string2)

Die Funktion erwartet den Zeiger im RAM!
Deshalb gibt es die Fehlermeldung.

von Peter D. (pdiener) Benutzerseite


Lesenswert?

@holger: Ja, so sehe ich das auch. Aber printf gibts ja auch beim CCS 
Compiler und der Aufruf ist einfach so:

printf("Sag was...");

Irgendwie muss man die Funktion doch definieren können, dass das geht, 
oder?

Peter

von holger (Gast)


Lesenswert?

>@holger: Ja, so sehe ich das auch. Aber printf gibts ja auch beim CCS
>Compiler und der Aufruf ist einfach so:

>printf("Sag was...");

>Irgendwie muss man die Funktion doch definieren können, dass das geht,

int Funktion (const char* string1, char* string2)

oder

int Funktion (const rom char* string1, char* string2)

Aber dann gibt es möglicherweise Ärger mit strcpy() :(

von STK500-Besitzer (Gast)


Lesenswert?

Eine Konstante als Funktionsparameter?
Wie geht das denn?

von Peter D. (pdiener) Benutzerseite


Lesenswert?

strcpy kann Konstanten und Variablen als source, das steht auch in der 
Doku. Und const darf ich in der Funktionsdeklaration nicht erwähnen, 
sonst compiliert es nicht mehr (mit irgendeiner nicht nachvollziehbaren 
Fehlermeldung - identifier expected - und zeigt auf eine Stelle nach 
const).

Mittlerweile hab ich es auch mit einem gcc ausprobiert und da gehts 
einfach mit const in der Funktion, das hilft nur leider nicht.

Edit: ohne const, einfach so wie vorher.

Peter

von Sven P. (Gast)


Lesenswert?

STK500-Besitzer wrote:
> Eine Konstante als Funktionsparameter?
> Wie geht das denn?

So zum Beispiel:
1
int addiere(int a, int b) {
2
  return a + b;
3
}
4
5
int main() {
6
  printf("%i\n", addiere(1, 2));
7
}

von holger (Gast)


Lesenswert?

Versuchs mal mit:

int Funktion (char rom * string1, char* string2)

von STK500-Besitzer (Gast)


Lesenswert?

>So zum Beispiel:

>int addiere(int a, int b) {
>  return a + b;
>}
>
>int main() {
>  printf("%i\n", addiere(1, 2));
>}

Ja, das geht.

Aber wie wäre es mit:
1
int addiere(const int a, const int b) 
2
{
3
  return a + b;
4
}
5
6
int main() 
7
{
8
  printf("%i\n", addiere(1, 2));
9
}

So habe ich Holgers Post verstanden...

Ich weiß nicht, ob mir da spezielles C-Wissen fehlt, aber mein Verstand 
sagt mir, dass das Blödsinn ist.
Ich übergebe einer Funktion ja eine Variable, damit ich sie mit 
unterschiedlichen Werten benutzen kann.
Dabei ist Funktion("Hallo",&s);  ein Aufruf von vielen möglichen...
Ich weiß nicht, wie der Compiler "konstante" Strings umsetzt - ich 
vermute aber, dass er aus dem konstanten Text ein char-Array macht und 
dessen Pointer an die Funktion übergibt.
Vielleicht liege ich aber auch daneben (mit meiner 
"const"-Parameter-Meinung). Vielleicht liegt es aber auch an Compilern 
von Controllern, die ich nicht mag. (ACHTUNG! Meine persönliche 
Meinung!!!)

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Ich habe mittlerweile im Manual gefunden, dass es nicht geht, eine 
Adresse eines Konstantenarrays zu erzeugen.
Das Problem wird beim direkten Adressieren eines Arrays
i = array[5];
durch ein Makro gelöst
und bei Funktionsaufrufen wie
printf("hallo");
mit irgendetwas, was nicht im Quellcode veröffentlicht wird.

Dass das nich geht, liegt angeblich an der Architektur vom Pic, wobei 
Flash und Ram so strikt getrennt sind, dass keine Pointer auf das Flash 
erzeugt werden können. Ganz nachvollziehen kann ich das allerdings 
nicht, der Compiler könnte das doch mühelos erledigen, ich erwarte ja 
nicht, dass das in Echtzeit passiert. Deswegen sind die Parameter ja 
Konstanten, da sind die Adressen ja schon dem Compiler bekannt. Daher 
verstehe ich das Problem nicht wirklich.

Es ist aber wohl so, dass die Parameter auf den Stack müssen, und der 
ist nunmal im Rambereich, und wenn dort die Adresse der Daten aus dem 
Flash steht, kann damit keine Adressierung durchgeführt werden. Oder so 
in etwa...

Eine Alternative für meine Funktion wäre ein Makro. Weiß jemand, wie ich 
in C ein Makro mit Parametern schreibe?

Grüße,

Peter

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.