Forum: Compiler & IDEs Mal wieder ein Problem mit structs


von J. T. (chaoskind)


Lesenswert?

MoinMoin,

ich hab mir ein Conways Spiel des Lebens  programmiert, mit einfacher 
Ausgabe über die Konsole per - und X für die Zellen. Das hat auch alles 
gut geklappt. Nun wollte ich ein erweitertes Spiel des Lebens 
programmieren, bei dem es mehr als nur die Zustände lebend/tot gibt. 
Dabei bin ich auf ein Problem mit structs gestoßen.

Wenn ich per "typedef struct" ein struct definiere und gleich eins davon 
deklariere:
1
typedef struct  Zelle_s
2
{
3
    uint8_t Geschlecht;
4
    uint8_t Energie;
5
    uint8_t Alter;
6
    uint8_t Art;
7
}Zelle[X_Max][Y_Max];
kann ich nicht drauf zugreifen
1
int main()
2
{
3
    uint16_t XPos = 0;
4
    uint16_t YPos = 0;
5
    Zelle[XPos][YPos].Geschlecht = Maennchen;  //Zeile 38
6
    Zelle[XPos][YPos].Energie = 10;
7
    Zelle[XPos][YPos].Alter = 0;
8
    Zelle[XPos][YPos].Art = Pflanzenfresser;
er wirft dann den 
Fehler:"B:\CodeBlocks\Projekte\GameOfLife_Extended\main.c|38|error: 
expected identifier or '(' before '[' token|"

wenn ich statt dessen aber
1
typedef struct  Zelle_s
2
{
3
    uint8_t Geschlecht;
4
    uint8_t Energie;
5
    uint8_t Alter;
6
    uint8_t Art;
7
};  //Zeile28
8
9
10
struct Zelle_s Zelle[X_Max][Y_Max];
11
//struct Zelle_s ZelleNeu[X_Max][Y_Max];
12
13
14
15
int main()
16
{
17
    uint16_t XPos = 0;
18
    uint16_t YPos = 0;
19
    Zelle[XPos][YPos].Geschlecht = Maennchen;
20
    Zelle[XPos][YPos].Energie = 10;
21
    Zelle[XPos][YPos].Alter = 0;
22
    Zelle[XPos][YPos].Art = Pflanzenfresser;
23
24
25
    return 0;
26
}
schreibe, dann erhalte ich lediglich die 
Warnung:"B:\CodeBlocks\Projekte\GameOfLife_Extended\main.c|28|warning: 
useless storage class specifier in empty declaration [enabled by 
default]|"

Was hat das mit diesem useless strage class specifier auf sich, und 
wieso taucht der nicht auf, wenn ich direkt dort ein struct dieser Art 
definiere. Und wieso kann ich auf dieses dann nicht zugreifen?


Ich hatte schonmal ein ähnliches Problem, da wurde mir noch geraten, dem 
struct _attribute_ ((_packed_)) mitzugeben. Das hat aber nur was 
damit zu tun, wie das struct im Speicher abgelegt wird, oder?

MfG Chaos

von nocheinGast (Gast)


Lesenswert?

Lass das "typedef" weg oder lies nach, was das eigentlich tut ;) .

von Karl Käfer (Gast)


Lesenswert?

Hallo j.t.,

j. t. schrieb:
> Wenn ich per "typedef struct" ein struct definiere und gleich eins davon
> deklariere:
>
1
> typedef struct  Zelle_s
2
> {
3
>     uint8_t Geschlecht;
4
>     uint8_t Energie;
5
>     uint8_t Alter;
6
>     uint8_t Art;
7
> }Zelle[X_Max][Y_Max];
8
>

Der Code
1
struct Zelle_s {
2
    uint8_t Geschlecht;
3
    uint8_t Energie;
4
    uint8_t Alter;
5
    uint8_t Art;
6
} Zelle;
deklariert einen struct-Datentyp "Zelle_s" und eine Variable "Zelle", 
die von diesem Datentyp ist. Du kannst diese Variable dann direkt 
verwenden.

Der Code
1
typedef struct Zelle_s {
2
    uint8_t Geschlecht;
3
    uint8_t Energie;
4
    uint8_t Alter;
5
    uint8_t Art;
6
} Zelle;
deklariert einen struct-Datentyp "Zelle_s" und einen Alias für den 
Datentyp namens "Zelle". Damit hast Du also auch keine Variable 
deklariert und deswegen nichts, worauf zu zugreifen könntest.

Mit Deinem Code oben deklarierst Du einen Datentyp "Zelle_s" und einen 
Array-Datentyp "Zelle", der letztlich ein Alias für 
Zelle_s[X_Max][Y_Max] ist. Wenn Du mit diesem Array-Datentyp dann eine 
Variable deklarierst, ist diese automatisch ein Array mit den 
gewünschten Dimensionen:
1
typedef struct Zelle_s {
2
    uint8_t Geschlecht;
3
    uint8_t Energie;
4
    uint8_t Alter;
5
    uint8_t Art;
6
} Zelle[X_Max][Y_Max];
7
8
Zelle z; // deklariert Variable vom Typ Zelle (=> Zelle_s[X_Max][Y_Max])

