Warning: Declaration of action_plugin_subjectindex_indexer::register(&$controller) should be compatible with DokuWiki_Action_Plugin::register(Doku_Event_Handler $controller) in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/subjectindex/action/indexer.php on line 15

Warning: Declaration of action_plugin_mathjax_enable::register(Doku_Event_Handler &$controller) should be compatible with DokuWiki_Action_Plugin::register(Doku_Event_Handler $controller) in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/mathjax/action/enable.php on line 62

Warning: Declaration of action_plugin_googleanalytics::register(&$controller) should be compatible with DokuWiki_Action_Plugin::register(Doku_Event_Handler $controller) in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/googleanalytics/action.php on line 40

Warning: Declaration of action_plugin_folded::register(&$controller) should be compatible with DokuWiki_Action_Plugin::register(Doku_Event_Handler $controller) in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/folded/action.php on line 40

Warning: Declaration of action_plugin_hidden::register(&$controller) should be compatible with DokuWiki_Action_Plugin::register(Doku_Event_Handler $controller) in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/hidden/action.php on line 28

Warning: Declaration of action_plugin_include::register(&$controller) should be compatible with DokuWiki_Action_Plugin::register(Doku_Event_Handler $controller) in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/include/action.php on line 354

Warning: Declaration of action_plugin_tag::register(&$contr) should be compatible with DokuWiki_Action_Plugin::register(Doku_Event_Handler $controller) in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/tag/action.php on line 175

Warning: Cannot modify header information - headers already sent by (output started at /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/subjectindex/action/indexer.php:15) in /data/web/virtuals/28604/virtual/www/subdom/bo/inc/auth.php on line 532

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/web/virtuals/28604/virtual/www/subdom/bo/inc/auth.php on line 818

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /data/web/virtuals/28604/virtual/www/subdom/bo/inc/parser/handler.php on line 1376

Warning: Declaration of SI_EntryDefault::match($text) should be compatible with SI_Entry::match() in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/subjectindex/plugins/EntryDefault.php on line 68

Warning: Declaration of SI_EntryTag::match($text) should be compatible with SI_Entry::match() in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/subjectindex/plugins/EntryTag.php on line 42

Warning: Declaration of SI_EntryVerse::match($text) should be compatible with SI_Entry::match() in /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/subjectindex/plugins/EntryVerse.php on line 1280

Warning: preg_match(): Compilation failed: invalid range in character class at offset 4360 in /data/web/virtuals/28604/virtual/www/subdom/bo/inc/parser/lexer.php on line 118
A PCRE internal error occured. This might be caused by a faulty plugin

Warning: Cannot modify header information - headers already sent by (output started at /data/web/virtuals/28604/virtual/www/subdom/bo/lib/plugins/subjectindex/action/indexer.php:15) in /data/web/virtuals/28604/virtual/www/subdom/bo/inc/actions.php on line 215
lcthw:ex13 [Bo.bule]

======Exercise 13: Switch Statement====== In other languages like Ruby you have a switch-statement that can take any expression. Some languages like Python just don't have a switch-statement since an if-statement with boolean expressions is about the same thing. For these languages, switch-statements are more alternatives to if-statements and work the same internally. The switch-statement is actually entirely different and is really a "jump table". Instead of random boolean expressions, you can only put expressions that result in integers, and these integers are used to calculate jumps from the top of the switch to the part that matches that value. Here's some code that we'll break down to understand this concept of "jump tables": #include <stdio.h> int main(int argc, char *argv[]) { if(argc != 2) { printf("ERROR: You need one argument.\n"); // this is how you abort a program return 1; } int i = 0; for(i = 0; argv[1][i] != '\0'; i++) { char letter = argv[1][i]; switch(letter) { case 'a': case 'A': printf("%d: 'A'\n", i); break; case 'e': case 'E': printf("%d: 'E'\n", i); break; case 'i': case 'I': printf("%d: 'I'\n", i); break; case 'o': case 'O': printf("%d: 'O'\n", i); break; case 'u': case 'U': printf("%d: 'U'\n", i); break; case 'y': case 'Y': if(i > 2) { // it's only sometimes Y printf("%d: 'Y'\n", i); } break; default: printf("%d: %c is not a vowel\n", i, letter); } } return 0; } In this program we take a single command line argument and print out all of the vowels in an incredibly tedious way to demonstrate a switch-statement. Here's how the switch-statement works: * The compiler marks the place in the program where the switch-statement starts, let's call this location Y. * It then evaluates the expression in switch(letter) to come up with a number. In this case the number will be the raw ASCII code of the letter in argv[1]. * The compiler has also translated each of the case blocks like case 'A': into a location in the program that is that far away. So the code under case 'A' is at Y+'A' in the program. * It then does the math to figure out where Y+letter is located in the switch-statement, and if it's too far then it adjusts it to Y+default. * Once it knows the location, the program "jumps" to that spot in the code, and then continues running. This is why you have break on some of the case blocks, but not others. * If 'a' is entered, then it jumps to case 'a', there's no break so it "falls through" to the one right under it case 'A' which has code and a break. * Finally it runs this code, hits the break then exits out of the switch-statement entirely. This is a deep dive into how the switch-statement works, but in practice you just have to remember a few simple rules: * Always include a default: branch so that you catch any missing inputs. * Don't allow "fall through" unless you really want it, and it's a good idea to add a comment //fallthrough so people know it's on purpose. * Always write the case and the break before you write the code that goes in it. * Try to just use if-statements instead if you can. ======What You Should See====== Here's an example of me playing with this, and also demonstrating various ways to pass the argument in: $ make ex13 cc -Wall -g ex13.c -o ex13 $ ./ex13 ======ERROR: You need one argument.====== $ $ ./ex13 Zed 0: Z is not a vowel 1: 'E' 2: d is not a vowel $ $ ./ex13 Zed Shaw ======ERROR: You need one argument.====== $ $ ./ex13 "Zed Shaw" 0: Z is not a vowel 1: 'E' 2: d is not a vowel 3: is not a vowel 4: S is not a vowel 5: h is not a vowel 6: 'A' 7: w is not a vowel $ Remember that there's that if-statement at the top that exits with a return 1; when you don't give enough arguments. Doing a return that's not 0 is how you indicate to the OS that the program had an error. Any value that's greater than 0 can be tested for in scripts and other programs to figure out what happened. ======How To Break It====== It is incredibly easy to break a switch-statement. Here's just a few of the ways you can mess one of these up: * Forget a break and it'll run two or more blocks of code you don't want it to run. * Forget a default and have it silently ignore values you forgot. * Accidentally put in variable into the switch that evaluates to something unexpected, like an int that becomes weird values. * Use uninitialized values in the switch. You can also break this program in a few other ways. See if you can bust it yourself. ======Extra Credit====== * Write another program that uses math on the letter to convert it to lowercase, and then remove all the extraneous uppercase letters in the switch. * Use the ',' (comma) to initialize letter in the for-loop. * Make it handle all of the arguments you pass it with yet another for-loop. * Convert this switch-statement to an if-statement. Which do you like better? * In the case for 'Y' I have the break outside the if-statement. What's the impact of this and what happens if you move it inside the if-statement. Prove to yourself that you're right. Copyright (C) 2010 Zed. A. Shaw Credits


Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /data/web/virtuals/28604/virtual/www/subdom/bo/inc/auth.php on line 818
lcthw/ex13.txt · Last modified: 2013/03/10 01:00 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0