Forum: Mikrocontroller und Digitale Elektronik Frage zum C-Programmieren von uCs


von Coder (Gast)


Lesenswert?

Ich habe ein paar allgemeine Fragen zum programmieren mit C:

1. Wann muss ich im Header File Prototypen definieren?

2. Für was steht #ifndef und all die #-Anweisungen, und was kann ich 
damit machen?

3. Was ist der unterschied ob ich eine Variable mit static definiere 
oder nicht?

4. Spielt es eine Rolle ob ich meine Variablen alle Global oder in den 
Funktionen definiere?

5. Ab Wann sollte man sein Code auf mehrere C-Files aufteilen?

Danke für Eure Antworten!

von Falk B. (falk)


Lesenswert?

@ Coder (Gast)

>1. Wann muss ich im Header File Prototypen definieren?

Wenn deine dazugehörige .c Datei Funktionen enthält.

>2. Für was steht #ifndef und all die #-Anweisungen, und was kann ich
>damit machen?

Damit kann man in Abhängigkeit von #defines bestimmte Teile des Codes 
kompilieren oder nicht.

>3. Was ist der unterschied ob ich eine Variable mit static definiere
>oder nicht?

Lange Geschichte.

>4. Spielt es eine Rolle ob ich meine Variablen alle Global oder in den
>Funktionen definiere?

Aber sicher. Prinzipiell sollte man so wenige wie möglich globale 
Variablen nutzen.

>5. Ab Wann sollte man sein Code auf mehrere C-Files aufteilen?

Kommt drauf an. ab 500..1000 Zeilen bzw. wenn es logisch sinnvoll ist 
(z.B. für UART, LCD etc.).

MfG
Falk

von Matthias Kölling (Gast)


Lesenswert?

Hallo Coder,

ein paar Ergänzungen meinerseits.
zu 1: nur, wenn die Funktion aus einem anderen c-file aufgerufen werden
      soll. Ansonsten den Prototypen ins c-file. Zusätzlich kann man die
      Funktion noch als static declarieren. Dann ist sie garantiert
      private.
zu 3: static steuert zum einen die "Sichtbarkeit" als auch die Ablage 
der
      Variablen im RAM. static auf file-Ebene oder in der Funktion 
belegt
      festen Speicherplatz. In der Funktion ist auch gewährleistet, dass
      der Inhalt der Variablen auch bei Verlassen der Funktion erhalten
      bleibt. Sogenannte lokale Variablen, die in einer Funktion
      deklariert werden entweder auf Registern oder auf dem Stack 
abgelegt
      und werden bei Verlassen der Funktion zerstört.
zu 4: Das kommt darauf an, was man machen will. Eine Variable in einer
      Funktion soll wahrscheinlich ihren Wert behalten. Ein
      Zwischenergebnis wird man auf lokalen Variablen halten. Das macht
      auch Berechnungen, bei denen immer wieder auf gleiche Array- oder
      Strukturelemente zugegriffen werden soll, auch schneller. Außerdem
      kommt es darauf an, wieviel RAM man zur Verfügung hat.

Gruß Matthias

von Morin (Gast)


Lesenswert?

Ein Tip vorneweg: Mach mal ein vernünftiges C-Tutorial. Das meiste was 
du gefragt hast betrifft die Sprache C (nicht mal speziell für 
Mikrocontroller), da ist ein Tutorial einfacher als wenn du dir hier im 
Forum die Sprache beibringen lässt. Wenn dann Fragen übrig sind kannst 
du natürlich gern fragen.

> 1. Wann muss ich im Header File Prototypen definieren?

Für jede Funktion im entsprechenden C-File, die auch in anderen C-Files 
sichtbar sein soll. Achtung: zwei "unsichtbare" Funktionen in 
verschiedenen C-Files dürfen trotzdem nicht gleich heißen; das geht in C 
zwar auch aber da du offensichtlich ein Anfänger bist lassen wir das 
erstmal weg.