Dann kannst Du auch Sachen machen wie
1
for(int i = 0; i<X_Max; i++) {
2
  for(int i = 0; i<X_Max; i++) {
3
    z[i][j].Geschlecht = 0;
4
    z[i][j].Energie = 100;
5
  }
6
}

Liebe Grüße,
Karl

von J. T. (chaoskind)


Lesenswert?

Hey Karl,

vielen herzlichen Dank für deine sehr ausführliche Erläuterung =). 
Während des Lesens tauchten immer wieder Fragen auf, die dann aber 2 
Zeilen später schon beantwortet waren!

MfG Chaos

von J. T. (chaoskind)


Lesenswert?

P.S.
Du hast nicht zufällig noch eine Idee, wie man das ganze dann grafisch 
ausgeben könnte? Ich hab mal ein Fraktalgenerator programmiert, der die 
Einzelbilder als bmp ausgegeben hat, aber hier hat ich schon gern was 
"zusammenhängend animiertes" *gg.

Oder nen Einstieg dazu? Das scheint ja doch ein komplexeres Thema zu 
sein.

von Joe F. (easylife)


Lesenswert?

Von curses über VRML bis OpenGL steht dir alles offen.

von Karl Käfer (Gast)


Lesenswert?

Hi j.t.,

j. t. schrieb:
> P.S.
> Du hast nicht zufällig noch eine Idee, wie man das ganze dann grafisch
> ausgeben könnte? Ich hab mal ein Fraktalgenerator programmiert, der die
> Einzelbilder als bmp ausgegeben hat, aber hier hat ich schon gern was
> "zusammenhängend animiertes" *gg.
>
> Oder nen Einstieg dazu? Das scheint ja doch ein komplexeres Thema zu
> sein.

Geht so... Ich hab' eben gelesen, was dieses "game of life" eigentlich 
ist, und eine (ganz einfache) Kommandozeilenversion geschrieben. Die 
Datenstruktur für das Spielfeld (und den temporären Zwischenspeicher) 
sieht so aus:
1
#define MAX_SIZE_X 9
2
#define MAX_SIZE_Y 9
3
4
typedef int mt[MAX_SIZE_X][MAX_SIZE_Y];
Das macht keine Datenstruktur, sondern nur einen Array mit den 
definierten Größen von "int"s. (Auf kleiner Hardware wie einem uC wäre 
das natürlich eine riesige Speicherverschwendung; die Werte "0" und "1" 
ließen sich ja bequem in einem Bit abbilden.)

Mit meinem neuen Typ "mt" deklariere ich dann zwei Variablen "m" und 
"n", wobei "m" das Spielfeld und "n" den Zwischenpuffer enthält. Die 
Funktion zur Ausgabe von "m" (oder "n", spielt keine Rolle) sieht dann 
so aus:
1
#define ANSI_CLEAR "\e[1;1H\e[2J"
2
#define SLEEP_SECONDS 2
3
4
void print(mt m) {
5
    int i = 0;
6
    int j = 0;
7
    sleep(SLEEP_SECONDS);
8
    printf(ANSI_CLEAR);
9
    for(i=0; i < MAX_SIZE_X; i++) {
10
        for(j=0; j < MAX_SIZE_Y; j++) {
11
            if( m[i][j] == 1 ) {
12
                printf(" #");
13
            } else {
14
                printf(" .");
15
            }
16
        }
17
        printf("\n");
18
    }
19
    printf("\n");
20
}
Die Funktion schläft "SLEEP_SECONDS" Sekunden, löscht den Bildschirm und 
gibt dann den Inhalt der übergebenen "mt"-Variable aus, etwa so:
1
 . . . . . . . . .
2
 . . . . . . . . .
3
 . . # # # . . . .
4
 . . . # . . . . .
5
 . . # # # . . . .
6
 . . . . . . . . .
7
 . . . . . . . . .
8
 . . . . . . . . .
9
 . . . . . . . . .
Die Escape-Sequenz "ANSI_CLEAR" funktioniert allerdings nur auf ANSI- 
und POSIX-Terminals, also zum Beispiel auf meinem Linux-System; unter 
Windows und / oder OS/X muß da gegebenenfalls eine andere Escape-Sequenz 
oder ein "system("cls")" bzw. "system("clear")" benutzt oder ein Befehl 
aus einem nicht-standardisierten Header wie conio.h oder ncurses benutzt 
werden.

HTH,
Karl

von J. T. (chaoskind)


Lesenswert?

Hey Karl,
schön dein Interesse am game of life geweckt zu haben. Ich war 
fasziniert davon, wie solch relativ komplexe Strukturen entstehen, wie 
die Gleiter, die sich über ein Spielfeld bewegen, ohne das jemals etwas 
von "Beweg dich" programmiert wurde. Was solch einfache Regeln 
implizieren.

Was da wohl erst kompliziertere Regelwerke wie Physik und Chemie 
ermöglichen mögen.... Da soll doch nochmal einer behaupten, sowas 
komplexes wie das Leben kann garnicht zufällig entstehen.

Doch zurück zum Thema, ich hab inzwischen etwas entdeckt, mit dem ich 
"Grafikkrams" machen kann. Allegro schimpft sich das ganze, und klappt 
eigentlich auch ganz gut.

