Felix schrieb:> Wie kann ich jetzt aber eine Variable richtig den wert True zuweisen?
z = (x >= y);
Die Klammern sind nicht nötig, liest sich aber IMO angenehmer und
verhindert MISRA-Meckerei.
Nun das ist einfach: z hat den Wert TRUE. Wie der in deinem Fall
aussieht hängt davon ab wie bool bei deinem Compiler umgesetzt ist. ich
würde Mal auf -1 tippen.
Die einzig sichere Aussage ist dass z nicht 0 sein wird.
Thomas
Nop schrieb:> Felix schrieb:>>> Wie kann ich jetzt aber eine Variable richtig den wert True zuweisen?>> z = (x >= y);>> Die Klammern sind nicht nötig, liest sich aber IMO angenehmer und> verhindert MISRA-Meckerei.
Dein Umschreibung ist nicht äquivalent solange die Typen von x und y
nicht bekannt sind.
Jemand schrieb:> Dein Umschreibung ist nicht äquivalent solange die Typen von x und y> nicht bekannt sind.
Wenn man sie abzählbar sind, ist sie äquivalent. Wenn nicht, hat der
Vergleich ohnehin keinen Sinn. Oder hast Du ein Gegenbeispiel?
Felix schrieb:> ich habe eine header, in der TRUE und FALSE> wie folgt definiert sind> #define FALSE 0> #define TRUE !FALSE> damit ist true alles ausser 0.
Das ist falsch. Es gibt genau einen Wert für TRUE und einen Wert für
FALSE. Alle anderen Werte sind weder TRUE noch FALSE, was zu
wunderschöner Verwirrung führen kann.
> Wie kann ich jetzt aber eine Variable richtig den wert True zuweisen?
So:
int x = (y < z) ? TRUE : FALSE;
if(value == wunsch) { result = TRUE; } else { result = FALSE; }
Durch die Definition musst die Werte immer explizit angeben (und
solltest sie auch immer explizit vergleichen).
Diese Definitionen typisch für älteres C, bevor es "bool" als
Standard-Datentyp gab. Man benutzt sie mit "int" oder einem beliebigen
anderen (signed) Integer-Datentyp.
> z.B.bool z;> ...> if(x<y) z=FALSE;> else z=TRUE;>> welchen wert hat z genau?
"z" sollte einen wahren Wert zurückgeben (also ungleich null), aber ob
dieser Wert garantiert gleich TRUE ist, weiß ich nicht.
> MISRA meckert auch, aber wie macht man sowas am besten?> (außer die MISRA-Regel löschen).
Entweder, du nimmst "bool" als Datentyp und "true" bzw. "false" als die
Werte, oder du nimmst "int" als Datentyp und "TRUE" bzw. "FALSE" aus dem
Header. Für letzteres: Sei immer explizit.
Gruß
Nop schrieb:> Jemand schrieb:>>> Dein Umschreibung ist nicht äquivalent solange die Typen von x und y>> nicht bekannt sind.>> Wenn man sie abzählbar sind, ist sie äquivalent. Wenn nicht, hat der> Vergleich ohnehin keinen Sinn. Oder hast Du ein Gegenbeispiel?
Der Vergleich macht zum Beispiel dann Sinn, wenn es ein bestimmter
Wertebereich einen Fehler andeutet, NaN aber ein prinzipiell gültiger
Zustand ist.
Jemand schrieb:> Der Vergleich macht zum Beispiel dann Sinn, wenn es ein bestimmter> Wertebereich einen Fehler andeutet, NaN aber ein prinzipiell gültiger> Zustand ist.
Dann würde der ganze Vergleich nicht funktionieren, weil C keine
besondere float-Repräsentation spezifiziert und somit Verhalten nach
IEEE-754 nicht in C vorausgesetzt werden kann. Dann müßte man schon die
speziellen Vergleichsmakros aus math.h nehmen, was hier aber nicht der
Fall war.
A. K. schrieb:> Scherzfrage dazu. Was kommt bei obigen Definitionen hier raus:int> a[] = { 2, 3 };> int f(void) { return TRUE[a]; }> int g(void) { return (TRUE)[a]; }
Da [] summarisch arbeitet und TRUE 1 ist, ergibt f dasselbe wie *(a +
1), also 3. Sollte bei g ebenfalls der Fall sein, weil TRUE kein
Datentyp ist und das somit kein cast sein kann.
Nop schrieb:> Da [] summarisch arbeitet und TRUE 1 ist, ergibt f dasselbe wie *(a +> 1), also 3.
Nope. [] bindet stärker als !, f ist !0[a] also !(0[a]) also !2 also 0.
Die Idee dazu kam mir anlässlich des generellen Tipps, Operationen in
Präprozessor-Makros immer in () zu schreiben. In weniger bizarren
Fällen überrascht das andernfalls schon mal.
A. K. schrieb:> Nope. [] bindet stärker als !
Ach, und ich hatte schon wieder vergessen, daß das hier überhaupt mit
dem negierenden Makro definiert war.
A. K. schrieb:> Nop schrieb:>> Da [] summarisch arbeitet und TRUE 1 ist, ergibt f dasselbe wie *(a +>> 1), also 3.>> Nope. [] bindet stärker als !, f ist !0[a] also !(0[a]) also !2 also 0.>> Die Idee dazu kam mir anlässlich des generellen Tipps, Operationen in> Präprozessor-Makros immer in () zu schreiben. In weniger bizarren> Fällen überrascht das andernfalls schon mal.
Eine nette Zwischenfrage bei Vorstellungsgesprächen:
Was tut der folgende Code?
Nop schrieb:> Jemand schrieb:>>> Der Vergleich macht zum Beispiel dann Sinn, wenn es ein bestimmter>> Wertebereich einen Fehler andeutet, NaN aber ein prinzipiell gültiger>> Zustand ist.>> Dann würde der ganze Vergleich nicht funktionieren, weil C keine> besondere float-Repräsentation spezifiziert und somit Verhalten nach> IEEE-754 nicht in C vorausgesetzt werden kann. Dann müßte man schon die> speziellen Vergleichsmakros aus math.h nehmen, was hier aber nicht der> Fall war.
C spezifiziert float und double nach IEEE-754 wenn _STDC_IEC_559_ == 1
ist (also praktisch überall).
Heiko L. schrieb:> Eine nette Zwischenfrage bei Vorstellungsgesprächen:> Was tut der folgende Code?> main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
Wer versucht den Mist zu entziffern kann gleich gehen? Die richtige
Antwort ist eine Gegenfrage: "Wird hier Quelltext dieser Art
akzeptiert?"
mh schrieb:> Heiko L. schrieb:>> Eine nette Zwischenfrage bei Vorstellungsgesprächen:>> Was tut der folgende Code?>> main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}>> Wer versucht den Mist zu entziffern kann gleich gehen? Die richtige> Antwort ist eine Gegenfrage: "Wird hier Quelltext dieser Art> akzeptiert?"
Das eine wie das andere würde vielleicht von Charakter zeugen. Fragt
sich, ob man an Charakteren interessiert ist.
Felix schrieb:> ich habe eine header, in der TRUE und FALSE wie folgt definiert sind> #define FALSE 0> #define TRUE !FALSE
Wer schreibt solchen Krampf in irgendwelche Header, was geht in den
Köpfen von solchen Leuten vor? Ist mir auch schon untergekommen, ich hab
die Header samt zugehörigem Code erstmal von dem Dreck reinigen müssen
bevor ich sie verwenden konnte, die haben mir mal den ganzen Datentyp
bool umdefiniert: und zwar als enum!
Ich kann ja verstehen daß man sich in grauer Vorzeit vor der Erfindung
der Posix-Typen irgendwie anders beholfen hat, aber der selbe Header hat
auch regen Gebrauch von stdint.h gemacht und keine Zeile war älter als
2014!
Bernd K. schrieb:> Wer schreibt solchen Krampf in irgendwelche Header,> was geht in den Köpfen von solchen Leuten vor?
In meinem vorherigen Projekt war das Firmenstandard... zusammen Regeln
wie "nur ein return pro Funktion" und "in jedem Block per Makro auf
Fehlerwerte prüfen".
Führte dann zum üblichen Kuriosum:
Nop schrieb:> Heiko L. schrieb:>>> Was tut der folgende Code?>> Im allgemeinen gar nichts, weil er nicht durchcompiliert.
In einer Unix-Umgebung sollte er das. Mal den Link checken.
Nop schrieb:> Im allgemeinen gar nichts, weil er nicht durchcompiliert.
Stimmt nur, wenn "normalerweise" Windows und Mikrocontroller impliziert,
aber kein Linux zulässt.
Heiko L. schrieb:> In einer Unix-Umgebung sollte er das. Mal den Link checken.
In einem Vorstellungsgespräch gibt's keine Links zum Checken, also ist
das die logische Antwort.
A. K. schrieb:> Stimmt nur, wenn "normalerweise" Windows und Mikrocontroller impliziert
Nein. "Im allgemeinen" spezifiziert überhaupt kein bestimmtes OS.
Nop schrieb:> Heiko L. schrieb:>>> In einer Unix-Umgebung sollte er das. Mal den Link checken.>> In einem Vorstellungsgespräch gibt's keine Links zum Checken, also ist> das die logische Antwort.
Naja, wenn du einen Unix-Quelltext nicht von c# unterscheiden kannst...
Was irgendwie schade ist - an einer fast unmöglichen Aufgabe zu
scheitern wäre die eine, zu lamentieren die andere Sache.
Nop schrieb:> In einem Vorstellungsgespräch gibt's keine Links zum Checken, also ist> das die logische Antwort.
Der Witz ist doch gerade, dass es ohne Link gehen soll. Neben
allgemeinem C muss man dafür aber wissen, dass auf Unix- und
Linux-Systemen implizit der Präprozessor-Makro unix definiert wird.
Ich wollte in meiner Scherzfrage aber eher darauf hinweisen, dass man -
wenn schon - TRUE so definieren sollte:
#define TRUE (!FALSE)
Heiko L. schrieb:> Naja, wenn du einen Unix-Quelltext nicht von c# unterscheiden kannst...
Außer, dass da mehrfach das Wort "unix" drin vorkam, hat der Code genau
keine Besonderheit von Unix. Das ist ganz gewöhnliches C, wie man es
auch unter DOS, OS/2 oder sogar CP/M benutzen kann.
A. K. schrieb:> Der Witz ist doch gerade, dass es ohne Link gehen soll. Neben> allgemeinem C muss man dafür aber wissen, dass auf Unix- und> Linux-Systemen implizit der Präprozessor-Makro unix definiert wird.
Unter Windows, TOS, Amiga-OS und zig anderen aber nicht. Wenn ein
Unix-ähnliches System vorausgesetzt wird, sollte das in der
Aufgabenstellung enthalten sein. Das eigentlich Verwirrende fand ich
allerdings mehr, daß die 0 eine Oktal-Sequenz einleitet und kein
String-Terminierer ist.
Nop schrieb:> Nein. "Im allgemeinen" spezifiziert überhaupt kein bestimmtes OS.
Das ist dann allerdings eher eine Frage für Germanisten, nicht so sehr
für Programmierer. ;-)
A. K. schrieb:> Das ist dann allerdings eher eine Frage für Germanisten, nicht so sehr> für Programmierer. ;-)
Auch Entwickler müssen in der Lage sein, Requirements exakt zu verstehen
und zu implementieren. Manchmal allerdings auch das Gegenteil - jede
mögliche Lücke zu entdecken und auszunutzen, um an der Spezifikation
vorbei zu arbeiten. ^^
Nop schrieb:> Unter Windows, TOS, Amiga-OS und zig anderen aber nicht. Wenn ein> Unix-ähnliches System vorausgesetzt wird, sollte das in der> Aufgabenstellung enthalten sein.
Dieser Code ist von 1987. Damals war Unix noch die prägende Umgebung für
Programmierung in C. Und wer heute diese Frage wirklich stellt, der wird
jemanden für eine unixoide Umgebung suchen, nicht für AVR.
> Das eigentlich Verwirrende fand ich> allerdings mehr, daß die 0 eine Oktal-Sequenz einleitet und kein> String-Terminierer ist.
Oktal ist etwas aus der Mode gekommen, war aber 1987 noch häufiger.
A. K. schrieb:> Der Witz ist doch gerade, dass es ohne Link gehen soll. Neben> allgemeinem C muss man dafür aber wissen, dass auf Unix- und> Linux-Systemen implizit der Präprozessor-Makro unix definiert wird.
Wenn ich meine Compiler auf "C" und nicht "GNU" einstelle kommt da immer
ein Fehler.
Darüber hinaus ist die Nutzung des implizit deklarierten printf ab C11
unzulässig, aber das Beispiel ist ja ein gutes Stück älter.
Nop schrieb:> Wenn ein> Unix-ähnliches System vorausgesetzt wird, sollte das in der> Aufgabenstellung enthalten sein.
Das ist nun aber Unsinn. Wenn das Beispiel heißt
1
auto fn() {
2
return sqlExecute("SELECT * FROM customers;");
3
}
ist die Antwort "Kompiliert nicht." ziemlich schwach, oder nicht?
Sonst müsste man ja denken: "Der versteht die Sachen einfach nicht."
Heiko L. schrieb:> Das ist nun aber Unsinn.
Nö, das ist die natürliche Folge von unzureichend spezifizierten
Anforderungen, daß man bekommt, was man gefordert hat, aber nicht
unbedingt, was man hatte haben wollen.
> ist die Antwort "Kompiliert nicht." ziemlich schwach, oder nicht?
Stimmt. Die Antwort "sind Sie sicher, daß es in diesem
Bewerbungsgespräch um die Stellen-ID XYZ geht, auf die ich mich beworben
hatte?" wäre wahrscheinlich kreativer.
Jemand schrieb:> Darüber hinaus ist die Nutzung des implizit deklarierten printf ab C11> unzulässig, aber das Beispiel ist ja ein gutes Stück älter.
Ich finde die Idee nicht falsch, in einem Gespräch nur diese Zeile
abzufragen, ohne jeden Kontext. Wer dann nur mit "Unsinn, nicht
kompilierbar, fertig" kommt, hätte bei mir verloren. Weil solche
Gespräche keine Ankreuzfragen enthalten, sondern den Denkvorgang des
Kandidaten vermitteln sollen.
Dieser Denkvorgang sollte auch bei mittelmässigen Kandidaten zu
implizitem mitgedachtem <stdio.h> führen, diese Zeile nicht als
vollständigen Quelltext ansehen, ggf. entsprechend mit "da fehlt"
kommentiert. Interessanter ist das unix, denn genau da zeigt sich, ob
jemand genug drauf hat, sich den Hintergrund mindestens zu erraten, oder
rückzufragen. Implizite Makros gibt es auf jeder Plattform. Abrufbar
gewusst habe ich das jetzt auch nicht mehr.
Nop schrieb:> Nö, das ist die natürliche Folge von unzureichend spezifizierten> Anforderungen, daß man bekommt, was man gefordert hat, aber nicht> unbedingt, was man hatte haben wollen.
Also musst du erstmal 10000000 Zeilen Quelltext und/oder Doku
durchlesen, bevor du überhaupt anfangen könntest, produktiv zu werden?!
Felix schrieb:> Hallo,>> ich habe eine header, in der TRUE und FALSE wie folgt definiert> sind#define FALSE 0> #define TRUE !FALSE> damit ist true alles ausser 0.>> Wie kann ich jetzt aber eine Variable richtig den wert True zuweisen?
In einer anderen Sprache könnte ich weiterhelfen:
const False = 0
const True = 1
Variable = True
Für was sollen die Möglichkeiten 2 bis 255 nützlich sein?
Wenn ich alle Möglichkeiten von 1 bis 255 zulassen will ist die Frage
If Variable = False then ...
oder umgedreht
If Variable > False then ...
A. K. schrieb:> Wer dann nur mit "Unsinn, nicht> kompilierbar, fertig" kommt, hätte bei mir verloren.
Bei mir hätte der Frager schon mit der Frage verloren, denn wenn man das
ernsthaft in einem Vorstellungsgespräch brächte, würden bei mir alle
Alarmglocken schrillen. Es gibt nämlich nur einen guten Grund, wieso man
gerne jemanden hätte, der auch obfuscated code lesen kann.
Immer dran denken, daß ein Vorstellungsgespräch wie Leuchtspurmunition
ist - funktioniert in beide Richtungen.
Nop schrieb:> A. K. schrieb:>> Wer dann nur mit "Unsinn, nicht>> kompilierbar, fertig" kommt, hätte bei mir verloren.>> Bei mir hätte der Frager schon mit der Frage verloren, denn wenn man das> ernsthaft in einem Vorstellungsgespräch brächte, würden bei mir alle> Alarmglocken schrillen. Es gibt nämlich nur einen guten Grund, wieso man> gerne jemanden hätte, der auch obfuscated code lesen kann.>> Immer dran denken, daß ein Vorstellungsgespräch wie Leuchtspurmunition> ist - funktioniert in beide Richtungen.
Naja, dein völliges Desinteresse für die Frage, was das täte, verriete
im Gegenzug auch einiges. Du trifft das schon ganz gut mit "sich falsch
beworben haben".
Nop schrieb:> Immer dran denken, daß ein Vorstellungsgespräch wie Leuchtspurmunition> ist - funktioniert in beide Richtungen.
Korrekt. Es kommt drauf an, wonach man sucht. Einen C Programmierer von
der Stange (Regeln anderer nutzend), oder jemanden, bei dem nicht nur
das Endprodukt, sondern auch die Sprache selbst eine Rolle spielt (die
Regeln definierend).
Nop schrieb:> A. K. schrieb:>> sondern auch die Sprache selbst eine Rolle spielt>> Soweit mir bekannt, ist "unix" aber nicht Bestandteil des> C-Sprachstandards.
Nee, richtig. Bei der Stelle geht es um Systeme, die es wirklich gibt.
A. K. schrieb:> Jemand schrieb:>> Darüber hinaus ist die Nutzung des implizit deklarierten printf ab C11>> unzulässig, aber das Beispiel ist ja ein gutes Stück älter.>> Ich finde die Idee nicht falsch, in einem Gespräch nur diese Zeile> abzufragen, ohne jeden Kontext. Wer dann nur mit "Unsinn, nicht> kompilierbar, fertig" kommt, hätte bei mir verloren. Weil solche> Gespräche keine Ankreuzfragen enthalten, sondern den Denkvorgang des> Kandidaten vermitteln sollen.>> Dieser Denkvorgang sollte auch bei mittelmässigen Kandidaten zu> implizitem mitgedachtem [...]
Wie reagierst du, wenn der Bewerber bei dieser Frage erstmal die
Handbremse zieht und wissen möchte, ob er bei der zukünftigen Arbeit mit
Quelltexten dieser Art rechnen muss, welcher Standard üblicherweise
genutzt wird und wie die Vorgaben zu magic numbers und
implementation-defined behavior sind.
Nop schrieb:> Soweit mir bekannt, ist "unix" aber nicht Bestandteil des> C-Sprachstandards.
Das wäre eine verständliche Rückfrage im Vorstellungsgespräch an
denjenigen, der die Frage präsentiert. Darauf dann die Antwort "was
könnte es denn sein?".
Ob man dann auf den konkreten Präprozessor-Makro kommt oder nicht ist
unwichtig. Man kann aber mindestens darauf kommen, dass es auf eine Zahl
von 0..4 rauslaufen muss. Gefolgt davon, dass im Format-String nur 0..1
Sinn ergibt.
Kurzum: Kann der Kandidat nur programmieren, oder kann er auch denken
und das kommunizieren? Zugegeben, im Stress eines Vorstellungsgespräch
wäre das anspruchsvoll.
mh schrieb:> Wie reagierst du, wenn der Bewerber bei dieser Frage erstmal die> Handbremse zieht und wissen möchte, ob er bei der zukünftigen Arbeit mit> Quelltexten dieser Art rechnen muss, welcher Standard üblicherweise> genutzt wird und wie die Vorgaben zu magic numbers und> implementation-defined behavior sind.
Auch das wäre eine gute Rückfrage.
A. K. schrieb:> Kurzum: Kann der Kandidat nur programmieren, oder kann er auch denken> und das kommunizieren?
Das kann man allerdings auch mit sinnvolleren Beispielen machen. Mir
würde es zu denken geben, wenn das Vorstellungsgespräch diese durchaus
nachvollziehbaren Anforderungen an einem komplett irrelevanten Beispiel
ergeben soll.
Das verweist auf Defizite jedenfalls im Screening-Prozeß, und die
Ergebnisse davon, also die Belegschaft, wären dessen Ergebnis. Nur noch
übertroffen davon, wenn solche Sourcetexte in der Firma wirklich
praxisrelevant wären.
Zudem sind jedenfalls bei meiner Arbeit die eigentlich anspruchsvollen
Denkaufgaben nicht auf Ebene unleserlichen Sourcecodes anzusiedeln, weil
sowas gar nicht erst durchs Codereview käme.
Als Kniffelaufgabe in der Freizeit schon OK, ich hab's ja auch
rausbekommen, wie der Code funktioniert. Aber in einem
Vorstellungsgespräch hat sowas nichts verloren.
Da wäre etwas wie Nigel Jones' Klassiker mit den 0x10 besten
Vorstellungsgesprächsfragen für embedded-Entwickler doch schon ein
anderes Kaliber.
Nop schrieb:> Da wäre etwas wie Nigel Jones' Klassiker mit den 0x10 besten> Vorstellungsgesprächsfragen für embedded-Entwickler doch schon ein> anderes Kaliber.
Das sicher vollends.
Nop schrieb:> Das eigentlich Verwirrende fand ich> allerdings mehr, daß die 0 eine Oktal-Sequenz einleitet und kein> String-Terminierer ist.
Das Escapezeichen \ gefolgt von einer Ziffer leitet eine Oktal-Sequenz
ein.
Die hat maximal drei Ziffern. Die 0 hat damit erstmal nichts zu tun
\0 kann auch als \000 oder \00 geschrieben werden. Oder als \x0
Das \021 kann auch als \21 geschrieben werden, hat aber den Nachteil,
dass eine mögliche folgende Oktalziffer noch zu dem Wert dazu genommen
wird.
Peter D. schrieb:> Man könnte schreiben:> #include <stdbool.h>> #define TRUE true> #define FALSE false> Aber wozu?
man könnte die beiden Defines auch komplett weglassen denn sie erfüllen
nicht den allergeringsten Zweck außer zur Verwirrung beizutragen.
#define ZWEI 2
#define UND &&
#define VIERZIG 40
Heiko L. schrieb:> Naja, wenn du einen Unix-Quelltext nicht von c# unterscheiden kannst...> Was irgendwie schade ist - an einer fast unmöglichen Aufgabe zu> scheitern wäre die eine, zu lamentieren die andere Sache.
Was soll eigentlich diese Überheblichkeit?
Nannte man früher Schwanzlängenvergleich. Wers braucht ...