• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

C Rätsel

mampfi

Hacker
Anbei ein kleines C-Rätsel, dass ich in einem C-Fehlersuch-Buch gefunden habe.

Ohne es auszuprobieren !!!!!!!!!!!

Macht dieses Programm?


#include <stdio.h>

int main(void)

{
unsigned char i;
char vektor[10];

for (i=0; i <= 10; i++) vektor=i;

for (i=0; i <= 10; i++) printf("%d\n", i[vektor]); /////// Diese Zeile ist die interessante


puts("Hauptprogramm Fertig");

}
 

Dakuan

Hacker
Ich habe früher mal das "Dr. Dobbs Journal" gelesen. Da waren jeden Monat solche Dinger drinn. Als Anzeige für PC-Lint.
Wie gcc darauf reagiert weiss ich noch nicht, aber mein Borland C++ wird das sicher nicht übersetzen wollen weill i kein Array ist.
Aber solche Dinger schärfen den Blick.
Dakuan
 
OP
M

mampfi

Hacker
Das Interessante an dem Rätsel ist, dass da nicht solche Brocken drinstehen wie etwa

if (*rec->*a++ - ++b - *c+=d)
{
}

sondern der Gimmick in dem einfachen Quellcode steckt.

Muss zugeben, rausgekriegt hab ichs nicht. Die Erklärung ist aber ganz einfach.


Ein C-Compiler sollte den Source ohne Warnungen kompilieren.
 

Dakuan

Hacker
Jetzt bin ich überrascht! BCC 5.1 hat's übersetzt und das Prog. läuft unter Win98!
aber:
Code:
Compiling D:\prg\allg\test\test1.c
  test1.c(7,51):Call to function 'printf' with no prototype
  test1.c(9,30):Call to function 'puts' with no prototype
  test1.c(10,2):Function should return a value
  ...
Abgesehen davon dass ein ordentliches Programm keine Warnungen erzeugen sollte, verstehe ich nicht warum es geht. Und dabei dachte ich dass ich zumindest C Grundkenntnisse hätte :(
Dakuan
 
OP
M

mampfi

Hacker
Der C-Crack bin ich auch nicht ehrlich gesagt.
Komm eigentlich aus der Turbo-Pascal-Richtung.

Zur Erklärung, ist einfache Pointer-Arithmetik.

Der C-Compiler liest es so:

i[vektor] = *(i +vektor) i ist die Startadresse und dazu wird vektor addiert.

und i +vektor = vektor +i also ist *(i + vektor) = *(vektor + i)

was heisst dass i[vektor] = vektor ist.

Wehe, wenn der gekündigte C-Crack auf die Art und Weise seine Quellcodes verschandelt
:twisted:
 

Dakuan

Hacker
Mag ja von der Mathematik her richtig sein, aber irgendwie bin ich damit unzufrieden.
Normalerweise schreibe ich gaaanz einfache Formeln und der Compiler hat immer was zu meckern :(
Dies ist der erste Fall in 20 Jahren wo der Compiler etwas durchgehen lässt was ich für nicht richtig halte... Wenn das meine Kollegen wüssten, hätte die Pascal Front wieder einige Pluspunkte gewonnen :lol:
Na ja, das Leben ist hart, aber ungerecht.
Dakuan
 
OP
M

mampfi

Hacker
Und grade diese Finessen sind immer das Argument der "C-Wahnsinnigen" gewesen, warum C so toll ist.

Allerdings hat Niklaus Wirth schon genau gewusst, warum er PASCAL erfunden hat.

Die Militärsprache ADA stammt ja aus der Familie der pascal-ähnlichen Sprachen, weil das Pentagon immer über C-Bugs gestolpert ist.

Ich finde solche Spielereien ganz lustig.

In der Freizeit. :wink:
 

framp

Moderator
Teammitglied
C (aber auch C++) hat eben die eingebaute Unkuenbarkeitsgarantie. Allerdings wird das immer erst dann festgestellt, wenn der Mitarbeiter gekuendigt hat und ein Nachfolger den Code maintainen darf/muss :-(
 
OP
M

mampfi

Hacker
Ehrlich gesagt, ich muss zugeben, ich hab schon mal ein paar Sauereien in einen Source-Code eingebaut, um dem "Nachfolger" klarzumachen, was er sich mit seinen Sprüchen eingehandelt hat.

Ein Kaufmann, der sich Programmierer nannte.

Die Sprache hieß übrigens Excel 4.0 und mann konnte damals selbstmodifizierenden Code damit schreiben.


Wie endete die Geschichte? Der Schöpfer des Programms übernahm das Projekt wieder und bekam von mir eine "freundschaftliche Erklärung" der Änderungen. :twisted:
 
OP
M

mampfi

Hacker
Nachtrag:

Funktioniert auch wenn vektor vom Typ "unsigned long" ist also einen Datentyp hat, der größer ist als 1 Byte.

Warum das funzt ist mir allerdings wirklich ein Rätsel.
 

Dakuan

Hacker
Ich finde C schon OK, so wie es ist. Ich denke man kann in jeder Programmiersprache Blödsinn machen. Ich persönlich nutze viele Freiheiten, die C/C++ bietet nicht aus, weil ich bestrebt bin, meinen Code so zu schreiben, daß ich selbst ihn nach einem halben Jahr noch verstehen kann :wink:
Ich hasse es, wenn Variablen mitten im Code declariert werden. Desshalb habe ich auch "Probleme" mit PHP, wo Variablen sogar den Typ wechseln können :evil:
Andererseits habe ich schon perfekt strukturierten Code in (standard/ur) Basic oder in Assembler gesehen. Das hängt alles von der Disziplin des Programmierers ab.
Selbst modifizierenden Code haben wir mal produziert, als die Rechner noch mit einer Taktfrequenz von ca. 3MHz liefen und ein Bios in einem 2 oder 4 kByte E-Prom passen musste. Heute kaum vorstellbar.
Dakuan
 

framp

Moderator
Teammitglied
Hab maln bischen bei K&R nachgelesen wie auch das Prog ausfuehren lassen.

(1) a <=> *(a+i)

=> i[vektor] <=> *(i+vektor)
=> i[vector] <=> vector

Und das ist das Ergebnis was man erhaelt: Die Zahlen 0-10

An sich (nach Lektuere von K&R) ganz einfach. Allerdings sind sich die meisten (auch ich) nicht der Aequivalenz der o.g. Beziehung (1) bewusst bzw erinnern sich dieser nicht mehr :-(
 
OP
M

mampfi

Hacker
Naja, PHP ist in Bezug auf die Variablen-Deklaration ja sowas wie das Basic des Webs.

Das Progrämmchen hab ich in einem der beiden Bücher gefunden.

1) No Bugs von David Thielen
2) Expert C Programming von Peter vn der Linden

Werd mal schauen, wo ich das gefunden hab.
 

spunti

Hacker
Für mich zeigt der Thread wieder klar, warum ich ein Javafreund bin.
Ansonsten seh ich das so wie Dakuan: Code muß verständlich sein.

grüße von der front:)
spunti
 

Zinnwurm

Hacker
Ich melde mich jetzt bloß als leidenschaftlicher PHP-Progger zu Wort. ^^

Ich deklariere meine Variablen auch am Anfang eines Skripts, das lässt sich durchaus machen. Dabei fällt mir ein, dass ich das seit einiger zeit nichtmehr gemacht habe, weil ich fast nur OO arbeite :p
Nein, aber nur, weil man Variablen jederzeit automatisch deklarieren kann, muss man es ja nicht, sondern kann sie brav an den Anfang der Datei schreiben. Ich finde dagegen es doch auch praktisch, das man nicht alles vor verwendung deklarieren muss. Ich nutze das ausschließlich bei Schleifenvariablen, die sonst nichtmehr gebraucht werden. Da erspart das einfach Arbeit. ^^
 

Dakuan

Hacker
Nein, aber nur, weil man Variablen jederzeit automatisch deklarieren kann, muss man es ja nicht, sondern kann sie brav an den Anfang der Datei schreiben.
Das Problem ist doch, dass der Variablentyp sich durch diese automatische Zuweisung ändern kann. Das ist eine potienzielle Fehlerquelle, und da möchte ich zumindest drauf aufmerksam gemacht werden.
Ich nutze das ausschließlich bei Schleifenvariablen, die sonst nichtmehr gebraucht werden
Bei Schleifenvariablen ($i, $j, $k) sollten sowiso Sonderregeln gelten (Freiwild) :wink:
Dakuan
 
Oben