Man kann alles bmp basiert machen. Man erstellt also eine 
BITMAP-variable, diese kann man dann entweder per Pixelsetzen selbst 
bemalen, oder man kann ein vorher erstelltes bmp per
1
BITMAP *Buffer;
2
BITMAP *Bild
3
Buffer = create_bitmap( 640, 480);
4
Bild = load_bitmap("File.bmp", NULL);

hineinladen. Per
1
draw_sprite(Buffer, Bild, xPos, yPos);//also in welche Bitmap, aus welcher, Position

das Bild welches man lädt, muss sich im selben Verzeichnis wie die 
complilierte exe befinden. Das ist bei mir bei allen der Fall, auch 
falsch geschrieben sind sie nicht(mehrfach geprüft). (Man erhält keine 
Fehlermeldung, wenn File.bmp nicht vorhanden ist, das programm stürzt 
einfach ab. Im Debugmodus erhält man ein Segmentation Fault.

Ich hab mehrere bmp die ich laden lasse, eins hab ich Testhalber mal mit 
dem funktionierenden Bild (Kloppo) geladen und siehe da, nutze ich nur 
dieses, aber mit Verschiedenen Namen, klappt es.
1
    BITMAP *buffer;
2
3
    BITMAP *Kloppo;
4
    BITMAP *LaufStart;
5
    BITMAP *Lauf1;
6
    BITMAP *Lauf2;
7
    BITMAP *Lauf3;
8
    BITMAP *Lauf4;
9
    BITMAP *Lauf5;
10
    BITMAP *Lauf6;
11
    BITMAP *Lauf7;
12
13
    buffer = create_bitmap( 640, 480);
14
    Cursorbild = create_bitmap(12,12);
15
16
    LaufStart = load_bitmap("laufst.bmp", NULL);
17
    Lauf1 = load_bitmap("lauf1.bmp", NULL);
18
    Lauf2 = load_bitmap("lauf2.bmp", NULL);
19
    Lauf3 = load_bitmap("lauf3.bmp", NULL);
20
    Lauf4 = load_bitmap("lauf4.bmp", NULL);
21
    Lauf5 = load_bitmap("lauf5.bmp", NULL);
22
    Lauf6 = load_bitmap("lauf6.bmp", NULL);
23
    Lauf7 = load_bitmap("Kloppo.bmp", NULL);
24
    Kloppo = load_bitmap("Kloppo.bmp", NULL);
25
26
    draw_sprite(buffer,Kloppo,220,400);
27
    blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
28
    clear(buffer);
29
    Wait(Wartezeit);
30
31
    draw_sprite(buffer,Lauf7,240,400);
32
    blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
33
    clear(buffer);
34
    Wait(Wartezeit);
35
36
    draw_sprite(buffer,Lauf6,240,400);
37
    blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
38
    clear(buffer);
39
    Wait(Wartezeit);

Seltsamerweise klappt das nur mit einigen bmp´s. Sobald 
draw_sprite(buffer,Lauf6,240,400); ausgeführt wird, stürzt das Programm 
wie gesagt mit einem Segmentation fault ab, wenn ich im debugger bin.

Achja ich benutze übrigens CODE::BLOCKS, mit allegro_mingw_4.2.2

MfG Chaos

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

j. t. schrieb:

> draw_sprite(buffer,Lauf6,240,400); ausgeführt wird, stürzt das Programm
> wie gesagt mit einem Segmentation fault ab, wenn ich im debugger bin.

Dann solltest du vielleicht den erhaltenen Pointer auf NULL überprüfen 
und wenn er NULL ist eine Fehlermeldung ausgeben: Bild xyz konnte nicht 
geladen werden.

Dann kann dein Benutzer überprüfen, was da schief geht. Bild nicht 
gefunden. PFaad nicht gefunden. Ev. ein Bildformat, mit dem die Lib 
nicht klar kommt. Kein Speicher mehr im System frei, Bild zu groß, .... 
Möglichkeiten gibt es viele, warum ein Bild nicht geladen werden kann. 
Aber wenn dem so ist, kannst du nicht einfach in deinem Programm weiter 
machen als ob nichts gewesen wäre.

von J. T. (chaoskind)


Lesenswert?

Das mit der Größe hab ich auch schon im Verdacht gehabt. Das Format ist 
überall das selbe. Mit Paint erstellte 24bit.bmp. Ich hab schon 
versucht, die Bilderdeutlich kleiner zu machen, sogar kleiner als dass, 
das funktioniert.

Das letzte was mir einfällt, wäre noch das Seitenverhältnis, das hab ich 
noch nicht getestet....

von J. T. (chaoskind)


Lesenswert?

Selbst wenn ich das Bild auf exakt die selbe Größe wie das 
funktionierende skaliere(in Paint), geht es nicht.....

Auch am Speicher sollte es nicht liegen, lade ich nur das 
funktionierende Bild, geht es ja, aber auch wenn ich das nun gleich 
große andere Bild als einziges Laden lasse, klappt es nicht.

Mit etwas ratlosen Grüßen,
Chaos

von J. T. (chaoskind)


Lesenswert?

Der Hinweis mit dem NULL-Pointer war schonmal gut.

if (Kloppo == NULL)
    {
        return 1;
    }
    if (LaufStart == NULL)
    {
        return 1;
    }

Bei LaufStart(das Bild was er nicht darstellen kann) gibt mir dann auch 
1 zurück.... Also wird das Bild wohl garnicht erst geladen.

Hat noch wer eine Ahnung, wodran das liegen könnte? Wie gesagt, beide 
Bilder sind gleich groß (76*115), in 24bit-Farbtiefe.

von J. T. (chaoskind)


Lesenswert?

Langsam bin ich mit meim Latein am Ende. Ich hab nun mal eine Kopie von 
dem Bild mit dem es klappt gemacht, und auch mit der Kopie geht es 
nicht. Auch nicht, wenn ich das funktionierende garnicht erst lade.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sieh Dir den Quelltext der Funktion load_bitmap an.

von Karl H. (kbuchegg)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Sieh Dir den Quelltext der Funktion load_bitmap an.

Alternativ und gleich vorweg: ich kenne dieses Framework nicht. Aber 
wenn ein Framework derartige Funktionen anbietet, wie zb eine 
Ladefunktion, die bei irgendeinem Fehler einfach einen NULL-Pointer 
liefert dann gibt es meistens auch irgendeine Fehler-Funktion, mit der 
man den letzten aufgetretenen Fehler abfragen kann.
Ich kann mir ehrlich nicht vorstellen, dass dich ein relativ bekanntes 
Framework da im Regen stehen lässt.


Edit:
gefunden.

Allegro gibt dir einen String, der (hoffentlich) den letzten Fehler 
genauer benennt

http://manpages.ubuntu.com/manpages/raring/man3/allegro_error.3alleg4.html
1
extern char allegro_error[ALLEGRO_ERROR_SIZE];
2
3
BITMAP* checked_load_bitmap( const char* fileName )
4
{
5
  BITMAP* bmp;
6
7
  bmp = load_bitmap( fileName );
8
  if( bmp == NULL )
9
    allegro_message( "Loading Bitmap\n'%s'\nfailed!\nError `%s'\n",
10
                             fileName, allegro_error);
11
12
  return bmp;
13
}

sieh mal nach, ob load_bitmap da einen sinnvollen Fehlertext 
hinterlässt, der dich weiter bringt.

von J. T. (chaoskind)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Sieh Dir den Quelltext der Funktion load_bitmap an.

Das hab ich schon versucht, wenn ich aber rechtsklick auf load_bitmap 
mach und dann auf show definition oder wie es heißt klickke, sagt er 
mir, er hätte nix dergleichen gefunden....

@Karl-Heinz:
Danke dir, das werd ich mal versuchen, ich meld mich heut abend nochmal, 
nun bin ich erstmal unterwegs

von Karl H. (kbuchegg)


Lesenswert?

j. t. schrieb:
> Rufus Τ. Firefly schrieb:
>> Sieh Dir den Quelltext der Funktion load_bitmap an.
>
> Das hab ich schon versucht, wenn ich aber rechtsklick auf load_bitmap
> mach und dann auf show definition oder wie es heißt klickke, sagt er
> mir, er hätte nix dergleichen gefunden....

Kommt drauf an, was du downgeloaded hast.
Das Zip-File, das ich mir gerade angesehen habe, kommt komplett mit 
Source Code.

Da du wahrscheinlich eine Lib zu deinem Projekt linkst, ist das nicht 
ungewöhnlich, dass deine IDE den Source Code nicht findet. Da musst du 
dann eben selber ran und mittels grep Werkzeugen die in der jeweiligen 
Situation relevanten Codestellen finden können.
Auch kann es unter Umständen, je nach IDE, sinnvoll sein, nicht gegen 
eine fertige Lib zu linken, sondern ein Projekt so aufzusetzen, dass man 
im Debugger in den Source Code reinsteppen kann.

Sorry, aber so ist das nun mal. Wer programmieren will, muss ein bischen 
mehr können und sich ein bischen mehr selbst helfen können, als die 
Sekretärin vom Boss, die gerade mal mit Word und Excel einigermassen 
umgehen kann.

von J. T. (chaoskind)


Lesenswert?

Karl Heinz schrieb:
1
> extern char allegro_error[ALLEGRO_ERROR_SIZE];
2
> 
3
> BITMAP* checked_load_bitmap( const char* fileName )
4
> {
5
>   BITMAP* bmp;
6
> 
7
>   bmp = load_bitmap( fileName );
8
>   if( bmp == NULL )
9
>     allegro_message( "Loading Bitmap\n'%s'\nfailed!\nError `%s'\n",
10
>                              fileName, allegro_error);
11
> 
12
>   return bmp;
13
> }

damit öffnet sich leider nur ein Fenster, in dem er mir dann sagt, die 
Datei konnte nicht geladen werden...

auch wenn ich eine Datei laden lasse, die es nicht gibt, kommt nur die 
selbe Fehlermeldung, nichtmal etwas ala  "die Datei konnte nicht 
gefunden werden"...

Was ist denn so ein grep-Werkzeug? Noch nie von gehört. Ich werd 
nebenbei mal Tante gugel fragen, aber falls du da ne schlüßige greifbare 
Erklärung hast, ist mir das immer lieber =)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

