Ein C-Puzzler   Julian Fietkau    am 2. Dezember 2010  im KunterBuntenSeminar
§                           ¤1   #include <stdio.h>23   void main(void)4   {5      double value = 10.0;6      printf("%g",...
#define MACRO(x,y,z) 2*(x+y*z)Funktionsartige Makros:Können im Quelltext ähnlich wie Funktionen verwendet werdenund bekomm...
§                                  ¤1   #include <stdio.h>23   #define INVERSE(x) 1/x45   void main(void)6   {7      doubl...
Referenzierungs-Operator:&   Liefert einen Zeiger auf eine Variable.    Dereferenzierungs-Operator:*   Liefert den Inhalt ...
§                               ¤1   #include <stdio.h>23   void main(void)4   {5      double value = 10.0;6      double* ...
§                                             ¤ 1   #include <stdio.h> 2 3   #define INVERSE(x) 1/x 4 5   void main(void) ...
§                                             ¤ 1   #include <stdio.h> 2 3   #define INVERSE(x) 1/x 4 5   void main(void) ...
§                                             ¤ 1   #include <stdio.h> 2 3 4 5   void main(void) 6   { 7      double value...
§                                             ¤ 1   #include <stdio.h> 2 3 4 5   void main(void) 6   { 7      double value...
§                                             ¤ 1   #include <stdio.h> 2 3   #define INVERSE(x) 1/x 4 5   void main(void) ...
gcc -std=c99 -E macro.c      §                              ¤687   (...)688689   void main(void)690   {691      double val...
§                                ¤1    #define PREPEND_ASTERISK(x) *x2    #define PREPEND_SLASH(x) /x34    PREPEND_ASTERIS...
ISO/IEC 9899:TC3 (C99-Standard)5.1.1.2 Translation phases:  3. The source file is decomposed into preprocessing     tokens6...
§                                                     ¤  printf("%g", INVERSE(*pValue)); ¦                                ...
§                                               ¤  printf("%g", INVERSE(*pValue)); ¦                                      ...
printf   → ( → "%g" → , →     → 1 → / → * →               pValue   → ) → ;                    gcc -E §                    ...
printf   → ( → "%g" → , →     → 1 → / → * →               pValue   → ) → ;                    gcc -E §                    ...
Danke für die Aufmerksamkeit! http://www.julian-fietkau.de/c_puzzler
Nächste SlideShare
Wird geladen in …5
×

Ein C-Puzzler

408 Aufrufe

Veröffentlicht am

Bei diesem Vortrag handelte es sich um einen Lightning Talk im KunterBuntenSeminar der Fachschaft Informatik.

In ganz knapp über fünf Minuten habe ich etwas C-Code erklärt, Makros und Zeigervariablen in C gezeigt und darauf aufbauend dann eine kleine Quizfrage gestellt. Die für die Teilnehmer überraschende Lösung habe ich dann anhand des Compilerverhaltens von GCC und dem ISO-Standard zu C99 erklärt.

Veröffentlicht in: Technologie
0 Kommentare
1 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
408
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
2
Aktionen
Geteilt
0
Downloads
0
Kommentare
0
Gefällt mir
1
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Ein C-Puzzler

  1. 1. Ein C-Puzzler Julian Fietkau am 2. Dezember 2010 im KunterBuntenSeminar
  2. 2. § ¤1 #include <stdio.h>23 void main(void)4 {5 double value = 10.0;6 printf("%g", 1/value);7 } ¦ ¥→ 0.1
  3. 3. #define MACRO(x,y,z) 2*(x+y*z)Funktionsartige Makros:Können im Quelltext ähnlich wie Funktionen verwendet werdenund bekommen Argumente übergeben. Achtung: Makros werden bereits zur Übersetzungszeit ausgewertet. Der Code des Makros wird an allen Stellen, an denen das Makro verwendet wird, vor dem eigentlichen Kompilieren einfach ein- gesetzt.
  4. 4. § ¤1 #include <stdio.h>23 #define INVERSE(x) 1/x45 void main(void)6 {7 double value = 10.0;8 printf("%g", INVERSE(value));9 } ¦ ¥→ 0.1
  5. 5. Referenzierungs-Operator:& Liefert einen Zeiger auf eine Variable. Dereferenzierungs-Operator:* Liefert den Inhalt der angegebenen Adresse.
  6. 6. § ¤1 #include <stdio.h>23 void main(void)4 {5 double value = 10.0;6 double* pValue = &value;7 printf("%g", 1 / *pValue);8 } ¦ ¥→ 0.1
  7. 7. § ¤ 1 #include <stdio.h> 2 3 #define INVERSE(x) 1/x 4 5 void main(void) 6 { 7 double value = 10.0; 8 double* pValue = &value; 9 printf("%g", INVERSE(*pValue));10 } ¦ ¥ A 0.1 B Übersetzungsfehler C Laufzeitfehler D noch etwas Anderes
  8. 8. § ¤ 1 #include <stdio.h> 2 3 #define INVERSE(x) 1/x 4 5 void main(void) 6 { 7 double value = 10.0; 8 double* pValue = &value; 9 printf("%g", INVERSE(*pValue));10 } ¦ ¥ A 0.1 B Übersetzungsfehler C Laufzeitfehler D noch etwas Anderes
  9. 9. § ¤ 1 #include <stdio.h> 2 3 4 5 void main(void) 6 { 7 double value = 10.0; 8 double* pValue = &value; 9 printf("%g", 1/*pValue);10 } ¦ ¥ A 0.1 B Übersetzungsfehler C Laufzeitfehler D noch etwas Anderes
  10. 10. § ¤ 1 #include <stdio.h> 2 3 4 5 void main(void) 6 { 7 double value = 10.0; 8 double* pValue = &value; 9 printf("%g", 1/*pValue);10 } ¦ ¥ A 0.1 B Übersetzungsfehler C Laufzeitfehler D noch etwas Anderes
  11. 11. § ¤ 1 #include <stdio.h> 2 3 #define INVERSE(x) 1/x 4 5 void main(void) 6 { 7 double value = 10.0; 8 double* pValue = &value; 9 printf("%g", INVERSE(*pValue));10 } ¦ ¥ A 0.1 B Übersetzungsfehler C Laufzeitfehler D noch etwas Anderes
  12. 12. gcc -std=c99 -E macro.c § ¤687 (...)688689 void main(void)690 {691 double value = 10.0;692 double* pValue = &value;693 printf("%g", 1/_*pValue);694 } ¦ ¥
  13. 13. § ¤1 #define PREPEND_ASTERISK(x) *x2 #define PREPEND_SLASH(x) /x34 PREPEND_ASTERISK(literal)5 PREPEND_SLASH(literal)6 PREPEND_ASTERISK(*pointer)7 PREPEND_SLASH(*pointer) ¦ ¥ gcc -std=c99 -E test.c § ¤ 7 (...) 8 9 *literal10 /literal11 **pointer12 / *pointer ¦ ¥
  14. 14. ISO/IEC 9899:TC3 (C99-Standard)5.1.1.2 Translation phases: 3. The source file is decomposed into preprocessing tokens6) and sequences of white-space characters (including comments). (. . . ) Each comment is replaced by one space character. (. . . ) 4. Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. (. . . ) (Hervorhebungen von mir.)
  15. 15. § ¤ printf("%g", INVERSE(*pValue)); ¦ ¥ 1 2 3printf → ( → "%g" → , → → INVERSE → ( → * → pValue → ) → ) → ; 4printf → ( → "%g" → , → → 1 → / → * → pValue → ) → ; 5 6 7 8
  16. 16. § ¤ printf("%g", INVERSE(*pValue)); ¦ ¥ 1 2 3printf → ( → "%g" → , → → INVERSE → ( → * → pValue → ) → ) → ; 4printf → ( → "%g" → , → → 1 → / → * → pValue → ) → ; gcc -E
  17. 17. printf → ( → "%g" → , → → 1 → / → * → pValue → ) → ; gcc -E § ¤ printf("%g", 1/*pValue); ¦ ¥
  18. 18. printf → ( → "%g" → , → → 1 → / → * → pValue → ) → ; gcc -E § ¤ printf("%g", 1/ *pValue); ¦ ¥
  19. 19. Danke für die Aufmerksamkeit! http://www.julian-fietkau.de/c_puzzler

×