Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Zeigerspielereien! Hilfe !!!

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
25.06.2003, 18:44 Uhr
Kathrin



Geben Sie für das folgende Programm hinter den betreffenden Druck Statements ab wekche Werte ausgegeben werden(Die Werte können Sie auf dezimaler Zahlenbasis angeben).

Vorrausetzungen:
-Beginn des Vektors 'sv' aber Speicherstelle 500
-sizeof(long)=8; sizeof(int)=4; sizeof(short)=2;


C++:
#include <stdio.h>

#define P(p) printf("(p) == %x\n", (p))
#define LEN 4 /* Elemente im long Vektor */
#define POS 2 /* Position im long Vektor */

short sv[LEN * sizeof(long) / sizeof(short)];
short * zs;

long * zl;
long (* zlv) [LEN];

main() {
register int i;

for (i = 0; i * sizeof(short) < sizeof sv; i++)
P( sv[i] = i );
putchar('\n');

P( & sv[POS * sizeof(long) /sizeof(short)] );
P( zs = sv + POS * sizeof(long) /sizeof(short) );
P( zl = (long *) sv + POS);
P( i = (int) sv + POS  * sizeof(long) );
putchar('\n');
    
P( sv[POS * sizeof(long) /sizeof(short)] );
P( * zs);
P( * (short *) i);
putchar('\n');

P( * zl);
P( * (long *) i);
P( * (long *) zs);
P( (long) sv[POS * sizeof(long) /sizeof(short)] );
putchar('\n');

P( zlv = (long (*) [LEN]) sv);
P( zlv + POS );
P( zl = (* zlv) + POS );
putchar('\n');

P( * zl);

}




Das wär ne Aufgabe die vielleicht morgen in meiner Klausur drankommt und ich check die Zeigerspielerei echt noch net so ganz! Wär einer so nett und würde mal das Ding durchgehen und seine Ergebnisse Posten ?? Ihr würdet mir damit einen RIESEN GEFALLEN TUN !!!
DANKE !!!!!!

Grüße Kathrin!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
25.06.2003, 23:07 Uhr
Kathrin



Kann keiner Helfen ??
Das Ding ist wirklich nicht ohne....
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
25.06.2003, 23:16 Uhr
Hans
Library Walker
(Operator)


Hi,

doch können wohl schon. Aber haben wohl nicht alle Zeit, es genau und verständlich aufzuschreiben, - eben weil es nicht ohne ist. - Jedenfalls vermute ich das jetzt einfach mal.
Ohne Dir jetzt zu nahe treten zu wollen: Es wäre besser gewesen, wenn Du die Frage schon gestern oder noch eher ins Forum gestellt hättest. Dann hätte man das ganze ruhiger angehen können.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
25.06.2003, 23:43 Uhr
ao

(Operator)


Hallo Kathrin,
ich hab das Programm mal so umgebaut, daß es übersetzbar und ausführbar wurde.

sizeof long == 8 ist so ne Gemeinheit, die einen davon abhalten soll, daß Problem vom Computer lösen zu lassen. Also mußte ich als erstes dafür sorgen, daß long tatsächlich 8 Bytes groß wurde:

C++:
#define long _int64 /* für Microsoft, bei anderen Compilern kann der Typ anders heißen */


Dann hab ich analog zu dem P-Makro ein PP-Makro gebaut, um die Speicheradressen umzurechnen auf Basisadresse 500:

C++:
char * cpsv = (char*)sv;
#define PP(pp) printf ("(pp) == %I64d\n", (_int64)((char*)(pp)-cpsv+(char*)500))


Die Ausgaben hab ich umformatiert, so daß Adressen dezimal (durch PP) und Werte hexadezimal mit führendem 0x (durch P) ausgegeben werden. Der Größen-Prefix I64 sorgt dafür, daß die Zahlenwerte im 64-Bit-(8-Byte)-Format ausgegeben werden, damit auch tatsächlich ein ganzer "long" erscheint (I64 ist Microsoft-spezifisch, glaub ich).