j. t. schrieb:
> Was ist denn so ein grep-Werkzeug?

Volltextsuche über mehrere Dateien in mehreren Verzeichnissen.

Windows liefert mit findstr ein ähnliches Werkzeug mit.

Beispiel:

findstr /s /c:"load_bitmap" c:\*.c

Sucht nach dem Begriff "load_bitmap" in allen *.c-Dateien in allen 
Verzeichnissen auf Laufwerk C:

Achtet auf Groß- und Kleinschreibung; soll das nicht geschehen, ist 
vor dem /c: -Parameter noch ein /i hinzuzufügen:

findstr /s /i /c:"load_bitmap" c:\*.c

von J. T. (chaoskind)


Lesenswert?

Ich konnte das Problem inzwischen lösen. Es lag doch am Speicherort der 
bmp. In dem Tutorial hieß es, die Bilder müssen im selben Verzeichnis 
liegen wie die exe, sie müssen aber im selben Verzeichnis liegen, wie 
die main.c, zumindest solang man aus Codeblocks raus startet. Im 
Projektordner hatte ich zufällig auch einmal die Datei reinkopiert, was 
erklärt, wieso es immer nur mit der einen Datei ging.

Wenn man aber die die exe von ausserhalb Codeblocks startet, müssen die 
Bilddateien sehr wohl im selben Ordner wie die exe sein.

MfG Chaos

von Rolf Magnus (Gast)


Lesenswert?

j. t. schrieb:
> In dem Tutorial hieß es, die Bilder müssen im selben Verzeichnis
> liegen wie die exe, sie müssen aber im selben Verzeichnis liegen, wie
> die main.c, zumindest solang man aus Codeblocks raus startet.

Wenn du in deinem Programm nicht explizit einen Pfad angibst, müssen die 
Dateien im aktuellen Arbeitsverzeichnis (current working directory) 
liegen.

von Karl H. (kbuchegg)


Lesenswert?

Rolf Magnus schrieb:
> j. t. schrieb:
>> In dem Tutorial hieß es, die Bilder müssen im selben Verzeichnis
>> liegen wie die exe, sie müssen aber im selben Verzeichnis liegen, wie
>> die main.c, zumindest solang man aus Codeblocks raus startet.
>
> Wenn du in deinem Programm nicht explizit einen Pfad angibst, müssen die
> Dateien im aktuellen Arbeitsverzeichnis (current working directory)
> liegen.

Hinzuzufügen ist nur noch (das ist mir in der Antwort ein bischen 
untergegangen), das man in den meisten IDEs in den diversen 
Projektoptionen einstellen kann, in der Umgebung welchen Working 
Directories ein EXE aus der IDE heraus zu starten ist. Das hat zb den 
Sinn, dass die Debug Version und die Release Version (die oft auf 
verschiedenen Verzeichnissen entstehen) mit demselben Working Directory 
aus der IDE heraus laufen können. Das wiederrum ist deswegen 
interessant, wenn es so wie hier entsprechende 'Zuliefer-Dateien' gibt, 
die man für die Debug und die Release Version nicht duplizieren möchte.

: Bearbeitet durch User
von Karl Käfer (Gast)


Lesenswert?

Hallo,

Karl Heinz schrieb:
> Hinzuzufügen ist nur noch (das ist mir in der Antwort ein bischen
> untergegangen), das man in den meisten IDEs in den diversen
> Projektoptionen einstellen kann, in der Umgebung welchen Working
> Directories ein EXE aus der IDE heraus zu starten ist.

Und da behaupten manche Leute immer noch, IDEs könnten einem die Arbeit 
erleichtern... was für ein Selbstbetrug. ;-)

LG,
Karl

von Masl (Gast)


Lesenswert?

Karl Käfer schrieb:
> Und da behaupten manche Leute immer noch, IDEs könnten einem die Arbeit
> erleichtern... was für ein Selbstbetrug. ;-)

Stimmt.
Es ist einfacher, in der Konsole mittels cd in das 
Wunsch-Working-Directory zu wechseln und dann das gewünschte Binary 
(Debug oder Release) unter ausschreiben des gesamten Pfades (zwecks 
meiner auch den relativen, wenn dieser kürzer ist) zu starten.

Versteh mich ned falsch. Konsole ist toll.
Aber in vielen Fällen ist eine (korrekt eingerichtete) IDE besser.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Masl schrieb:
> Es ist einfacher, in der Konsole mittels cd in das
> Wunsch-Working-Directory zu wechseln und dann das gewünschte Binary
> (Debug oder Release) unter ausschreiben des gesamten Pfades (zwecks
> meiner auch den relativen, wenn dieser kürzer ist) zu starten.

Dann läuft's aber nicht im Debugger.

von Masl (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Dann läuft's aber nicht im Debugger.

Ups, dachte die Ironie würde so heraustriefen dass diese nicht zu 
übersehen wäre.

von Udo S. (urschmitt)


Lesenswert?

Karl Käfer schrieb:
> Und da behaupten manche Leute immer noch, IDEs könnten einem die Arbeit
> erleichtern... was für ein Selbstbetrug. ;-)

Genau, es lebe der Kommandozeilendebugger und der Kommandozeileneditor 
edlin war praktisch die Krone der Informatik. Da war vi schon ein 
starker Rückschritt :-P

von Karl H. (kbuchegg)


Lesenswert?

Karl Käfer schrieb:
> Hallo,
>
> Karl Heinz schrieb:
>> Hinzuzufügen ist nur noch (das ist mir in der Antwort ein bischen
>> untergegangen), das man in den meisten IDEs in den diversen
>> Projektoptionen einstellen kann, in der Umgebung welchen Working
>> Directories ein EXE aus der IDE heraus zu starten ist.
>
> Und da behaupten manche Leute immer noch, IDEs könnten einem die Arbeit
> erleichtern... was für ein Selbstbetrug. ;-)
>

Wieviele 'Gleichgesinnte' es hier im Forum gibt, kann ich nicht sagen. 
Aber ich gehöre noch zu der Generation, die ohne IDE gelernt hat. 
Schlicht und ergreifend deshalb, weil die Rechner damals noch zu schwach 
auf der Brust waren.
Wenn du je ein größeres Projekt ohne IDE durchgezogen hättest, würdest 
du so einen Unsinn nicht von dir geben.

Ja ich geb dir recht, dass sich so manches Verhalten einer IDE nur dann 
erschliesst, wenn man versteht, was sich unter der bunten Oberfläche auf 
einer Commandline abspielen würde. Aber das ist kein Argument um IDEs zu 
verteufeln, sondern maximal ein Argument dafür, nicht nur Klicki-Bunti 
zu betreiben, sondern sich minimale Kentnisse anzueignen, wie man einen 
Computer mittels Command Line steuert und mit welchen Konzepten da 
gearbeitet wird.

: Bearbeitet durch User
von Karl Käfer (Gast)


Lesenswert?

Hi Masl,

Masl schrieb:
> Karl Käfer schrieb:
>> Und da behaupten manche Leute immer noch, IDEs könnten einem die Arbeit
>> erleichtern... was für ein Selbstbetrug. ;-)
>
> Stimmt.
> Es ist einfacher, in der Konsole mittels cd in das
> Wunsch-Working-Directory zu wechseln und dann das gewünschte Binary
> (Debug oder Release) unter ausschreiben des gesamten Pfades (zwecks
> meiner auch den relativen, wenn dieser kürzer ist) zu starten.

Ordentliche Shells beherrschen Features wie Tab-Completion, die 
Verkettung von Befehlen, Batchdateien und etwas wie GNU readline...

Liebe Grüße,
Karl

von Masl (Gast)


Lesenswert?

> Karl Käfer schrieb:
> Ordentliche Shells beherrschen Features wie Tab-Completion, die
> Verkettung von Befehlen, Batchdateien und etwas wie GNU readline...
> Liebe Grüße,
> Karl

Ordentliche IDEs haben dazu einen (1) Knopf.

von Karl Käfer (Gast)


Lesenswert?

Hallo Udo,

Udo Schmitt schrieb:
> Karl Käfer schrieb:
>> Und da behaupten manche Leute immer noch, IDEs könnten einem die Arbeit
>> erleichtern... was für ein Selbstbetrug. ;-)
>
> Genau, es lebe der Kommandozeilendebugger und der Kommandozeileneditor
> edlin war praktisch die Krone der Informatik. Da war vi schon ein
> starker Rückschritt :-P

Du mißverstehst mich. Ich spreche mich nicht grundsätzlich gegen 
grafische Benutzerschnittstellen aus, sondern hinterfrage nur den Sinn 
dieser hoch integrierten Teile, die etliche Werkzeuge in einer 
(angeblich) komfortablen Oberfläche zusammenfassen. Meine Erfahrung mit 
etlichen solcher Werkzeuge ist, daß sie den Blick auf das Wesentliche -- 
den Code, die Ausgaben des Compilers und anderer Werkzeuge -- 
einschränken und keineswegs komfortabler sind als eine Sammlung 
leistungsfähiger Standalone-Tools, die grafisch sein können, aber nicht 
müssen. Außerdem drängen einem viele dieser Werkzeuge einen bestimmten 
Workflow auf, der meistens, aber eben nicht immer zum spezifischen 
Projekt paßt.

Liebe Grüße,
Lutz

von Karl Käfer (Gast)


Lesenswert?

Hallo Karl Heinz,

Karl Heinz schrieb:
> Karl Käfer schrieb:
> Wieviele 'Gleichgesinnte' es hier im Forum gibt, kann ich nicht sagen.

Das spielt auch keine Rolle, es sei denn, man wollte ein Argumentum ad 
populum konstruieren, und das will hier natürlich keiner.

> Wenn du je ein größeres Projekt ohne IDE durchgezogen hättest, würdest
> du so einen Unsinn nicht von dir geben.

Ja, Meister, ich bin nur ein unwürdiger Wurm und habe keine Ahnung. Ich 
lebe zwar schon seit gut 25 Jahren von der Softwareentwicklung, aber 
über "Hello World" und Conways "Game of Life" bin ich bisher leider noch 
nicht hinaus gekommen. Aber bitte sag das nicht meinen Kunden! ;-)

> Ja ich geb dir recht, dass sich so manches Verhalten einer IDE nur dann
> erschliesst, wenn man versteht, was sich unter der bunten Oberfläche auf
> einer Commandline abspielen würde.

