www.mikrocontroller.net

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


Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
int Funktion (char* string1, char* string2)
{
char str1[30], str2[30];

strcpy(str1, string1);
strcpy(str2, string2);

//hier werden str1 und str2 verarbeitet und return-Wert erzeugt

}

void main()
{
  char inBuf[30];
  int a;

  strcpy(inBuf, "hallo");

  a = Funktion(&"hallo", inBuf);
}

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

Autor: Matthias Nix (vbchaos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass das "&" beim String mal weg in der Übergabe

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann bekomme ich einen Fehler vom Compiler:
Attempt to make Pointer to a constant.

Peter

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Matthias Nix (vbchaos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, bei mir mit dem GCC geht das so ohne Probleme...
void sendString (char * string1, char * string2,  char * string3)
{
// blablabla
}

sendString ("Hallo", "Welt", "!");

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus der Fehlermeldung, die kommt, wenn ich schreibe

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

Peter

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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() :(

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Konstante als Funktionsparameter?
Wie geht das denn?

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer wrote:
> Eine Konstante als Funktionsparameter?
> Wie geht das denn?

So zum Beispiel:
int addiere(int a, int b) {
  return a + b;
}

int main() {
  printf("%i\n", addiere(1, 2));
}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal mit:

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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
int addiere(const int a, const int b) 
{
  return a + b;
}

int main() 
{
  printf("%i\n", addiere(1, 2));
}

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!!!)

Autor: Peter Diener (pdiener) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.