Eine "Kinderfrage" bzg. *.h und *.c

#4660809
Lesenswert?

Guten Tag,
ich habe eine "Kinderfrage" - das muß eigentlich sehr einfach sein, aber 
ich kapiere das noch nicht. Suche hat auch kein Ergebnis gebracht 
(komischerweise).

Die Frage: wie verteilt man Programm auf mehrere Files?
Ich kenne #include, und soweit ich etwas auf ein *.h - File umplatziere 
und danach mit #include in Haupttext einbinde - dann arbeitet alles so, 
als ob der Inhalt zweiten Files direkt im Text wäre. Aber wenn ich 
versuche, wie empfolen, in *.h nur #define und Prototypen von Funktionen 
zu schreiben, und die Funktionen selbst in dem gleichnahmigen *.c - 
File, dann klappt nichts. Nur Fehlermeldungen.

Ich denke, ich kann nicht richtig *.c und *.h zusammenbinden.
Ob jemand mir bitte erklären könnte, woran das liegt, oder noch besser 
ein Link geben, wo Einbinden von anderen Files beschrieben wird?
Leider gibt meine Suche alles mögliches über C selbst, aber nichts über 
Hantieren mit *.h und *.c.

Vielen Dank im voraus,
Maxim.
#4660826
Lesenswert?

Maxim B. schrieb:
> Aber wenn ich
> versuche, wie empfolen, in *.h nur #define und Prototypen von Funktionen
> zu schreiben, und die Funktionen selbst in dem gleichnahmigen *.c -
> File, dann klappt nichts.

ALLE *.c Files müssen Teil vom Projekt sein.
Die Header kommen dann über die #include Anweisungen dazu.
JEDE *.c muss alle Header einbinden, in denen die Prototypen von 
Funktionen stehen, welche in der jeweiligen *.c verwendet werden.
#4660834
Lesenswert?

>
> Profi-Tip: Die Fehlermeldungen haben sogar einen Text, den man lesen
> kann.
Leider bringt das wenig: nur Info, daß das und das nicht definiert 
wurde. Obwohl in Hauptfile schon alles da und allein mit *.h alles 
arbeitet... Warum mit *.h wird alles richtig kompiliert und mit *.h und 
*.c zusammen nicht? Wie bindet man diese Files zusammen?
#4660838
Lesenswert?

Maxim B. schrieb:
>>
>> Profi-Tip: Die Fehlermeldungen haben sogar einen Text, den man lesen
>> kann.
> Leider bringt das wenig: nur Info, daß das und das nicht definiert
> wurde.

Wenn es eine "undefined reference" Meldung ist, dann bringt die 
Information sehr viel: Dann kommt die Fehlermeldung nämlich nicht vom 
Compiler, sondern vom Linker.

Wie baust Du denn die Software? Mit einer bestimmten IDE? Mit selbst 
geschriebenen makefiles? Anders?
#4660839
Lesenswert?

> JEDE *.c muss alle Header einbinden, in denen die Prototypen von
> Funktionen stehen, welche in der jeweiligen *.c verwendet werden.
Danke!
Bedeutet das, daß ich in *.c alle #include, die im Hauptfile schon 
angegeben sind, wiederholen muß?
Ich weiß - das sind Kinderfragen. Aber noch dummer wäre es, nicht zu 
fragen :)
Gast #4660879
Lesenswert?

Jede .c wird für sich selber übersetzt in ein Objectfile. Das macht der 
Compiler

Dann werden die Objectfiles mit den Bibliotheken zu einem Ausführbaren 
Programm gebunden. Das macht der Linker.

Deine IDE muss jetzt wissen, welche .c-Dateien (und Bibliotheken) zu 
deinem Programm gehören. Dazu gibt es meist ein Project-Menü, in dem man 
das machen kann.

Es geht auch mit der Hand, bzw etwas einfacher mit einem makefile.
#4660885
Lesenswert?

Ich denke, das Problem liegt daran, daß ich in *.h und *.c falsche 
Angaben mache.
Ich habe nun versucht, in "Nebenfile.c" alle #include zu machen.
Nun kommt folgende Spielerei:
wenn ich in *.h keine Variablen gebe und alle nur in Hauptfile, sagt 
Compieler: undefinierte Variable in "Nebenfile.c".
Wenn ich aber die Variablen in *.h platziere und von beiden *.c includen 
lasse, dann sagt Compieler "multiple definition".
Was mache ich falsch?
Gast #4660886
Lesenswert?

Einfaches Beispiel:

myfunction.c:
1
void MyFunction(void)
2
{
3

4
}

Den Prototypen hierzu gibt es in myfunction.h:
1
extern void MyFunction(void);


In jeder Datei, die MyFunction nun verwenden will, muss der Prototyp 
bekannt sein. Dies wird idR durch Inkludierung des Headers gemacht:

main.c:
1
#include "myfunction.h"
2