Dann sind wir ja wenigstens in dem Punkt einig, daß man trotzdem wissen 
sollte, was unter der Haube passiert. Und dann benutze ich eine IDE, um 
genau diese Abläufe wieder zu verbergen? Wozu?

> Aber das ist kein Argument um IDEs zu verteufeln,

Habe ich IDEs "verteufelt"? Gut, daß Du das sagst, mir selbst wäre das 
gar nicht aufgefallen. Ohne Deinen Hinweis hätte ich jetzt doch wirklich 
davon ausgegangen, lediglich gefragt zu haben, worin denn wohl bitte der 
Vorteil solcher hochintegrierten Funktionsmonster besteht, verglichen 
mit einer modernen Kommandozeile mit einer dem jeweiligen Zweck präzise 
anpaßbaren Sammlung von stabilen, flexiblen und leistungsfähigen 
Werkzeugen.

Nichts für ungut, aber die Behauptung, daß ich keine Ahnung hätte, 
reicht mir als Argument in der Sache irgendwie nicht aus. Zumal Du davon 
ausgehen kannst, daß ich solche Diskussionen bereits mit etlichen 
Kollegen geführt habe. Viele lächeln da erstmal spöttisch, bis sie mir 
eine Zeit lang über die Schulter geschaut haben. In der Regel friert 
dieses etwas mitleidige Lächeln dann nach ein paar Minuten erst langsam 
ein und weicht dann einer Mimik, die zwischen Irritation und 
Nachdenklichkeit oszilliert. ;-)

Liebe Grüße,
Karl

von Karl Käfer (Gast)


Lesenswert?

Hallo Masl,

Masl schrieb:
>> Karl Käfer schrieb:
>> Ordentliche Shells beherrschen Features wie Tab-Completion, die
>> Verkettung von Befehlen, Batchdateien und etwas wie GNU readline...
>
> Ordentliche IDEs haben dazu einen (1) Knopf.

Das ist, zugegeben, ein kaum zu unterschätzender Vorteil für Leute, die 
nur mit zwei Fingern tippen. Aber wie kann ich mit dem Knopf die 
Fehlermeldungen des Compilers durchsuchen, oder LLVM statt GCC 
einstellen? Das scheint wohl ein ziemlicher Wunderknopf zu sein, wow.

Liebe Grüße,
Karl

von Karl H. (kbuchegg)


Lesenswert?

Karl Käfer schrieb:

>> Ordentliche IDEs haben dazu einen (1) Knopf.
>
> Das ist, zugegeben, ein kaum zu unterschätzender Vorteil für Leute, die
> nur mit zwei Fingern tippen. Aber wie kann ich mit dem Knopf die
> Fehlermeldungen des Compilers durchsuchen,

Im Devolper Studio ist das zum Beispiel F4.
Und die IDE tut noch mehr. Die sucht auch gleich noch die bewusste Zeile 
im Editor raus und stellt den Cursor dort hin. Wenn ich noch mal F4 
drücke, sucht die IDE die nächste Codestelle für den nächsten Fehler. 
Cool, wa?

Und deinen Sarkasmus kannst du dir in die Haare schmieren. Sonderlich 
viel scheinst du noch nicht mit IDEs gearbeitet zu haben.

>  In der Regel friert dieses etwas mitleidige Lächeln dann nach ein paar Minuten 
erst langsam ein und weicht dann einer Mimik, die zwischen Irritation und 
Nachdenklichkeit oszilliert. ;-)

Dann scheinen  deine Kollegen noch weniger drauf zu haben als du.
Aber das sind wir schon gewohnt, dass sich jeder mit einem 30 Stunden 
Wifi Schnellsiederkurs heute SOftwareentwickler schimpft.

: Bearbeitet durch User
von Karl Käfer (Gast)


Lesenswert?

Lieber Karl Heinz,

Karl Heinz schrieb:
> Im Devolper Studio ist das zum Beispiel F4.
> Und die IDE tut noch mehr. Die sucht auch gleich noch die bewusste Zeile
> im Editor raus und stellt den Cursor dort hin. Wenn ich noch mal F4
> drücke, sucht die IDE die nächste Codestelle für den nächsten Fehler.
> Cool, wa?

Wie soll ich das denn sagen, ohne sarkastisch zu wirken? Der GNU 
Debugger (gdb) kann das auf der Kommandozeile seit mehr als zwanzig 
Jahren, ebenso natürlich auch jedes seiner Frontends: ddd, xxdbg, kdbg, 
und der GUD-Mode meines GNU Emacs natürlich auch. Allerdings nimmt die 
Häufigkeit, mit der ich einen Debugger benötige, glücklicherweise ab.

Dafür kann ich den Emacs (und den GNU Debugger) problemlos auch über 
eine schmalbandige Satellitenverbindung remote auf der Kommandozeile 
benutzen, das kommt bei mir als Yachtsegler in internationalen Gewässern 
durchaus häufiger vor. Probier' das doch mal mit einer reinen GUI-IDE, 
das ist ja schon mit 100 MBit kein Vergnügen. ;-)

> Und deinen Sarkasmus kannst du dir in die Haare schmieren.

