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!
@ 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
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
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.
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.
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.
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.
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.
@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
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) ;)
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.
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.
> 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 :)