> 2. Für was steht #ifndef und all die #-Anweisungen, und was kann ich
> damit machen?

Steueranweisung für den Compiler, d.h. die sind nicht Teil des Programms 
sondern steuern, wie das Programm vom Compiler erzeugt wird.

#ifndef Speziell steuert, dass der Teil bis zum #endif nur dann 
übersetzt wird, wenn das entsprechende Symbol noch nicht per #define 
definiert wurde. Typischerweise macht man in Header-files so was:

#ifndef SYMBOL
#define SYMBOL
...
#endif

Falls dann innerhalb eines C-Files derselbe Header File mehrmals (z.B. 
von anderen Header-Files) included wird, so wird der Inhalt nur einmal 
beachtet.

> 3. Was ist der unterschied ob ich eine Variable mit static definiere
> oder nicht?

Für Globale Variablen: Static versteckt eine Variable, so dass sie in 
anderen C-Files niemals sichtbar ist und gleich heißen kann wie 
static-Variablen in anderen C-Files. Siehe der "Anfänger"-Kommentar bei 
Punkt 1.

Für lokale Variablen: Nicht-static-Variablen werden 1x pro Aufruf der 
Funktion angelegt, und jede angelegte Variable hat einen eigenen Wert 
für sich; Bei static benutzen alle Aufrufe (also Nacheinander-Aufrufe 
und auch geschachtelte Aufrufe) dieselbe angelegte Variable und können 
über deren Wert kommunizieren.

> 4. Spielt es eine Rolle ob ich meine Variablen alle Global oder in den
> Funktionen definiere?

Siehe Kommentar zu 3. was die pro-Aufruf angelegten Variablen angeht. 
Das geht mit globalen Variablen gar nicht.

> 5. Ab Wann sollte man sein Code auf mehrere C-Files aufteilen?

- Code wird schwer überschaubar
- Mehrere logische Einheiten die sich trennen lassen
- Mehrere Programmierer, die unabhängig arbeiten sollen

Mein Tip: Du bist noch ganz am Anfang. Bleib bei so einfachen Programmen 
dass sich das Aufteilen nicht lohnt. Mit der Übung kommt der Rest dann 
schon.

von Coder (Gast)


Lesenswert?

Vielen Dank!

Dann hab ich noch eine Frage:

Da wird doch bei uCs teilweise der Speicher zwischen DATA und CODE 
unterschieden? Hab das glaube ich mal bei einem x86 gesehn.

Für was braucht man das? Wenn man mit C Coded unterscheidet man auch 
nicht zwischen DATA und Code.

von roboterbastler (Gast)


Lesenswert?

static, global , versteckt usw...

Ist alles spielerei die keine grosse Wirkung hat auf den µCs, ausser das 
du durcheinander gebracht wirst mit dieser Sram-vollpackerei.

Am sinnvollsten ist es, wenn du die Sram-Adressen selber verwaltest, 
dann erlebst du in c keine Überraschungen auf den µcs.

von Simon K. (simon) Benutzerseite


Lesenswert?

roboterbastler wrote:
> static, global , versteckt usw...
>
> Ist alles spielerei die keine grosse Wirkung hat auf den µCs, ausser das
> du durcheinander gebracht wirst mit dieser Sram-vollpackerei.
>
> Am sinnvollsten ist es, wenn du die Sram-Adressen selber verwaltest,
> dann erlebst du in c keine Überraschungen auf den µcs.

Ja ne, Chef. Da hat aber einer Ahnung.

von Ralph B. (ralph-b)


Lesenswert?

Also Simon soo kannst du das aber nicht schreiben.

Wenn einer soo gut ist, das er besser als ein spezialisiert Compiler den 
Ram verwalten kann, dann musst du ihm huldigen und nicht einen so 
negativen klingenden Beitrag schreiben.

von Piazzaiolo (Gast)


Lesenswert?

@Simon:

Hab mir mal deine Website angeschaut, hast ja schon einige coole Sachen 
gemacht!

Meine Frage:

Hast du dir das alles selbst beigebracht? Oder machst du Beruflich auch 
was ähnliches?

Gruss Pizzaiolo

von Simon K. (simon) Benutzerseite


Lesenswert?

Ralph Broeder wrote:
> Also Simon soo kannst du das aber nicht schreiben.
>
> Wenn einer soo gut ist, das er besser als ein spezialisiert Compiler den
> Ram verwalten kann, dann musst du ihm huldigen und nicht einen so
> negativen klingenden Beitrag schreiben.

Nö, natürlich nicht. Aber mal abgesehen dass ich (abhängig vom 
Schriftbild des Autors) nicht davon ausgehe, dass er das kann, ist es 
zudem in der Regel auch noch unsinnig sowas selber zu machen, da nur 
wesentlich viel Zeit und ne Menge an Überblick dabei drauf geht.

Den Einstieg in Elektrotechnik und Mikroprozessorsachen (vor etwa 4-5 
Jahren) habe ich selbst gemacht. Derzeit bin ich 18 und gehe noch zur 
Schule (13. Klasse) ;)

von Morin (Gast)


Lesenswert?

Erst mal: Hut ab, alle deine Fragen haben genau ins Schwarze getroffen! 
Soll heißen sie sprechen genau die komplizierten Probleme an.

> Da wird doch bei uCs teilweise der Speicher zwischen DATA und CODE
> unterschieden? Hab das glaube ich mal bei einem x86 gesehn.

Stimmt, wobei der x86 da eher harmlos ist.

> Für was braucht man das? Wenn man mit C Coded unterscheidet man auch
> nicht zwischen DATA und Code.

Zum x86: da betrifft es die Systembefehle, die man eh nicht aus C heraus 
benutzt. Das "normale" Programmieren unterscheidet nicht zwischen Data 
und Code (jedenfalls nicht von der CPU aus, manchmal aber vom 
Betriebssystem aus).

Zu Mikrocontrollern: Aus deiner Sicht "braucht" man es für gar nichts, 
es ist im Gegenteil eine Einschränkung mit der du bei Mikrocontrollern 
klar kommen musst, was bei "normalen" CPUs nicht so wäre. Ich kenne zwar 
nicht die genauen Hintergründe, aber allgemein liegt die Vermutung nahe, 
dass der µC unter solchen Einschränkungen intern einfachere Hardware 
benutzen kann.

Dass du in C solche Einschränkungen nicht hast bedeutet im Allgemeinen, 
dass C nicht in allen Fällen problemlos für die jeweiligen 
Mikrocontroller übersetzt werden kann. Mangels Erfahrung kann ich dir 
aber keine Details nennen - das hängt auch stark davon ab welchen µC du 
genau verwendest.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Literaturhinweis

Brian Kernighan, Dennis Ritchie Programmieren in C zweite Auflage, 
Hanser-Verlag

von Severino R. (severino)


Lesenswert?

Morin wrote:

>> 2. Für was steht #ifndef und all die #-Anweisungen, und was kann ich
>> damit machen?
>
> Steueranweisung für den Compiler, d.h. die sind nicht Teil des Programms
> sondern steuern, wie das Programm vom Compiler erzeugt wird.
>
Ich will ja nicht kleinlich sein, aber die Anweisungen #indef, #ifndef, 
#endif werden vom Präprozessor verarbeitet und der Compiler bekommt sie 
gar nicht zu sehen.

Natürlich ist das ein Detail, aber für's Verständnis manchmal wichtig. 
Ebenso wie die #include.

von Morin (Gast)


Lesenswert?

> Ich will ja nicht kleinlich sein, aber die Anweisungen #indef, #ifndef,
> #endif werden vom Präprozessor verarbeitet und der Compiler bekommt sie
> gar nicht zu sehen.

Naja, das war die usprüngliche Trennung... aber soweit ich weiß rief man 
schon damals ein Programm namens "cc" auf, was kurz für C-Compiler ist 
und trotzdem den Präprozessor mit einschließt :)

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.