Das werde ich sehr gerne tun, sobald Du Dich sinnvoll und sachlich an 
der Diskussion beteiligst. Ich weiß, daß Du mehr drauf hast, als Dich 
wie ein Kind aufzuführen, dem jemand sein Förmchen weggenommen hat. Ich 
will Dir nichts Böses und habe auch nichts gegen Dich -- im Gegenteil.

> Sonderlich viel scheinst du noch nicht mit IDEs gearbeitet zu haben.

Über die Jahre habe mir immer wieder solche Programme angeschaut, aber 
bisher einfach noch nichts entdeckt, daß ich nicht genauso komfortabel, 
gleichzeitig aber viel flexibler haben kann.

Wenn Du hier über grep(1) referierst, vermute ich mal, daß Du mit UNIX 
(oder Linux) vertraut bist. Mein Ansatz entspricht hier der klassischen 
UNIX-Philosophie: viele Werkzeuge können flexibel miteinander kombiniert 
werden, und jedes Werkzeug beherrscht nur eine einzige Aufgabe, die aber 
dann richtig, richtig gut.

Ich kenne noch TurboC++ 4.5, aber natürlich auch moderne IDEs wie 
Eclipse, kdevelop, QT Creator, Visual Studio, SunOne, und ein paar 
andere. Es ist explizit nicht so, daß ich solche Werkzeuge nicht immer 
wieder angeschaut und ihnen eine Chance gegeben hätte -- nicht, weil ich 
meines GNU Emacs überdrüssig wäre, sondern weil ich mich seit Jahren 
frage, was um alles in der Welt ausgerechnet Softwareentwickler dazu 
motiviert, IDEs zu benutzen, die ihre Flexibilität und ihre 
Kontrollmöglichkeiten einschränken. Normale Anwender, ok -- aber 
Entwickler?

> Dann scheinen  deine Kollegen noch weniger drauf zu haben als du.
> Aber das sind wir schon gewohnt, dass sich jeder mit einem 30 Stunden
> Wifi Schnellsiederkurs heute SOftwareentwickler schimpft.

Ja, genau: alle blöd, außer Dir. Aber wenn Du Dich in den letzten fünf 
Jahren mal an einem modernen UNIX- oder Linux-System angemeldet, einen 
Mobilfunkteilnehmer bei Vodafone angerufen, oder in Europa mit einer 
Kreditkarte bezahlt hast: dann war da mit Sicherheit eine Software im 
Spiel, an der ich in irgendeiner Weise beteiligt war oder bin.

Liebe Grüße,
Karl

von Masl (Gast)


Lesenswert?

Ich kann auch den gcc, gdb und vim von der Konsole aus Bedienen. Ich 
weiß also, was unter der Haube läuft. Trotzdem musste ich (für mich) 
feststellen, dass eine IDE mich produktiver arbeiten lässt.

Zugegeben, es steckt Aufwand zum Lernen und Einrichten dahinter, aber 
irgendwann wird Eclipse dann mal sehr mächtig. OK, vielleicht 
ressourcenhungrig, aber das steht hier nicht zur Debatte.

Ich sehs so: für jede Arbeit das richtige Werkzeug. Wenn ich mich auf 
eine bestimmte Philosophie (z.B. nur freie Software) oder ein bestimmtes 
UI (z.B. nur GUI oder nur CLI) festlegen würde, so würde ich mich nur 
selbst einschränken.

Oder, um Obi-Wan zu zitieren:
1
Nur ein Sith kennt nichts als Extreme.

von Karl Käfer (Gast)


Lesenswert?

Hallo Masl,

Masl schrieb:
> Ich kann auch den gcc, gdb und vim von der Konsole aus Bedienen. Ich
> weiß also, was unter der Haube läuft. Trotzdem musste ich (für mich)
> feststellen, dass eine IDE mich produktiver arbeiten lässt.

Warum bist Du damit produktiver, wie kommst Du darauf?

> Zugegeben, es steckt Aufwand zum Lernen und Einrichten dahinter, aber
> irgendwann wird Eclipse dann mal sehr mächtig.

Worin besteht denn diese Mächtigkeit? Das war doch meine Frage. Wenn das 
Teil so enorm mächtig ist, müßte die Antwort doch leichtfallen.

> OK, vielleicht ressourcenhungrig, aber das steht hier nicht zur Debatte.

Für mich schon, insbesondere, wenn ich den Einrichtungs-, 
Konfigurations- und Wartungsaufwand und die dafür benötigten Ressourcen 
einbeziehe. Das war schließlich der Ausgangspunkt der ganzen Debatte.

> Ich sehs so: für jede Arbeit das richtige Werkzeug.

Das sehe ich genauso. Deswegen versuche ich zu verstehen, worin denn nun 
der Mehrwert einer IDE besteht, daß sich dafür sogar der Einarbeitungs- 
und Konfigurationsaufwand eines solchen Werkzeuges lohnt. Aber bislang 
konnte mir niemand eine vernünftige, sachliche Antwort darauf geben und 
mich persönlich anzugreifen und mir Ahnungslosigkeit zu unterstellen, 
ist, sorry, keine Antwort, sondern nur unsachlich, arrogant und hilflos.

Liebe Grüße,
Karl

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.