3
...
4
MyFunction();

Und zwar nicht nur in der Datei, die main() beinhaltet, sondern in jeder 
Datei, die MyFunction aufruft:

AnderesModul.c:
1
#include "myfunction.h"
2

3
...
4
MyFunction();

Auch in myfunction.c ist es aus mehreren Gründen empfehlenswert, 
myfunction.h einzubinden.
Gast #4660892
Lesenswert?

Nachtrag:

Zunächst mal sind globale Variablen nicht unbedingt empfehlenswert. Um 
eine Mehrfachdefinition zu verhindern, bedient man sich eines so 
genannten "Include Guards":

myfunction.h:
1
#ifndef _MYFUNCTION_H_
2
#define _MYFUNCTION_H_
3

4
hier kommt der eigentliche Inhalt des Headerfiles
5

6
#endif
Gast #4660901
Lesenswert?

Noch ein Nachtrag:

Wenn du eine globale Variable in main.c anlegst, dann kannst du auch aus 
anderen Modulen daraus zugreifen, wenn die Variable dem Modul vorher 
bekannt gemacht wird:

main.c:
1
uint32_t MyVar = 0;

nebenfile.c:
1
extern uint32_t MyVar;
2

3
MyVar = 12345ul;

Wie gesagt versucht man aber normalerweise, globale Variablen zu 
vermeiden. Die Gründe und Argumente hierfür sind vielfältig. Bei Deinem 
ersten C-Programm kann man aber wohl darüber hinwegsehen.
#4660916
Lesenswert?

Maxim B. schrieb:
> Wenn ich aber die Variablen in *.h platziere und von beiden *.c includen
> lasse, dann sagt Compieler "multiple definition".
> Was mache ich falsch?

Wenn du das machst, dann wird ja, wie du ganz oben schon selber gesagt 
hast, der Text des Headers beiden *.c Dateien zugefügt.
Das ist also genau das gleiche, als ob du in beiden *.c die gleiche 
globale Variable definierst.
"Definitionen" im Sinne von etwas, dass direkt Programmcode erzeugt oder 
Speicherplatz reserviert, haben in einem Header nichts verloren!
#4660921
Lesenswert?

Vielen Dank!
Um klarer zu machen, wo ich hinke, gebe ich hier die Dateien aus meinem 
Probeprojekt:

Vielen Dank im voraus für Fehleranweisungen!
Hier geht es um ein Voltmeter für sehr rauscharme Umgebung, daher 
statische LED.

Bestimmt fehlt mir noch Klarheit, was wohin gehört...
Angehängte Dateien:
Gast #4660929
Lesenswert?

Maxim B. schrieb:
> Bestimmt fehlt mir noch Klarheit, was wohin gehört...

Variablen sollte nicht in .h Dateien angelegt werden.
1
volatile int volt = PWM_init / 2; //

dort sollte sie nur als Extern vorhanden sein.
1
extern volatile int Volt;

und dann müssten sie in die passende C rein.
1
volatile int volt = PWM_init / 2; //
#4660931
Lesenswert?