Das komplette Programm sieht damit so aus:

C++:
#include <stdio.h>

#define P(p) printf("(p) == 0x%I64x\n", (_int64)(p))
#define LEN 4 /* Elemente im long Vektor */
#define POS 2 /* Position im long Vektor */

#define long _int64

short sv[LEN * sizeof(long) / sizeof(short)];
short * zs;

long * zl;
long (* zlv) [LEN];

char * cpsv = (char*)sv;
#define PP(pp) printf ("(pp) == %I64d\n", (_int64)((char*)(pp)-cpsv+(char*)500))

main() {
    register int i;

    for (i = 0; i * sizeof(short) < sizeof sv; i++)
        P( sv[ i ] = i );
    putchar('\n');



    PP( & sv[POS * sizeof(long) /sizeof(short)] );
    PP( zs = sv + POS * sizeof(long) /sizeof(short) );
    PP( zl = (long *) sv + POS);
    PP( i = (int) sv + POS * sizeof(long) );
    putchar('\n');

    P( sv[POS * sizeof(long) /sizeof(short)] );
    P( * zs);
    P( * (short *) i);
    putchar('\n');

    P( * zl);
    P( * (long *) i);
    P( * (long *) zs);
    P( (long) sv[POS * sizeof(long) /sizeof(short)] );
    putchar('\n');

    PP( zlv = (long (*) [LEN]) sv);
    PP( zlv + POS );
    PP( zl = (* zlv) + POS );
    putchar('\n');

    P( * zl);
    return 0;

}


Dann erscheinen folgende Ausgaben:


Code:
(p) == 0x0
(p) == 0x1
(p) == 0x2
(p) == 0x3
(p) == 0x4
(p) == 0x5
(p) == 0x6
(p) == 0x7
(p) == 0x8
(p) == 0x9
(p) == 0xa
(p) == 0xb
(p) == 0xc
(p) == 0xd
(p) == 0xe
(p) == 0xf

(pp) == 516
(pp) == 516
(pp) == 516
(pp) == 516

(p) == 0x8
(p) == 0x8
(p) == 0x8

(p) == 0xb000a00090008
(p) == 0xb000a00090008
(p) == 0xb000a00090008
(p) == 0x8

(pp) == 500
(pp) == 564
(pp) == 516

(p) == 0xb000a00090008


Ohne Gewähr, natürlich.

Für die Berechnung zu Fuß:
1. Nicht verwirren lassen.
2. "Preprozessor spielen" und alle konstanten Ausdrücke so weit wie möglich vorab berechnen (POS * sizeof long / sizeof short ergibt z.B. 8 ( 2 * 8 / 2 )). Dann wirds schon übersichtlicher.

Für konkrete Hilfe bei Problemen mit Zeigerarithmetik ists wohl schon ein bißchen spät. Da wäre es gut gewesen, du hättest gezieltere Fragen gestellt als "ich hab das alles nicht verstanden". So bleibt nur, dir viel Erfolg zu wünschen.

Nebenbei bemerkt: Das ist ne typische Prüfungsaufgabe ohne jegliche praktische Bedeutung. In über 8 Jahren als hauptberuflicher Softwareentwickler habe ich *so was* noch nie gesehen, geschweige denn selber geschrieben. Ein Programmierer, der im Real-Life solchen Code abliefert, gehört geteert und gefedert. Meine Meinung dazu.

ao

Dieser Post wurde am 25.06.2003 um 23:45 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
26.06.2003, 22:28 Uhr
~StefanD
Gast


"Ein Programmierer, der im Real-Life solchen Code abliefert, gehört geteert und gefedert."

....und ein Lehrer, der sowas als Prüfung verlangt auch. Meine Meinung dazu.


Stefan.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
26.06.2003, 22:38 Uhr
~Kathrin
Gast


Erstmal Danke für den Lösungsvorschlag und ebenfalls Danke für Eure Kommentare...! Die bauen mich wenigstens ein wenig auf des es nicht zu 100% un meiner schusseligkeit liegt... !
Wär wirklich noch intressant ein paar Meinungen dazu zu hören, vielleicht werd ichs wagen dem Lehrer die Beiträge ma unter die Nase zu halten wenn alle Prüfungen rum sind...! Immerhin sollen damit noch zukünftige Generationen gequält werden....
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
27.06.2003, 00:13 Uhr
ao

(Operator)


Na ja, daß Prüfungsaufgaben manchmal sinnfrei sind, damit muß man leben, glaube ich. Viel schlimmer finde ich den katastrophalen Stil dieses Programms und die Vorstellung, daß die Schüler sich irgendwas davon zum Vorbild nehmen könnten.

Konkret:

1. main retourniert nichts -> im Fall von main kein Fehler (glaube ich), aber auf jeden Fall unschön.

2. Die Deklaration sv [LEN * sizeof long / sizeof short];
Willkürliche Verklausulierung der Längenangabe. Wenn das nicht willkürlich ist, sondern einen Grund hat, gehört das kommentiert. An anderen Stellen ebenso.

3. Die Statements P( i = (int) sv + POS * sizeof(long) ); und P(*(short*)i); und P(*(long*)i);
Willkürliches Umwandeln von Zeigertypen in Ganzzahltypen und zurück, sog. "inconsistent level of indirection". So was ist fast immer ein logischer Fehler, der gerne mal eine Access-Violation zur Folge hat. Auf jeden Fall ist es verwirrend und mißbräuchlich, den Wert einer Integer-Variablen auf einmal als Speicheradresse zu interpretieren. Auch hier: Derart unkonventioneller Code muß, wenn er beabsichtigt ist, unbedingt kommentiert werden.

4. Das Print-Makro. %x ist nicht das Formatkennzeichen für die Ausgabe von Zeigervariablen. Das Verhalten von printf ist undefiniert; der ausgegebene Wert kann falsch sein. %p wäre richtig.

5. Das Statement P( zlv = (long (*) [LEN]) sv); Im Prinzip dasgleiche wie Punkt 3. Aus dem short-Array wird ein Zeiger-Array; die dort im Speicher stehenden Zahlen werden auf einmal komplett uminterpretiert und wie Zeiger behandelt. Es fehlt bloß noch, daß sie dereferenziert werden.

6. Statement P(sv[i]=i), aber auch etliche andere Stellen: Zuweisung (-> Ausdruck mit Seiteneffekten) im Argument eines Funktionsmakros! Großes Pfui! Jeder kennt das Beispiel #define max(a,b) a>b?a:b. Frage: Wie oft wird i inkrementiert, wenn max (i++, 10) aufgerufen wird, einmal oder zweimal? Antwort: Es kommt auf den Wert von i an. Nach solchen Fehlern kann man tagelang suchen, und hinterher könnte man den, der das programmiert hat, in Streifen schneiden.


Ob man das alles dem Lehrer vor die Nase halten sollte, weiß ich nicht. In einem günstigen Moment und sachlich vorgetragen kann es hilfreich sein. Auf keinen Fall sollte es wie eine Retourkutsche für eine vergeigte Prüfung aussehen.

Was ist das eigentlich für eine Prüfung? Berufsausbildung? Allgemeinbildende Schule?

ao

Dieser Post wurde am 27.06.2003 um 00:14 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
27.06.2003, 00:15 Uhr
~StefanD
Gast


Mich ärgert es eigentlich nur, daß manche Lehrer zu glauben scheinen, sie müßten mit ihren Aufgaben ihre Schüler verarschen. Nichts anders ist diese Code doch! Wenn ich mir vorstelle, anhand solcher "leuchtender Beispiele" Programmieren zu lernen! Würde mich nicht wundern, wenn jede Menge Schüler danach nie wieder was mit "Informatik" zu tun haben wollen. Bloß ist das eben gar keine Informatik, nicht einmal Programmierung. Bloß ein Lehrer, der seine Schüler verarscht. Oder einer, der es vielleicht nicht besser kann?!!!


Stefan (*grrrrr*).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: