Anfänger und Listen

Schnelle objektorientierte, kompilierende Programmiersprache.
Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Anfänger und Listen

Beitrag von cloidnerux » Mo Feb 17, 2014 8:14 pm

Klar. Aber warum ist da offensichtlich ein Unterschied zwischen "((int) *p)" und "(int) *p"? Zwischen "(3 * 2)" und "3 * 2" ist doch auch keiner ;)
Weil der Compiler den Nutzer vor sich selber schützt.
Es ist nämlich nicht (int) *p, sondern

Code: Alles auswählen

sizeof(int) * p
gegenüber

Code: Alles auswählen

sizeof((int)*p))
Also multiplizierst du eine Zahl mit einem Zeiger. Das ist so erstmal nicht zulässig.

Hinzu kommt Operatorpriorität http://www.proggen.org/doku.php?id=c:expr:opprio
Der Compiler wertet von links nach rechts aus, er findet sizeof, führt das aus und das Ergebnis ist ein int.
Wenn int links von etwas steht, dürfen nur noch bestimmte Operatoren folgen, die Dereferenzierung gehört nicht dazu. Also muss das * eine Multiplikation sein, aber Pointer als rvalue ist nicht zulässig.
Mit den Klammern drum herum, ist das was anderes. Die Klammern haben eine höhere Priorität, der Ausdruck wird also im Gesamten ausgewertet.
Redundanz macht wiederholen unnötig.
quod erat expectandum

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Anfänger und Listen

Beitrag von mfro » Mo Feb 17, 2014 8:38 pm

cloidnerux hat geschrieben:Also multiplizierst du eine Zahl mit einem Zeiger. Das ist so erstmal nicht zulässig.
Gut, Zeiger multiplizieren ist wirklich nicht die feine Art. Aber addieren und zu int casten darf man sie doch, oder?

Code: Alles auswählen

void whatsthis(void)
{
      char p;
    
      int a = sizeof (int) p + p;
      int b = sizeof((int) p + p);
    
    
      printf("a =  %d, b = %d\n", a, b);
}
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Anfänger und Listen

Beitrag von cloidnerux » Mo Feb 17, 2014 8:56 pm

Gut, Zeiger multiplizieren ist wirklich nicht die feine Art. Aber addieren und zu int casten darf man sie doch, oder?
Ja. Das Problem ist das von dir gewählte Beispiel.

Code: Alles auswählen

int a;
int *p = &a;
int c = (int)p;
printf("%d", a+c);
p = (int*)10000;
Du kannst einen Pointer zu int casten, du kannst einen int zu einem Pointer casten. Ein Pointer ist auch nur ein verkappter int.
Was nicht geht ist direkt Multiplizieren, denn das führt zu Problemen, wenn du mal die Dereferenzierung vergisst:

Code: Alles auswählen

int a = *p * 10; //richtig
a = p * 10; //falsch
Deswegen meckert der Compiler.
Du kannst Addieren:

Code: Alles auswählen

int *p = &a + 4;
Und bitte beachten, sizeof wird zur Compilierzeit ausgewertet, nicht zur Laufzeit.
Redundanz macht wiederholen unnötig.
quod erat expectandum

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Anfänger und Listen

Beitrag von mfro » Mo Feb 17, 2014 9:04 pm

cloidnerux hat geschrieben:
Gut, Zeiger multiplizieren ist wirklich nicht die feine Art. Aber addieren und zu int casten darf man sie doch, oder?
Ja. Das Problem ist das von dir gewählte Beispiel.
Du meinst Pointer addieren und zu int casten ist grundsätzlich zulässig, nur nicht in meinem Beispiel? ;)
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Anfänger und Listen

Beitrag von cloidnerux » Mo Feb 17, 2014 9:09 pm

Du meinst Pointer addieren und zu int casten ist grundsätzlich zulässig, nur nicht in meinem Beispiel? ;)
Dein Beispiel versucht nicht einen Pointer zu int zu casten.
Du Multiplizierst einfach nur ein int mit einem Pointer und das ist nicht zulässig.
Redundanz macht wiederholen unnötig.
quod erat expectandum

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Anfänger und Listen

Beitrag von mfro » Mo Feb 17, 2014 9:11 pm

cloidnerux hat geschrieben:
Du meinst Pointer addieren und zu int casten ist grundsätzlich zulässig, nur nicht in meinem Beispiel? ;)
Dein Beispiel versucht nicht einen Pointer zu int zu casten.
Du Multiplizierst einfach nur ein int mit einem Pointer und das ist nicht zulässig.
Im letzten Beispiel addiere ich. Geht trotzdem nicht ;)
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Anfänger und Listen

Beitrag von nufan » Mo Feb 17, 2014 9:19 pm

mfro hat geschrieben:sizeof(*first) ist tatsächlich nicht wirklich falsch, aber _sehr_ mißverständlich.

[...]

sizeof(struct struktur) ist in jedem Fall besser, weil weniger kryptisch.
Prinzipiell gebe ich dir recht, aber es sei auch noch ein Vorteil dieser Schreibweise angemerkt: Ändert sich der Typ von first auf einen kleineren ist der Fehler relativ schwer zu finden. Aber wie gesagt gebe ich dir recht und ich bevorzuge auch den Typ anzugeben. Eine IDE kann entsprechende Fehler über automatisches Refactoring auch abfangen.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Anfänger und Listen

Beitrag von mfro » Mo Feb 17, 2014 10:16 pm

cloidnerux hat geschrieben: Ja. Das Problem ist das von dir gewählte Beispiel.
Falls Du's noch nicht bemerkt hast, das ist ein kleines Rätselchen. Und

Code: Alles auswählen

 int a = sizeof (int) p + p;
funktioniert aus demselben Grund nicht, warum das:

Code: Alles auswählen

 int c = a+++++b;
oder das

Code: Alles auswählen

 int verhältnis = *p_a/*p_b;
auch nicht funktioniert ;) .
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Anfänger und Listen

Beitrag von cloidnerux » Mo Feb 17, 2014 10:59 pm

Falls Du's noch nicht bemerkt hast, das ist ein kleines Rätselchen.
Hab ich tatsächlich nicht :D
Aber für mehr spaß und Erheiterung:
http://stackoverflow.com/questions/9494 ... d-behavior
http://stackoverflow.com/questions/3676 ... uld-know-a
Redundanz macht wiederholen unnötig.
quod erat expectandum

ufor
Beiträge: 11
Registriert: Mo Jan 06, 2014 5:36 pm

Re: Anfänger und Listen

Beitrag von ufor » Mo Feb 17, 2014 11:44 pm

Hallo zusammen

Danke für die ausführlichen Antowrten fürs erste habe ich eine Vorstellung wie das Programm funktioniert.
Ich bin auch dankbar für die Erklärungen, aber bei eurem "Rätsel" bin ich dann doch ausgestiegen.
Nur noch eine kleine Frage:

Code: Alles auswählen

while (hilfszeiger -> next != NULL)
           {
            hilfszeiger = hilfszeiger -> next;
           }
Mit dieser Schleife zeigt doch hifszeiger solange auf next bis next NULL ist. Meine Frage wie weiß das Programm, dass es auf den nächsten Zeiger next "springen" soll. Normalerweise gibt es doch eine Variabel die bei jedem Durchlauf erhöht wird. Diese fehlt hir. Ober habe ich da doch noch erwas nicht ganz verstanden.

Antworten