Build started 26.7.2016 at 13:26:38
avr-gcc -mmcu=atmega324pa -Wl,-Map=Voltmeter_2016_07_24_v3.map 
Voltmeter_2016_07_24_v3.o Ind_stat.o     -o Voltmeter_2016_07_24_v3.elf
Ind_stat.o: In function `vyvod':
D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik\2016_07_Voltmeter\Program 
m\Voltmeter_2016_07_24_v3\default/../Ind_stat.c:12:  multiple definition 
of `zif1'
Voltmeter_2016_07_24_v3.o:D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik 
\2016_07_Voltmeter\Programm\Voltmeter_2016_07_24_v3\default/../Voltmeter 
_2016_07_24_v3.c:45:  first defined here
Ind_stat.o: In function `vyvod':
D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik\2016_07_Voltmeter\Program 
m\Voltmeter_2016_07_24_v3\default/../Ind_stat.c:12:  multiple definition 
of `zif2'
Voltmeter_2016_07_24_v3.o:D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik 
\2016_07_Voltmeter\Programm\Voltmeter_2016_07_24_v3\default/../Voltmeter 
_2016_07_24_v3.c:45:  first defined here
Ind_stat.o: In function `vyvod':
D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik\2016_07_Voltmeter\Program 
m\Voltmeter_2016_07_24_v3\default/../Ind_stat.c:12:  multiple definition 
of `zif3'
Voltmeter_2016_07_24_v3.o:D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik 
\2016_07_Voltmeter\Programm\Voltmeter_2016_07_24_v3\default/../Voltmeter 
_2016_07_24_v3.c:45:  first defined here
Ind_stat.o: In function `vyvod':
D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik\2016_07_Voltmeter\Program 
m\Voltmeter_2016_07_24_v3\default/../Ind_stat.c:12:  multiple definition 
of `zif4'
Voltmeter_2016_07_24_v3.o:D:\A_Radioelementen_Daten\ZZ_Projekt\Schematik 
\2016_07_Voltmeter\Programm\Voltmeter_2016_07_24_v3\default/../Voltmeter 
_2016_07_24_v3.c:45:  first defined here
Ind_stat.o:(.data+0x0): multiple definition of `volt'
Voltmeter_2016_07_24_v3.o:(.data+0x0): first defined here
make: *** [Voltmeter_2016_07_24_v3.elf] Error 1
Build failed with 1 errors and 0 warnings...

Es tut mir leid, aber ich verstehe Englisch nur so halbwegs... mehrfache 
definition von Var. - das ist mir klar. Aber warum und wie ist das zu 
verbessern?
Gast #4660959
Lesenswert?

Maxim B. schrieb:
> Es tut mir leid: ich kapiere immer noch nicht...
> Wenn ich eine Var. in beiden *.c verwende - wo muß ich sie deklarieren?
> In Hauptfile, in Nebenfile oder in Header?

jede Variabel darf nur EINMAL deklariert werden. Damit kann es nicht in 
einer Header Datei sein.

zu jeder .h gibt es meist eine .c und dort gehört die Variable rein.

Und es müssen nur Funktionen in der .h die außerhalb er .c genutzt 
werden sollen.
#4660964
Lesenswert?

Na, Danke an alle! Geklappt!
Aber ich sollte eine Zeile in Hauptfile ändern:
statt
  OCR1B = volt; // PWM in Halbe
sollte ich schreiben
  OCR1B = PWM_init/2; // PWM in Halbe
Dann blieb var. volt nur für Ind_stat.c und auch nur dort erklärt.

Nun läuft Programm als ob alles in einem File... Wie auch gedacht...

Aber trotzdem: wenn ich eine Var. in mehreren Files verwende, wo genau 
und wie wäre sie zu deklarieren? Ich möchte das verstehen...
#4660973
Lesenswert?

Maxim B. schrieb:
> Na, Danke an alle! Geklappt!
> Aber ich sollte eine Zeile in Hauptfile ändern:
> statt
>   OCR1B = volt; // PWM in Halbe
> sollte ich schreiben
>   OCR1B = PWM_init/2; // PWM in Halbe
> Dann blieb var. volt nur für Ind_stat.c und auch nur dort erklärt.

Bravo ;-)

Maxim B. schrieb:
> Aber trotzdem: wenn ich eine Var. in mehreren Files verwende, wo genau
> und wie wäre sie zu deklarieren? Ich möchte das verstehen...

Da wo die Variable eben logisch hin gehört. Definiert wird sie in dem 
logisch zugehörigen *.c File und im entsprechenden Header als extern 
deklariert, damit der Compiler bei anderen *.c Files die diesen Header 
einbinden weiß, dass es diese Variable irgendwo gibt und wie sie 
Aussieht.
Da soll sich dann später der Linker darum kümmern, ob das alles so 
wirklich passt ;-)
#4660975
Lesenswert?

Maxim B. schrieb:
> Aber trotzdem: wenn ich eine Var. in mehreren Files verwende, wo genau
> und wie wäre sie zu deklarieren? Ich möchte das verstehen...

Wenn Du schon globale Variablen verwendest, dann sollten diese 
wenigstens nur in einem einzigen Modul beschrieben werden. Dieses Modul 
ist dann sozusagen der Besitzer dieser Variablen, hier wird der 
Speicherplatz dafür angelegt. Die anderen Module lesen diese Variable 
nur.

Noch besser wäre es, auf globale Variablen ganz zu verzichten - oder 
zumindest überall da, wo es möglich ist.

Kauf Dir ein Buch über C-Programmierung!
Moderator Persönliche Seite #4660980
Lesenswert?

Peter II schrieb:
> jede Variabel darf nur EINMAL deklariert werden. Damit kann es nicht in
> einer Header Datei sein.

Falsch.

Jede Variable kann so oft Du willst deklariert werden. Aber sie darf nur 
einmal definiert werden.

Das ist die Definition:

int foo;

Das ist die Deklaration:

extern int foo;

Und das ist für einen C-Compiler kein Problem:

extern int foo;
extern int foo;
extern int foo;
extern int foo;
int foo;

Du hast offenbar Definition und Deklaration verwechselt.
#4660982
Lesenswert?

Maxim B. schrieb:
> Aber trotzdem: wenn ich eine Var. in mehreren Files verwende, wo genau
> und wie wäre sie zu deklarieren? Ich möchte das verstehen...

Volker S. schrieb:
> "Definitionen" im Sinne von etwas, dass direkt Programmcode erzeugt oder
> Speicherplatz reserviert, haben in einem Header nichts verloren!

Wenn du eine Funktion/Variable definierst, dann wird dafür Speicher 
verbraucht.
Darf nur einmal gemacht werden. Das gehört in eine C-Datei

Wenn du eine Funktion/Variable deklarierst, dann gibst du dem Compiler 
bekannt, das ein Objekt mit diesem Namen existiert. Kann oft gemacht 
werden.
Das gehört in eine H-Datei, aber nur, wenn diese Information ausserhalb 
der eigenen C-Datei gebraucht wird.

Da du aus main nur ismerenie und indikator aufrufst, brauchst du die 
anderen Funktionen auch nicht in der H-Datei deklarieren.
#4660993
Lesenswert?

Maxim B. schrieb:
> Z.B. wenn eine Var. in ISR geändert wird und von vielen anderen
> Funktionen abgefragt - wo und wie muß sie gefiniert werden?

Da würde ich auf das Main-C-File "tippen". Also die Datei, welche die 
Definition der Funktion main() enthält.
Dann meinetwegen in einem Header Namens "global....h" als extern 
deklarieren und diesen in allen C-Files einbinden die auf die Variable 
zugreifen.
Grundsätzlich aber trotzdem überlegen, ob es nicht manchmal doch besser 
ist, Variablen beim Funktionsaufruf zu übergeben.
#4660998
Lesenswert?

Danke!
Ich habe in global.h geschrieben
extern volatile int volt;
und in
Ind_stat.c volatile int volt = PWM_init / 2;
weiter zurück gemacht bei Init in Voltmeter_2016_07_24_v3.c:
OCR1B = volt; // PWM in Halbe

Ist das so korrekt?
Programm scheint zu funktionieren, aber ich möchte für die Zukunft 
wissen...

Über das Buch habe ich auch schon gedacht. Aber von Bildschirm leichter 
zu lesen...
Es gibt viele Bücher und viel Kritik... Wenn ich nach PDFs beurteilen 
darf, es gibt überall etwas Wichtiges, was nicht besprochen wird. Z.B. 
über heutige Problem habe ich nirgendwo etwas gefunden... Obwohl ich 
auch schon Bloodshed Dev-C++ installiert habe - um mit C als solcher 
etwas vertrauter zu werden (obwohl mein Ziel ausschließlich 
Mikrokontroller sind)...

Welches Buch wäre am besten?
Gast #4661000
Lesenswert?

Maxim B. schrieb:
> Wenn ich eine Var. in beiden *.c verwende - wo muß ich sie deklarieren?
> In Hauptfile, in Nebenfile oder in Header?

Modul1.c:
1
int Var = 0;

Modul1.h:
[c}
extern int Var;
1
Modul2.c:
2
[c]
3
#include "Modul1.h"
4
...
5
Var = 1;

Das ist jetzt nochmal exakt das Gleiche, das ich oben schon mal 
beschrieben habe! Es gibt im Allgemeinen auch keine "Haupt- und 
Nebenfiles". Die  main() stellt lediglich den Einsprungpunkt dar, nicht 
mehr und nicht weniger.
Gast #4661013
Lesenswert?

Irgendwas ist mit der Formatierung durcheinandergekommen, hier nochmal 
richtig:

Modul1.c:
1
int Var = 0;


Modul1.h:
1
extern int Var;


Modul2.c:
1
#include "Modul1.h"
2
...
3
Var = 1;


Rein theoretisch geht das auch ohne Header, Modul2.c müsste dann eben 
direkt die Deklaration enthalten:

Modul2.c
1
extern int Var;
2
...
3
Var = 1;
#4661016
Lesenswert?

Maxim B. schrieb:
> Volker S. schrieb:
>
>> Vielleicht das nächste mal in einem russischsprachigem Forum posten ;-)
>
> Danke für Tipp. Würde ich weiter ein russischer Bürger bleiben und in
> Rußland leben, so würde ich so auch tun.

Sollte nur ein kleiner Wink mit dem Zaunpfahl sein. Es ist für die Leute 
hier doch viel einfacher, wenn Namen von Funktionen und Variablen 
verständlich sind. Du scheinst ja auf jeden Fall keine Probleme mit der 
deutschen Sprache zu haben. Da ist es doch eine nette kleine zusätzliche 
Übung auch deutsche Namen zu vergeben. (Ich versuche das zur Übung alles 
auf Englisch)
#4661021
Lesenswert?

Volker S. schrieb:
Es ist für die Leute
> hier doch viel einfacher, wenn Namen von Funktionen und Variablen
> verständlich sind. Du scheinst ja auf jeden Fall keine Probleme mit der
> deutschen Sprache zu haben.
Ich habe das auch nicht böse gemeint. Obwohl außer Thema - ich möchte 
mit Dank sagen, daß Deutschland vielleicht einziges Land auf der Erde 
bleibt, wo auch die Ausländer in der Hochschule kostenlos studieren 
dürfen! Ohne dieser Option könnte ich hier nie sein...

Ja, ich habe vor dem Posten alle Kommentare auf Russisch für Kommentare 
auf Deutsch ersetzt. Aber die Namen von Funktionen irgendwie verpaßt, zu 
korrigieren... Ich wußte nicht, daß das so reizen kann...

Hier in Pritzwalk reagieren die Leute auf Russisch eher mit Nostalgie 
und nie mit Abneigung.

Kommentar muß vor allem für mich selber so verständlich wie nur möglich 
sein - davon ging ich aus.
Moderator Persönliche Seite #4661028
Lesenswert?

Honk schrieb:
> Modul1.c:int Var = 0;
>
> Modul1.h:extern int Var;
>
> Modul2.c:#include "Modul1.h"
> ...
> Var = 1;


Ich empfehle, Modul1.h zusätzlich auch in Modul1.c zu "inkludieren", 
also:

Modul1.c:
1
#include "Modul1.h"
2
int Var = 0;

Das hat einen - nicht auf Anhieb ersichtlichen - aber einfachen Grund: 
So meckert der Compiler sofort, wenn man versehenlich eine Variable 
inkonsistent definiert, z.B.:

Modul1.c:int Var = 0;

Modul1.h:extern double Var;

Modul2.c:#include "Modul1.h"
...
Var = 1;

Diese Situation fällt nicht auf! Im Programm passiert dann garantiert 
nicht das erwartete!

Wenn aber das Include-Statement in jedem relevanten C-Modul steht:

Modul1.c:#include "Modul1.h"
int Var = 0;

... dann kann der Compiler sofort eine Fehlermeldung ausgeben.
#4661033
Lesenswert?

Maxim B. schrieb:
> Ich wußte nicht, daß das so reizen kann...

Also zumindest ich bin überhaupt nicht gereizt.
Da bin ich viel zu sehr abgehärtet von unseren Studierenden.
Wenn die einen Variablennamen mit zehn Zeichen vergeben, dann sind dann 
oft max. zwei bis drei Zeichen dabei, welches die Variable und deren 
Zweck irgendwie sinnvoll beschreibt. "Variable_1" oder so was sehe ich 
auch recht häufig ;-)
#4661048
Lesenswert?

Volker S. schrieb:

> Also zumindest ich bin überhaupt nicht gereizt.

das ist gut. Ich habe mich zuerst so gewundert: bisher habe ich in etwa 
10 Jahren in D. nur einmal oder zweimal überhaupt etwas erlebt, was man 
annähernd als Unfreundlichkeit gegen Ausländern bezeichnen kann... :) In 
TV erzählt man viel Schreckchen, das ist aber weit vom Leben entfernt...

Ja, ich verstehe schon: wenn man an die Studierende täglich etwas sagt 
und wieder und immer noch und sie hören sowieso nicht... :)
Ich habe Musik studiert, bei uns ist das weniger stark geprägt, weil 
Unterricht meistens 1:1 ist. Aber ich kann schon einen Dozenten gut 
verstehen...
Moderator Persönliche Seite #4661053
Lesenswert?

Maxim B. schrieb:
> Modul1.c: zusätzlich als Prüfung: #include "Modul1.h" vor der Variable
> mit Wert
>
> Alles richtig?

Jepp, so ist es richtig. Übrigens macht man es so auch für die 
Definitionen/Deklarationen von Funktionen - also wenn man 
modulübergreifend eine Funktion aufruft:

Modul1.c:
1
#include "Modul1.h"
2

3
int foo (int a, int b)
4
{
5
   bar (a, b);
6
}

Modul1.h:
1
extern int foo (int);

Modul2.h:
1
#include "Modul1.h"
2
...
3
   foo (123);

Erst durch das include in Modul1.c fällt auf, dass die Funktion foo() 
eigentlich zwei Parameter braucht.
Moderator Persönliche Seite #4661070
Lesenswert?

Maxim B. schrieb:
> Dann aber stimmt Prototyp und Funktion nicht mehr überein?

Ja. Das fällt nur auf, wenn Modul1.h auch in Modul1.c includiert wird. 
Sonst ist der Prototyp einfach für die Katz.

Im Laufe der Software-Entwicklung kommt es immer wieder vor, dass 
Funktionen um zusätzliche Parameter erweitert werden. Nur so merkt man, 
dass man nicht alles andere vollständig angepasst hat. Es gibt noch 
nichtmals einen Fehler vom Compiler und man sucht sich dumm und 
dusselig.
#4661084
Lesenswert?

Maxim B. schrieb:
> ich möchte
> mit Dank sagen, daß Deutschland vielleicht einziges Land auf der Erde
> bleibt, wo auch die Ausländer in der Hochschule kostenlos studieren
> dürfen!
Danke!

Das ist was leider viele nicht verstehen, du hast es wenigstens mal 
benannt!
(ok rel. kostenlos, oder sind Studiengebühren wieder abgeschafft?)

Zu dem Sprachmix, ich hatte mal in einem Großraumbüro Prüfgeräte 
entwickelt und die Prüfsoftware geschrieben,

es war kein Problem Gespräche am Nachbartisch in deutsch auszublenden 
oder mitzuhören je nach dem (wir hatten durchaus Themenüberschneidungen 
bei denen ein kollegialer Austausch sinnvoll war), aber wenn die 
Kollegen auf türkisch anfingen zu reden konnte ich mich nicht mehr 
konzentrieren, mein Kopf versuchte immer zu verstehen was geredet wurde, 
ausblenden unmöglich.

Deswegen zur besseren Lesbarkeit hier für die meisten User zur späteren 
Hilfestellung scheinen deutsche lesbare Vasiablen- und Funktionsnamen 
sinnvoll.
#4661099
Lesenswert?

Joachim B. schrieb:
> (ok rel. kostenlos, oder sind Studiengebühren wieder abgeschafft?)

Ja, die "Studiengebühren" (für das Erststudium) sind soweit ich weiß 
wieder abgeschafft. Es gibt allerdings noch "Verwaltungsgebühren" und 
Beiträge zum Studierendenwerk ...
z.B. an der Hochschule Ulm 
https://studium.hs-ulm.de/de/Seiten/Beitraege_Gebuehren.aspx?SearchCategory=Studienstart;
Moderator Persönliche Seite #4661108
Lesenswert?

Joachim B. schrieb:
> Deswegen zur besseren Lesbarkeit hier für die meisten User zur späteren
> Hilfestellung scheinen deutsche lesbare Vasiablen- und Funktionsnamen
> sinnvoll.

Meiner Ansicht nach hinkt Dein Vergleich. Man muss die Variablen- und 
Funktionsnamen ja nun nicht deshalb unbedingt auf türkisch schreiben.

Ich finde es zum Beispiel prägnanter...
1
void delay (int msec)
2
{
3
   ...
4
}
zu schreiben als:
1
void Verzoegerung (int msek)
2
{
3
   ...
4
}

Diesen Mischmasch aus deutschen Bezeichnernamen und englischen 
Schlüsselwörtern finde ich genauso anstrengend wie das Zuhören von 
türkischsprachigen Tischnachbarn :-)

Aber dem kann man ja Abhilfe schaffen:
1
#define Zeichen                      char
2
#define Hauptfunktion                main
3
#define Ganzzahl                     int
4
#define LangeGanzzahl                long    
5
#define Gleitkommazahl               float   
6
#define DoppeltGenaueGleitkommazahl  double  
7
#define Fuer                         for
8
#define Waehrend                     while
9
#define GebeZurueck                  return
10

11
Dann siehts so aus:
12

13
Ganzzahl Hauptfunktion ()
14
{
15
    Ganzzahl Zaehler;
16
    Zeichen Buchstabe;
17

18
    Fuer (Zaehler = 0; Zaehler < 100; Zaehler++)
19
    {
20
        Waehrend (ZeichenAusUartNichtBereit ())
21
        {
22
             WarteDochEinWeilchenUndPfeifSolangEinLiedchen ();
23
        }
24
        Buchstabe = ZeichenAusUartAuslesen ();
25
        ZeichenWiederAusgeben (Buchstabe);
26
    }
27
    GebeZurueck 0;
28
}

Mir wird gerade schlecht....
#4661119
Lesenswert?

Frank M. schrieb:
> Mir wird gerade schlecht....

Witzig, genau so was habe ich vor einigen Jahren für Kinder geschrieben:
1
#ifndef _DEUTSCH_H
2
#define _DEUTSCH_H
3

4
// Anschluesse
5

6
//allgemein
7
#define EINGANG     1
8
#define AUSGANG     0
9
...
10

11
// Befehle ???
12
#define solange     while
13
#define fuer        for
14
#define wenn        if
15
#define sonst       else
16
#define wiederhole  do
17

18
#define pruefe      switch
19
#define falls       case
20
#define fertig      break
21
#define falls_nichts default
22

23
#define fuerimmer()         while(1)
24
#define bleib_hier_stehen() while(1){;}
25

26
#define in_anderer_datei extern
27

28
#define zahl_0_255      unsigned char
29
#define zahl_0_65536    unsigned short
30

31
#define aufzaehlung     enum
32
#define typendefinition typedef
33

34
// Operatoren
35
//#define umgedreht ~
36

37
// Funktionen ???
38
#define hauptprogramm()       void main(void)
39
#define starteinstellungen()   void __init(void)
40

41
#define pause() _asm nop nop nop nop nop nop nop nop nop nop nop nop _endasm
42
...

Das Hauptprogramm sah dann so aus:
1
//void main()
2
hauptprogramm()
3
{
4

5
  tasten.ALLE = 0;  // Tastenbenachrichtigung löschen
6
  menue = FANGDENPUNKT;        // Startmenue festelegen
7

8
  fuerimmer(){
9
    wenn(tasten.T_S){LED_RGB = 0; tasten.T_S = 0; wenn(menue > 0) menue--;}// > erstes Menue
10
    wenn(tasten.T_K){LED_RGB = 0; tasten.T_K = 0; wenn(menue < (LETZTES_MENUE)) menue++;}
11

12
    pruefe (menue){
13
          falls DIGITALPOTI: digitalisieren(); fertig;
14
          falls HELLER_DUNKLER : hellerdunkler(); fertig;
15
          falls RGB: rotgruenblau(); fertig;
16
          falls ZAEHLEN: zaehlen(); fertig;
17
          falls MULTIPLIZIEREN: multiplizieren(); fertig;
18
          falls FARBEN: farbenmischen(); fertig;
19
          falls BILDER: bilder(); fertig;
20
          falls PUNKT: wanderpunkt(); punktanzeigen(); fertig;
21
          falls JOYSTICK: joystick(); positionanzeigen(); fertig;
22
          falls FANGDENPUNKT: zufall(); joystick(); fangdenpunkt(); fertig;
23
//          falls MALEN: malen(); fertig;
24
//          falls TEXT: text(); fertig;
25
//          falls LAUFSCHRIFT: laufschrift(); fertig;
26
//          falls TOENE: toeneabspielen(); fertig;
27
          falls_nichts: menue = 0; fertig;  // nur zur Sicherheit ;-)
28
    }
29
  }
30
}
#4661211
Lesenswert?

Maxim B. schrieb:
> Mark B. schrieb:
>> Was um alles in der Welt soll "ismerenie" und "vyvod" bedeuten?
>>
> Als eingebürgerte Russe erlaube ich mir ab und zu auch mit russischen
> Worten hantieren :) Für mich sind sie verständlich :) Ich bin in
> Elektronik ein Liebhaber, schreibe eigentlich nur für mich selbst.
>
> ismerenie heißt Messen
> vyvod heißt Ausgabe.

Nun ja. So hast Du halt einen Mischmasch:

-manches ist auf Englisch, z.B. PWM_init
-manches ist auf Russisch, z.B. ismerenie
-manches ist auf Deutsch,  z.B. Null_volt

Wenn Du da noch durchblickst und es ein Projekt für Dich allein ist... 
okay.

Sobald mehr als ein Entwickler ins Spiel kommt (also im beruflichen 
Kontext fast immer), sollte man sich dann schon auf eine Sprache 
einigen und die dann auch konsequent überall verwenden.
Gast #4661427
Lesenswert?

Maxim B. schrieb:
> Ich denke, ich kann nicht richtig *.c und *.h zusammenbinden.

Es ist eigentlich ganz einfach. Mit einem Eintrag #include "dateiname" 
kannst du beliebige Dateien in deine C-Quelle einbinden. Ob sowas nun 
auf .h endet oder irgendwie anders, ist im Grunde völlig egal. Das *.h 
hat man sich lediglich angewöhnt.

Die Frage steht nun, was denn in so einer *.h Datei stehen muß. Antwort: 
Alles, was die aufrufenden Programme von der C-Datei wissen müssen, auf 
die sich die .h Datei bezieht. Und alles andere eben NICHT. Schreib also 
nur das Nötigste in eine .h Datei hinein. Ausgenommen sind sinnvolle 
Kommentare, die du oder ein anderer nach 5 Jahren immer noch versteht.

Beispiel: ein UART, also eine serielle Schnittstelle. Für sowas schreibt 
man zumeist einen separaten Handler, damit sich höhere Programmschichten 
nicht um die Einzelheiten der Schnittstelle kümmern müssen.
Im Treiber uart.c kommen z.B. vor:

void Char_Out(char c)
{ ...
}
und
char Char_In(void)
{ ...
}
und
void Init_Uart(long Baudrate)
{ ...
}

Also schreibt man sich eine Headerdatei uart.h, wo dann folgendes 
hineinkommt:

/* UART-Anschluss von Maxim */
#ifndef Maxims_Uart
#define Maxims_Uart
extern void Char_Out(char c);
extern char Char_In(void);
extern void Init_Uart(long Baudrate);
#endif

Wenn eine andere C-Quelle, z.B. burtsev.c jetzt diese uart.h Datei 
einbindet, dann kann man die Funktionen von uart.c dort in burtsev.c 
benutzen, weil ja der Compiler alles weiß, was er zum Aufrufen von 
Char_Out und so wissen muß. Obendrein weiß er, daß alle diese Funktionen 
nicht in der burtsev.c vorkommen, sondern woanders stehen. Er wird 
deswegen auch nicht meckern, daß ja die Funktionsrümpfe fehlen. Das 
macht dann viel später der Linker, falls ihm was fehlt.
Man bindet normalerweise die eigene .h auch in die C-Quelle mit ein, 
damit der Compiler die Konsistenz zwischen den Prototypen und den 
eigentlichen Funktionen prüfen kann. Das "extern" stört dabei nicht. Das 
mit dem #ifndef.. und #define dient dazu, bei Mehrfacheinbindung 
derselben Headerdatei keine eventuellen Duplikate zu bekommen. Ist 
normalerweise bei sauberer Programmierung überflüssig, aber ich mach 
sowas immer und aus Prinzip.

Und wenn dein Treiber so etwas wie ein struct benötigt, was auch die 
aufrufenden Programmteile kennen müssen, dann schreibt man die 
Definition dieses struct's in die .h Datei. Wenn das aber was internes 
ist, und alle anderen Programmteile davon nichts wissen müssen, dann 
schreibt man es in die C-Quelle und nicht in die zugehörige .h hinein, 
denn das würde nur den Rest der Welt verwirren.

Nochwas: Deine Frage ist durchaus KEINE Kinderfrage, sondern eine sehr 
ernste Frage.

W.S.
#4662545
Lesenswert?

Vielen Dank für die Erklärungen!
Das ist für mich sehr, sehr wert!

Ich werde sicher nie ein Profi in diesem Bereich, mein Unterhalt 
verdiene ich an der Orgel - aber das alles macht mir viel Spaß!
Außerdem gibt es viele Kleinigkeiten, die nur ich alleine brauche oder 
nur wenige Kollege - dann ist das nicht zu kaufen und nur selbst zu 
basteln...

Mit *.h und *.c ist besonders wichtig, da die Klarheit hier auch die 
Bibliotheke von Anderen zu nutzen ermöglicht. So wie i2c oder für 
Indikator.

Vielen Dank!

Was die Sprache betrifft: innerlich sind das für mich keine zwei 
Sprachen, sondern eine große Sprache, die Russisch und Deutsch mit 
einschließt. Mit der Zeit geht es immer leichter, zwischen den Sprachen 
umzuschalten, und irgendwann gibt es die Grenze nicht mehr... Auch wenn 
bei mir herum in der Familie alles nur deutschsprachig ist... Da ich ein 
Musiker bin, war alles für mich dadurch einfacher, weil die Noten auf 
allen Sprachen gleich aussehen (nur in Buchstab-Notation gibt es 
Unterschiede zwischen Englischen und Deutschen: die Engländer schreiben 
komischerweise statt "H" "B" und statt "B" "B mit be" - das ist 
gewöhnungsbedürftig!. Im russissprachigen Raum nutzt man deutsche 
Variante (außer in Pop-Musik).
#4662611
Lesenswert?

Maxim B. schrieb:
> Was die Sprache betrifft: innerlich sind das für mich keine zwei
> Sprachen, sondern eine große Sprache, die Russisch und Deutsch mit
> einschließt. Mit der Zeit geht es immer leichter, zwischen den Sprachen
> umzuschalten, und irgendwann gibt es die Grenze nicht mehr...

Naja, dann kannst du diese Fähigkeit nutzen, um Code zu schreiben, den 
nur wenige Leute verstehen.

> Musiker bin, war alles für mich dadurch einfacher, weil die Noten auf
> allen Sprachen gleich aussehen (nur in Buchstab-Notation gibt es
> Unterschiede zwischen Englischen und Deutschen: die Engländer schreiben
> komischerweise statt "H" "B"

Ich würde es umgekehrt sagen: Die Deutschen schreiben komischerweise 
statt "B" "H". Ich hab mich schon in der Grundschule gefragt, warum um 
alles in der Welt das H zwischen dem A und dem C steht und nicht das B.
Gast #4682680
Lesenswert?

Rolf M. schrieb:
> warum um
> alles in der Welt das H zwischen dem A und dem C steht und nicht das B.

Weil die musikalische Tradition in Deutschland sehr lang und tief ist. 
Historisch war Tonleiter kein Dur oder moll, wie die meisten es heute 
kennen, sondern gerade A-B-C-D-E-F-G. "H" kam erst viel später in 
Gebrauch, deshalb hat nächste Zeichen bekommen, noch frei.
Andere länder (englichsprachigen) kennen keine so lange musikalische 
Tradition wie Deutschland. Sie haben alles übernommen, wie Tonleiter 
schon längst komplettiert wurde. Für die schien es einfacher, statt "H" 
"B" zu schreiben, was die Profi in D. eher als mangelhafte Ausbildung 
wahrnehmen.
Gast #4684446
Lesenswert?

Ich muss mal meinen Senf dazugeben, wenns OK ist...
Dieser Thread ist in meinen Augen der wichtigste zum Thema C 
überhaupt!!!
Hier wird etwas behandelt was ich schon bestimmt 1 Million mal falsch 
gemacht habe. Danke dafür!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren