C++-Codebeispiel Phase 1
unter GNU/Linux-Systemen mit GCC –
aus früherem Programmieren in C++
Inhaltsverzeichnis zu JMB's Seite
zur Phase1 des Programmierens in C++
unter GNU/Linux-Systemen
Makefiles und
das Utility make
Beim Programmieren ist der Gebrauch
eines Makefiles (das vom Utility
make verwendet wird,
siehe Verwendung unterhalb des Makefile‑Beispiels;
vgl. GNU Autoconf) in jedem Fall
sinnvoll,
da dies die nötigen Eingaben
auf ein sinnvolle Maß reduzieren kann
(vgl. kleine Einführung für C und Makefiles,
umfangreichere Einführung in Makefiles,
O'Reilly-Einführung in Makefiles) –
hier ein sinnvolles kleines Beispiel für Makefile:
# ******************************************************************************
# * 'Makefile' des Verzeichnisses '~/mycpp/jmb/' *
# * *
# * J.M.B. [URL: https://www.jmb-edu.de/cpp_programming.html#makefileexamp] *
# * *
# * Lizenz: (c) 2019 unter GPLv3: https://www.gnu.org/licenses/gpl-3.0.txt *
# * *
# * Erstellung: 05.08.2019 *
# * *
# * Letzte Umgestaltung: 04.09.2019 (Phase 1; vgl. Phase 2 vom 03.09.2019) *
# ******************************************************************************
# * Was man unter `mach alles' verstehen soll (z.B. mehrere Programme setzen):
all: example
# * Sprungpunkt fuer das Programm (wie es heißt und was damit passieren soll):
example: example.cpp
g++ example.cpp -o example
# * Editieren:
edit:
-vim example.cpp
# * Binary aufrufen:
run:
-./example
# * Hausputz:
clean:
-rm -f core *.o *.bak *~
# * Fruehlingsputz (auch Binary wird geloescht):
superclean: clean
-rm -f example
# * Sicherung:
backup: clean
-cd .. ; tar cfvz ~/Downloads/mycpp_jmb.tgz jmb/ ; cd jmb
# Zu beachten ist, dass nach "LABEL:" bzw. am leeren Zeilenanfang Tabs
# stehen muessen - Leerzeichen funktioniert nicht!
Nun kann mit make example
(aktuell identisch mit make all)
das Beispielprogramm example.cpp übersetzt werden,
der Hausputz macht aktuell noch nichts
(da core, *.o und *.bak nicht existieren),
make superclean
löscht das Binary
(d.h. die ausführbare Datei
in Maschinensprache),
und make backup
erstellt ein Backup des Verzeichnisses jmb.
Noch wirkt es als nur geringe Ersparnis,
aber schon aufwendig ausgeklügelte Compiler-Flags
oder mehrere zu übersetzende Module bringen dadurch
eine enorme Erleichterung sowie Ordnung, Dokumentation
und Übersicht.
Aber man sieht, dass man den Namen nicht mehr
kennen muss;
man geht ins Projektverzeichnis,
editiert die Quelldatei (wenn es nur eine ist,
sonst braucht man geeignete Label)
mit make edit,
übersetzt den Code mit make all und ruft zum Test
das Binary mit make run auf
(vgl. zugehöriges Programm).
Das Makefile steht unten
mit dem Beispielprogramm example.cpp
und dem resultierenden Binary example
zum direkten
Download bereit.
Vorstellen eines Beispiel‑Programms in C++
Quelltext
/******************************************************************************
* C++-Programm 'example.cpp' im Verzeichnis '~/mycpp/jmb/' *
* *
* Funktion: "Zerlegung einer Zahl in ihre Primfaktoren" *
* *
* J.M.B. [URL: https://www.jmb-edu.de/cpp_programming.html#progcppexamp] *
* *
* Lizenz: (c) 2019 unter GPLv3: https://www.gnu.org/licenses/gpl-3.0.txt *
* *
* Erstellung: 05.08.2019 *
* *
* Letzte Umgestaltung: 04.09.2019 (Phase 1; vgl. Phase 2 vom 03.09.2019) *
******************************************************************************
*/
# include <iostream> // fuer std::cin, std::cout, std::endl
# include <string> // fuer std::stoi
# include <math.h> // fuer sqrt
/* Gebrauch von ANSI-Farben in kompatiblen Terminals:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Effekt Code | Farbe Vordergrund Hintergrund | ASCII 27 = \033
* zurücksetzen 0 | schwarz 30 40 | = ESC-Zeichen
* fett/hell 1 | rot 31 41 |
* unterstrichen 4 | gruen 32 42 | Z.B. hell rot
* invertiert 7 | gelb/orange 33 43 | auf schwarz
* fett/hell aus 21 | blau 34 44 | "\033[4;31;40m"
* unterstri. aus 24 | magenta 35 45 |
* invertiert aus 27 | cyan 36 46 | Reset: "\033[0m"
* * Just play ! * | weiss/grau 37 47 | * Have fun! *
*/
#define RESET "\033[0m" /* Reset to Defaul: zuruecksetzen*/
#define ULLWHITEONYELLOW "\033[1;4;37;43m" /* unterstrichen weiss auf orange*/
#define ULLYELLOWONGREEN "\033[1;4;33;42m" /* unterstrichen gelb auf gruen */
#define ULLYELLOWONYELLOW "\033[1;4;33;43m" /* unterstrichen gelb auf orange */
#define ULLREDONBLACK "\033[1;4;31;40m" /* unterstrichen rosa auf schwarz*/
void primeFactors(int n) // Eigene Funktion zur PF-Ausgabe
{
using std::cout; // cout bedeutet nun std::cout
using std::endl; // endl bedeutet nun std::endl
cout << "Primzahlfaktoren von " << n << " sind:\n";
/* 1. Schritt: */
// Anzahl 2-en ausgeben, durch die n (vor 1. Schritt) dividiert werden kann
while (n%2 == 0) // wenn bei Division kein Rest
{
cout << "2, "; // jeder Faktor wird ausgegeben
n = n/2;
}
/* 2. Schritt: */
// n (Anfang 2. Schritt) muss nun ungerade sein - Primfaktoren 2 wurden
// entdeckt, somit kann man immer eine Zahl uebergehen, daher i=i+2
for (int i = 3; i <= sqrt(n); i = i+2)
{
// Solange n durch i teilbar ist, wird i ausgegeben (analog 2 oben)
while (n%i == 0) // wenn bei Division kein Rest
{
cout << i << ", "; // jeder Faktor wird ausgegeben
n = n/i;
}
}
/* 3. Schritt: */
// Wenn for bis i = Wurzel n (n nach 1. Schritt) nicht n=1 (Ende 2. Schritt)
// liefert, muss n der letzte fehlende Primfaktor der Zerlegung sein
if (n > 2)
{
cout << n << "."; // Ausgabe n, da letzter fehlender PF
}
cout << endl;
}
int main(int argc, const char* argv[]) // Hauptfunktion bei Aufruf-Parameter
{ /* Begruessung */
std::cout << ULLYELLOWONGREEN << " * Programm '" << argv[0] << "' zur Ausgabe der Primfaktoren *" << RESET << "\n";
/* Zahl ermitteln, die in PFs aufgespalten werden soll */
int wert = 0;
if (argc > 1) // Wurde neben Aufrufnamen ein Parameter
{ // angegeben?
wert = std::stoi(argv[1]); // Dann sollte dies die Zahl sein.
if (wert < 2) // Zahlen kleiner 2 machen keinen Sinn!
{
std::cout << ULLREDONBLACK << "Fehler:" << RESET << " Der Aufrufparameter war kleiner als 2!\n";
}
}
while (wert < 2) // Bis wert mindestens 2 ist einlesen
{
std::cout << "Gib eine ganze Zahl > 1 ein: ";
std::cin >> wert; // Eingabewert in Variable wert lesen
if(!std::cin) // Lese-Status pruefen ...
{
std::cout << ULLREDONBLACK << "Fehler:" << RESET << " Unerlaubte Eingabe!\n";
return 1; // Abbruch mit Fehlercode 1
}
}
/* PFs ermitteln und mit "," getrennt ausgeben */
primeFactors(wert); // Funktionsaufruf fuer PFs
/* Verabschiedung */
std::cout << ULLWHITEONYELLOW << " * That's all, folks! " << ULLYELLOWONYELLOW << ";)" << ULLWHITEONYELLOW << " * -<(c) J.M.B. 2019, GPLv3>~-" << RESET << "\n";
return 0; // Uebergabewert (= Fehlercode) an Betriebssystem/Shell
}
/******************************************************************************
* Das war's - ein erstes kleines Programm - nicht zu trivial ... :)) *
******************************************************************************
*/
Erläuterung zum Quelltext
✯ Neu 09/2019 ✯
Die Phase 2 wurde am 03.09.2019 abgeschlossen –
der neue Quellcode (vergrößert von 104
auf aktuell 775 Zeilen;
also wieder größer als das
bereits am 23.08.2019
überarbeitete Makefile 😳 ; von 41
auf nun 139 Zeilen und auch größer als die GPLv3‑Lizenz mit 674 Zeilen)
mit den Erklärungen
ist nun auf der Phase 2‑Seite
zu finden ...
und es hat sich viel geändert:
Umstellen auf unsigned long long
zur Zerlegung größerer Zahlen,
Abfangen von (ich hoffe 😀 )
allen Eingabefehlern,
Ausgabeumleitung inkl. Schreiben in eine Datei
mit genauem Zeitstempel im Namen,
viele Flags z.B. mit inverser oder
monochromer Bildschirmausgabe,
Ausgabe eines Hilfstextes und ANSI-Steuercodes
über konstante String-Variablen,
übersichtlichere Ausgabe der Primfaktoren,
flexiblere Eingabe mit beliebigen Trennzeichen
sowie erweiterte Kommentare ...
Das Programm ist mit Phase 2 weit genug gediehen,
um damit einen C++-Einstiegskurs sinnvoll leiten
zu können. 😤
Da die hier dargestellte Phase 1
deutlich kompakter ist,
kann diese auch zuerst gelesen werden,
erst danach die deutlich erweiterte Fassung und
Erklärung zu Phase 2.
Es gibt einiges zu beachten, bis man
mit dem Quelltext etwas anfangen kann:
- Kommentare:
Alles von //
bis zum Zeilenende wird vom Compiler ignoriert
(z.B. Zeile 16 oder 44),
ebenso alles zwischen /* und */ (z.B. Zeilen 1-14
oder Zeile 73; vgl. Kommentar‑Arten unten).
Hier sollen Kommentare verwendet werden,
die den Quelltext auch nach Monaten
bis Jahren schnell verständlich machen sollen.
Man sollte sich merken, dass bei C und C++
als Kommentar immer der Slash / mit einem weiteren Zeichen
(genauer // bzw.
/* ... */)
kombiniert wird –
bei Shell-Skripten bzw. Makefiles ist es
das Doppelkreuz (oder hash) #,
bei 📜LATEX
das Prozentzeichen %,
bei 🌐HTML
<!-- ... -->
(vgl. Kommentarbeispiele aus Wikipedia).
- Hauptteil: Jedes C++/C‑Programm
enthält genau eine main-Funktion
(im obigen Beispiel Zeile 72;
hier in der komplizierten Fassung
unter Heranziehen von mit dem Aufruf
mitgegebenen Parametern).
Diese Funktion entspricht
dem aufgerufenen Programm –
alles weitere muss von dort aufgerufen werden,
wie im Beispiel die Funktion primeFactors
(in Zeile 96).
Will man Aufrufparameter ignorieren, reicht ein einfaches:
int main() // Hauptfunktion ohne Aufruf-Parameter
Die Hauptfunktion main sollte
mit return 0
abgebrochen werden, was das sofortige Programmende
bedeutet mit Übergabewert 0
für alles OK, jede andere Zahl
(aus Kompatibilitätsgründen
besser nur bis 127,
zumeist aber 1,
bedeutet einen Fehler{code},
den man in der Shell [unter Linux meist
die Bash, zu überprüfen
über echo $SHELL
mit typischer Ausgabe:
/bin/bash] aufrufen kann:
./example; echo
"Fehlercode: "$?).
- Präprozessor: Alle Zeilen,
die mit Doppelkreuz #
beginnen, werden vom Präprozessor ausgeführt,
noch bevor der Compiler seine Arbeit aufnimmt.
#include weist diesen an,
die anzugebende Standard-Bibliothek
(im obigen Beispiel Zeilen 16-18;
hier mit im Kommentar
angegebenem Verwendungszweck; diese Dateien sollten sich
im Suchpfad des Compilers befinden) oder auch
eine weitere Quelltextdatei im aktuellen Verzeichnis
(#include "meinModul.hpp";
also doppelte Anführungszeichen
statt spitze Klammern)
einzubinden oder bestimmte Konstanten zu definieren
(Textersetzung; im obigen Beispiel Zeilen 32-36
für ASCII-Steuercodes zur Farbwahl).
- Struktur:
Je nach Projekt
kann der Programmierstil
deutlich variieren.
Man sollte sich einen aussuchen und
bei eigenen Projekten durchhalten,
so dass man intuitiv Fehler finden kann.
Bei existierendem Code sollte man sich
anpassen –
oder alles umschreiben.
Bei einem Team sollte man sich möglichst
auf den Code-Stil einigen
(siehe auch C++‑Code‑Standards von Standard C++ Foundation, Google, GitHub, geosoft, KDE-Framework|-Libs|Qt, Bjarne Stroustrup's C++ Style and
Technique FAQ;
und C-Code-Standards von GNU und Linux).
Hier habe ich (fast) alles auf Deutsch
kommentiert, natürlich ist
bei internationalen Projekten Englisch angesagt.
a) Zusammengehörigkeit:
Man sieht, dass {...} bestimmte Blöcke
zusammen gehören (z.B. Zeilen 39+70, 54+61,
oder 57+60),
ebenso dass ...;
eine Anweisung mit Ende
bezeichnet (z.B. Zeilen 40, 47
oder 48; diese Anweisungen werden immer nacheinander
abgearbeitet – bei Ausdrücken erlebt man
Überraschungen: hier kann der Compiler
optimieren) oder dass (...) Ausdrücke beinhalten,
die z.B. wahr oder falsch sein können
(Typ bool
mit Literalen true
{=1; ggf. auch
eine größere Zahl} und false {=0},
z.B. Zeilen 45, 65 oder 77).
Nach if muss
kein Leerzeichen / Blank folgen, { kann direkt nach der Verzweigungs-
oder Schleifenanweisung kommen.
Dass hier zugehörige
geschweifte Klammern die selbe Einrückung haben
(also untereinander stehen)
oder niedere Blöcke
genau zwei Leerzeichen mehr eingerückt sind,
ist meine Präferenz, auch dass ich nie
Tabulatoren gebrauche (die leider
im Makefile Pflicht sind).
Gebrächlich sind 2 oder 4
(ganz selten, z.B. dem Linux-Kernel,
auch 8) Blanks oder ein Tab
als Einrücktiefe.
b) Kommentar-Arten:
Vermeidung von Kommentaren der Art /* ... */
hat den Vorteil,
dass man dann mit diesem Stil
große Bereiche auskommentieren kann (vgl. Kommentarabschnitt oben).
c) Namenskonventionen:
Bei Variablen klein beginnen und dann CamelCase:
anzahlErfolgterAufrufe
(bzw. bei Klassenvariablen
mit Underscore _
abschließen: anzahlErfolgterAufrufe_),
bei Funktionen wie Variable
oder auch snake_case:
wer_findet_funktion(),
einfache Typen klein mit Unterstrich und Endung:
adress_typ,
Klassen groß beginnen mit CamelCase,
Konstanten, Enum-Elemente und Makros groß mit Unterstrich:
SMILEY_FROWNING.
- Algorithmus:
Als Mathe-Lehrer, der den Schülern
ab der Klassenstufe 6 beibringt,
eine Bruchaufgabe sei nur
bei vollständig gekürztem Bruch
auch vollständig gelöst und
somit die volle Punktzahl wert,
ist ein Programm zur Ausgabe der Primfaktoren
(PFs) natürlich naheliegend. 😉
Was passiert aber mathematisch
in der Funktion primeFactors:
Schritt 1 (Zeilen 45‑49):
Die eigentlich zu zerlegende Zahl n
(hier als Aufruf-Parameter übergeben,
Zeile 79, oder im laufenden Programm eingegeben,
Zeile 88)
wird zuerst durch 2 geteilt (halbiert),
bis dies nicht mehr restfrei
geht (d.h. die verbleibende Zahl
ist ungerade und ist das neue n,
wenn das ursprüngliche n
gerade war).
Die Variable n ist immer der Quotient,
in dem noch nicht getestete Faktoren
stecken können. Bei jedem gefundenen PF
gibt es einen neuen Wert für n,
der sich durch Teilen mit dem gefundenen PF
ergibt (dies gilt auch für den folgenden
Schritt 2).
Schritt 2 (Zeilen 53‑61):
Nun wird nacheinander die zuvor erhaltene
ungeraden Zahl n
durch Zahlen i von 3
bis zu sqrt(n)
[d.h. square root (n) =
Wurzel (n) = √n]
jeweils so oft
wie restfrei möglich geteilt
(analog Schritt 1),
wobei nur ungerade i getestet werden.
Hierzu sind ein paar Bemerkungen
zum besseren Verständnis nötig:
- Da bereits der Primfaktor 2
in Schritt 1 bearbeitet wurde, muss hier
mit i = 3 begonnen werden.
- Es müssen nur ungerade Zahlen
getestet werden (dies wird in Zeile 53
durch i=i+2 erreicht),
denn außer 2 sind alle anderen geraden Zahlen
nicht prim. Zudem wurde durch Schritt 1
eine ungerade Zahl n erzwungen, so dass
die geraden Zahlen keine Divisoren i
für Teilen ohne Rest darstellen.
- Da der Laufindex inkrementiert wird,
d.h. sich von klein zu groß wandelt,
werden Nicht-Primzahlen keine Teiler i
sein können, da diese Faktoren besitzen,
um die n bereits beraubt wurde.
- Hier darf n als am Ende
von Schritt 1 eingefroren betrachtet werden:
Wurzel n wäre die größte Zahl,
die zweimal als Faktor in n stecken kann.
Eine Zahl größer Wurzel (n)
kann damit nur einmal in n stecken.
Diese als einzige von Schritt 2
nicht behandelte Möglichkeit
behandelt Schritt 3.
Wenn sich durch diese for-Schleife
am Ende n = 1 ergibt
(n = 2 ist nicht möglich
wegen Schitt 1, daher ist (n > 2)
in Zeile 65 in Ordnung),
dann ist die Primfaktorzerlegung
bereits geschafft.
Ansonsten kommt nun
Schritt 3 (Zeilen 65‑69):
Wie in Punkten 3. und 4.
von Schritt 2 ausgeführt,
kann n, wenn es nicht 1 ist,
nur eine Primzahl sein, die größer als
√n ist.
Es gilt also nur noch, diese Primzahl n
der Liste hinzuzufügen.
Fertig! 😎
- Lizenz und Urheberrecht:
Wenn man privat Code schreibt, besitzt man
das Copyright und sollte dies
auch anmerken. Dies gibt das Recht,
den Code zu verkaufen, aber natürlich ebenso,
diesen im Form von Freier Software der Allgemeinheit
zu überlassen
(Copyleft), so dass niemand
diesen Code missbrauchen kann,
sondern nur abändern und ebenfalls
im Quellcode der Allgemeinheit zur Verfügung
stellen muss.
Dies macht die GNU General Public License: GPL,
deren jüngste und mächtigste Variante
zur Befreiung der Anwender die GPLv3 ist.
Der von mir nur gelinkte Text
wird normalerweise dem Software-Quelltext
als Datei beigelegt.
Hier bedeutet mein Copyright nur,
dass ich es geschrieben habe und die Nutzung freigebe –
die Basis-Struktur kam aus einem Beispiel meiner 1. Literaturangabe
(S. 63, Listing 4.2),
der Algorithmus ist wohl bekannt und im Netz
vielfach leicht zu finden, ebenso die ANSI-Farbsequenzen, die ich schon
Ende der 1980-er in Tubo Pascal verwendete.
Nur die spezielle Gestaltung
ist somit mein Werk.
Nichts hier ist also ein Copyright
(Urheberschaft macht bei sehr Einfachem
wenig Sinn; wenn das mal die Patentämter
[bzw. die verantwortliche Legislative]
begreifen würden) oder
eine Lizenz wert ... es soll nur
als Beispiel dienen,
wie man mit eigener Software umgehen sollte.
- Feinheiten:
So, wie die Farbcodes im Teminal über ANSI-Escape-Sequenzen eine neue Farbe festlegen (Kommentar und Festlegung
in Zeilen 20-36,
Anwendung in Zeilen 74+82+91+98),
so gibt es auch in String-Angaben bzw. allgemein
in C/C++ Escape-Sequenzen,
z.B. um einen Zeilenumbruch: \n (new line;
vgl. Zeile 42+74+82+91+98), ein Unicode-Zeichen
über \Uhhhhhhhh
zu bewirken oder
auch das doppelte Anführungszeichen: "
zu maskieren, das ja als Beginn- bzw. Endemarke
eines Strings dient und somit im String
als \"
dargestellt werden muss.
Die Escape-Sequenzen beginnen immer
mit einem Rückwärtsschrägstrich /
Backslash: \.
Im Übrigen werden Escape-Sequenzen
auch in Druckersprachen
wie ESC/P (Epson) oder
PCL (HP) verwendet,
wenn keine Seitenbeschreibungssprachen wie PostScript
verwendet wird.
Eine Vereinfachung ist
in Zeilen 40+41 zu finden, so dass der Namespace
für die beiden angegebenen Funktionen
nicht mit std::
ausgewiesen werden muss.
Stattdessen könnte man auch in einer Zeile
für alle Funktionen
der Standardbibliothek schreiben:
using namespace std; // fuer std::cout und std::endl - aber auch bei anderen wirksam
Diese allgemeine Änderung sollte aber eher
vermieden werden, insbesondere wenn in main
und damit global umdefiniert,
weil hier Mehrdeutigkeiten
eingeführt werden könnten.
Daher lieber nur für häufig
aufgerufene Bibliotheks-Funktionen in einer Funktion
umdefinieren wie im Listing gezeigt.
- Kommt noch was?:
Nicht alles
ist erklärt ... und wird es
wohl auch nie (auch wenn ich
auf Hinweise eingehe).
Dafür sei die Literaturliste
und eine Internetrecherche empfohlen.
Ich beabsichtige, noch einiges
zu ergänzen –
und auch am Code deutliche Änderungen
einfließen zu lassen,
auch wenn die Basisfunktionalität
so erhalten bleiben soll.
Daher habe ich hier die Phase 1
(vom 08.08.2019)
dieses Programms eingefroren.
So wie auch der unten angegebene Download
diese Fassung auch nach Änderungen der aktuellen Fassung
weiterhin anbieten wird.
Ideen für Änderungen
hätte ich genug ...
auch für ganz andere Programme ...
oder einen Programmierkurs für Heranwachsende,
der sich an einen 📢Vortrag
anschließen könnte.
Ergänzungen
Wie man nun auf der Kommandozeile mit dem Programm
umgeht, d.h. die einzelnen Programmierschritte auslöst:
den Quelltext editiert, diesen übersetzt und
das ausführbare Programm aufruft,
kann man oben beim Makefile nachlesen.
Hier die Ausgabe im xfce4-terminal
(nach bewusst falschem Startparameter -5 und dann Eingabe von 999):
Das Beispielprogramm steht mit dem Makefile
zum direkten Download
weiter unten bereit.
Zum Binary, d.h. der Datei
des ausführbaren Programms in Maschinencode,
noch ein paar Infos
bzw. wie man sich diese beschafft:
$ ls -al example
-rwxrwxr-x 1 jmb jmb 19240 Aug 6 19:14 example
# d.h. 19249 Byte = 18,8 kB Größe
$ file example
example: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d90c0ad815b0b065ff826a7b39ee71a153341497, for GNU/Linux 3.2.0, not stripped
$ strings example
# Ausgabe aller Zeichenketten (Strings) des Executables (viel)
$ readelf -x .rodata example
# Anzeigen der statischen Strings
$ nm example
# Auflisten der Symbole
$ readelf -s example
# Anzeigen der Symbole
$ readelf -h example
# Ausgabe des ELF (Binärformat unter Linux) - Headers
$ readelf --relocs example
# Klären, ob das Binary ein positionsunabhängiges Executable ist bzgl. der Bibliotheken.
$ ldd example
# Liste dynamisch gelinkter Bibliotheken (hier sechs: linux-vdso.so.1, libstdc++.so.6, libm.so.6, libgcc_s.so.1, libc.so.6, /lib64/ld-linux-x86-64.so.2)
$ ldconfig -p | grep NAME_BIBLIOTHEK
# Nachschauen, ob eine bestimmte Bibliothek auf dem System installiert ist, z.B. bei `ldconfig -p | grep libm.so.6' u.a. `... => /lib/x86_64-linux-gnu/libc.so.6'.
$ /lib/x86_64-linux-gnu/libc.so.6
# liefert am Anfang: 'GNU C Library (Ubuntu GLIBC 2.29-0ubuntu2) stable release version 2.29.' auf Xubuntu 19.04.
$ objdump -d example
# Disassemblieren des Binary bzw. des Object Files (*.o)
$ strace ./example
# Lässt das Programm ablaufen und berichtet, was es dabei tut.
Dies sind ein paar Beispiele,
wobei zumeist auf die GNU Binary Utilities
(kurz binutils, ebenso Name des Pakets,
in dem neben Assembler as und Linker ld
diese Werkzeuge für ausführbare Dateien
enthalten sind; diese werden, wie bereits ausgeführt,
typischerweise gemeinsam mit gcc,
make und
gdb verwendet;
vgl. Homepage sowie Dokumentation
zu GNU Binutils) zurückgegriffen wurde.
Wer das Makefile,
den Quelltext
des obigen C++‑Beispielprogramms und das Executable
für Linux haben möchte,
kann es einfach als gezippte Tar‑Datei
jmb_added_for_cpp_programming_phase1.tgz (7,8 kB,
Fassung vom 06.09.2019)
downloaden und an passender Stelle
zum neuen Unterverzeichnis jmb_phase1
mit den drei Dateien
(Makefile, example und
example.cpp)
entpacken über:
tar xvfz jmb_added_for_cpp_programming_phase1.tgz.
Siehe auch Link zum Download
der aktuellen Fassung der Phase 2 vom 03.09.2019.
Link zum 🐧persönlichen Hintergrund bzgl.
GNU/Linux.
Link zu 🌠meiner generellen Motivation.
Link zur Hauptseite des 💾Programmierens
in C++.
Bei Fragen / Problemen mit dieser Seite bzw.
meiner Webpräsenz kontaktieren Sie mich bitte:
E-Mail: 📧jmb@jmb-edu.de
© 1987-2024
Bitte beachten Sie hierzu auch mein 📄Impressum.
[Zurück zur 🏁Startseite]
Erste Fassung: | 30. | Juli | 2019 |
Letzte Änderung: | 01. | Januar | 2024 |