Variablen Benennung C++

Gast #6346318
Lesenswert?

Wenn man mit Ländern mit imperialen Einheiten zusammenarbeitet sicher. 
Sonst geben die das noch in sqft*oz/psi an…
Allgemein würde ich aber in Basiseinheiten rechnen und die Einheit im 
Kommentar angeben.
#6346320
Lesenswert?

Wenn es sinnvoll ist, ja, wenn nicht, dann nicht. Das gilt eigentlich 
für alle Variablennamen...

Wobei C++ zum Handling von solchen physikalischen Größen mit 
unterschiedlichen Einheiten benutzerdefinierte Literale bietet, die da 
sehr viel Sicherheit reinbringen. Aussagekräftige Variablennamen kann 
man dazu dann immer noch nutzen.

Oliver
Gast #6346330
Lesenswert?

Bei einer Frequnez würde ich von Hz ausgehen, wenn nichts andere dran 
steht. bei Zeitspannen macht das eher Sinn:

duration_ms
timeout_minutes

Oder auch:

price_cent

Mir persönlich genügt es, wenn das in einem Kommentar direkt über der 
Variable bzw. Funktion (bei Parametern) dokumentiert ist.
Gast #6346372
Lesenswert?

Anonymous U. schrieb:
> Wie denkt ihr darüber?

Ich sage, denke und handle ....

Variablen immer klein beginnen.
KamelHöckerSchreibweise
Keine Unterstriche
Keine ungarische Notation (noch nicht mal in deiner abgeschwächten 
Version)
Geltungsbereich so weit wie irgend möglich einschränken.

Oliver S. schrieb:
> benutzerdefinierte Literale
Ja!

Beispiel(aus meiner kleinen Arduino Welt):
1
const Millis interval {25_ms};
Gast #6346378
Lesenswert?

Wenn Du mehrere Formate für Frequenz hast, dann mache einen Typ daraus.

Bei nur einem wäre es dumm, da es keine Info birgt und das über den Code 
verteilt wird.

Bei mehreren wäre es unzureichend, da Du ja unterschiedliche Funktionen 
damit aufrufen musst.
Gast #6346387
Lesenswert?

Anonymous U. schrieb:
> Wie denkt ihr darüber?

Beide verstehe ich nicht.

Eine Frequenz f in Hz könnte in einer Variablen namens frequency_Hz 
stecken.

Aber das frequency_is_1Hz bedeuten soll ? Ein boolscher Wert der nur 
dann tru ist wenn die Frequenz genau 1 Hz beträgt ?

Und temperature_case_0C1 soll 0C1 etwa 0,1 GradC bedeuten ? Wenn man die 
Temperatur mit Nachkommastellen erfasst, dann

temp_Zehntelgrad oder temp_tenthsofadegreecelsius

Also im Prinzip sinnvoll, aber eindeutiger gewählte Namen sonst weiss es 
der andere Leser doch wieder nicht.
Gast #6346423
Lesenswert?

Hier mal wie das aussehen könnte:
1
using Frequency = uint64_t;
2

3
Frequency operator "" _Hz(unsigned long long int val)
4
{
5
    return val;
6
}
7

8
Frequency operator "" _kHz(unsigned long long int val)
9
{
10
    return val * 1000;
11
}
12

13
Frequency freq1 = 1_Hz;
14
Frequency freq2 = 23_kHz;

Dokumentiert sich quasi selber der Code.
#6346671
Lesenswert?

Zehpluplus schrieb:
> Hier mal wie das aussehen könnte:
>
>
1
> using Frequency = uint64_t;
2
> 
3
> Frequency operator "" _Hz(unsigned long long int val)
4
> {
5
>     return val;
6
> }
7
> 
8
> Frequency operator "" _kHz(unsigned long long int val)
9
> {
10
>     return val * 1000;
11
> }
12
> 
13
> Frequency freq1 = 1_Hz;
14
> Frequency freq2 = 23_kHz;
15
>
>
> Dokumentiert sich quasi selber der Code.

So macht man das sicher nicht: ein einfacher alias reicht nicht.

schlechte Fortsetzung:
1
using Bla = uint64_t;
2
    Frequency freq1 = 1_Hz;
3
    Frequency freq2 = 23_kHz;
4

5
    Bla b = 23_kHz; // Ups
6
    
7
    auto x = b * freq1; // What?
8
}
#6346674
Lesenswert?

Wilhelm M. schrieb:
> Anonymous U. schrieb:
>> Macht es Sinn die Einheit in den Variablennamen zu integrieren?
>
> Nein.
>
> Definiere Dir dafür eigene Datentypen. Es gibt genug Beispiele für die
> Modellierung physikalischer Einheiten im Netz.

Ich bin ja erstaunt, dass ich hier nicht mit negativen Kommentaren 
beworfen worden bin. Habe ich doch vor ca. 3-4 Jahren noch dafür 
tiefsten Spott erhalten. Manche Dinge scheinen sich ja so langsam 
einzuschleifen ...
#6347093
Lesenswert?

Würde ich nicht machen. Das macht den Code wahnsinnig unleserlich.

Einfach beim Anmelden der Variablen bzw. bei der Definition des 
Datentyps per Kommentar das dokumentieren, was man wissen muss. In einem 
Kommentar hat man den Platz dafür und eben einen Ort wo man nachschauen 
kann. Das reicht völlig. Eine Variable muss mir nicht an jeder Stelle im 
Code, wo Sie steht, ihre Einheit im Namen entgegen plärren. Das ist 
redundante Information. Und je nach Variable bzw. Anwendung sind Dinge 
wie die physikalische Einheit, Wert eines LSB, Wertebereich, 
Vorzeichenkonvention, etc. von Interesse. Das kann man u. U. unmöglich 
alles sinnvoll in einen Variablennamen packen.

Jetzt mal von eher ausgefallenen Einheiten ganz zu schweigen... Mir 
fällt jetzt spontan nur "nV/sqrt(Hz)" ein, aber ich denke es ist klar 
was ich meine.
Gast #6347255
Lesenswert?

Ein 50 Jahre altes Zitat, mit dem Dimensionen/Einheiten aus 
Programmiersprachen herausgehalten wurden:

"“Numbers as invented by mathematicians are abstract and beautiful. This 
should not be spoiled by engineers".
Gast #6347270
Lesenswert?

Ich benutze meistens SI-Einheiten, dann ist klar, was z.B. unter 
BusSpannung gespeichert wird.
Muss ich die allerdings anders abspeichern, weil z.B Millivolt und 
Megahertz gespeichert werden, dann gebe ich die Einheit auch bei den 
Variablennamen an:
BusSpannungmV
CpuFrequenzMhz

Das kennzeichnet dann, dass die Einheit nicht die 'normale' Si-Einheit 
ist.

Damit lebe ich seit mehreren Jahren ganz gut.
Moderator #6347312
Lesenswert?

Wenn irgendwie möglich, wähle ich als Einheit für Variablen immer die
entsprechende kohärente SI-Einheit. Dies muss dann genau einmal für ein
ein gesamtes Softwareprojekt als kurzer Vermerk dokumentiert werden. Bei
Verwendung von FP-Datentypen geht das praktisch immer.

Verwendet man aus Effizienzgründen Integertypen, möchte man oft die
Zahlenwerte skalieren, um entweder die Auflösung oder den Wertebereich
zu vergrößern. Da versuche ich dann, mit möglichst wenigen verschiedenen
Skalierungsfaktoren auszukommen, idealerweise mit maximal zwei pro
physikalischer Größe und Programmmodul (Bibliothek, Übersetzungseinheit
oder Klasse): Einen für das API und optional einen davon abweichenden
für die interne Darstellung. Beides wird an zentraler Stelle für das
jeweilige Modul dokumentiert.

Eine Dokumentation des Skalierungsfaktors für jede Einzelvariable ist
damit nicht erforderlich.

Nur in Ausnahmefällen, wo aus triftigen Gründen der Skalierungsfaktor
einer Variable von der programm- oder modulweit festgelegten Vorgabe
abweichen muss, dokumentiere ich diesen Umstand gesondert für die
entsprechende Variable, bspw. im Kommentar bei der Deklaration. Das es
sich hier um einen Ausnahmefall handelt, der besonderes Augenmerk
verdient, kann es aber auch sinnvoll sein, dem Variablennamen einen
entsprechenden Suffix anzuhängen, bspw. "duration_ms", "delay_ticks",
"distance_100m" oder "angle_2piDiv256". Der Unterstrich ist dabei als
"in" zu lesen.

Die Verwendung von benutzerdefinierten Literalen und größenspezifischen
Datentypen (bspw. Boost.Units) kann bei komplexen physikalischen
Berechnungen bei der Fehlervermeidung hilfreich sein, ist aber ein
Thema, das nur indirekt mit der Fragestellung des TE zu tun hat.
Persönliche Seite #6347324
Lesenswert?

Man kann sich von std::chrono inspirieren lassen:

https://en.cppreference.com/w/cpp/header/chrono

Dort gibt es Datentypen wie std::chrono::nanoseconds und user-defined 
literale wie  operator""ns . Durch die Kodierung der Einheit im Datentyp 
vermeidet man Fehler und kann die Daten auch generisch verarbeiten.

Wie man es nicht macht kann man sich bei FreeType2 anschauen:

https://www.freetype.org/freetype2/docs/reference/ft2-basic_types.html#ft_pos

Es ist entweder "integer font units, or 16.16, or 26.6 fixed-point pixel 
coordinates". Statt FT_Pos16_16, FT_Pos26_6 und FT_PosFontUnit o.ä. zu 
definieren darf man raten was es jeweils ist.
Gast #6347404
Lesenswert?

Niklas G. schrieb:
> Man kann sich von std::chrono inspirieren lassen:
>
> https://en.cppreference.com/w/cpp/header/chrono
>
> Dort gibt es Datentypen wie std::chrono::nanoseconds und user-defined
> literale wie  operator""ns . Durch die Kodierung der Einheit im Datentyp
> vermeidet man Fehler und kann die Daten auch generisch verarbeiten.

std::chrono ist nicht gerade das beste Beispiel.

Es gibt:
1
std::chrono::nanoseconds
2
std::chrono::microseconds
3
std::chrono::milliseconds
4
std::chrono::seconds
5
std::chrono::minutes
6
std::chrono::hours
7
std::chrono::days
8
std::chrono::weeks
9
std::chrono::months
10
std::chrono::years
als Alias für bestimmte std::chrono::duration Typen und es gibt
1
operator""ns
2
operator""us
3
operator""ms
4
operator""s
5
operator""min
6
operator""h
7
operator""d
8
operator""y
als Literals. Wer genauer hinschaut, wird feststellen, dass kein Literal 
für den Monat gibt. Und wer nachschaut, was diese Literale genau für 
einen Typ erzeugen, wird feststellen, dass die ersten 6 die 
entsprechenden std::chrono::duration Typen liefern. Die d und y Literale 
liefern die Typen std::chrono::day und std::chrono::year Typen, die 
nichts mit std::chrono::duration zu tun haben.

Interessant sind auch die Datentypen von t1 und t2.
1
auto t1 = 12s / 3;
2
auto t2 = 12m / 3;

Dann bleibt noch die Frage, welchen namespace man braucht, um die 
Literals zu nutzen? std::literals, std::chrono, 
std::literals::chrono_literals oder 
std::chrono::literals::std_chrono_literals?

Und wer etwas anderes als den "proleptic Gregorian calendar" (oder Jahre 
die außerhalb von ±2^15] liegen) benötigt, ist mit std::chrono eh 
verloren.

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