Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!cs.utexas.edu!uunet!viusys!uxui!unislc!ttobler From: ttobler@unislc.uucp (Trent Tobler) Newsgroups: comp.lang.c Subject: Re: Explanation, someone?? Message-ID: <1991Jun21.214346.19629@unislc.uucp> Date: 21 Jun 91 21:43:46 GMT References: <33641@usc.edu> Organization: unisys Lines: 124 From article <33641@usc.edu>, by burzin@skat.usc.edu (Burzin N. Engineer): > Hi, > I just gave an interview which had a C quiz and there was this program > that really confused me. I have compiled the program and can still not figure > out what is going on. Any reference or help will be appreciated. > --- > char *c[] = { > "ENTER", > "NEW", > "POINT", > "FIRST" > }; > char **cp[] = { c+3, c+2, c+1, c}; translation to something humans can grasp (not really valid C code): cp[] = { &"FIRST", &"POINT", &"NEW", &"ENTER" }; > char ***cpp = cp; > main() > { > printf("%s", *++cpp); This statement may cause problems, because *++cpp is not a (char *), it is a (char **), so whatever the address of "POINT" is gets interpreted as a array of characters. Depends on the compiler/machine what happens. Anyway, if the machine doesn't trap it, it does have the effect of setting cpp to &cp[1]. > printf("%s", *--*++cpp+3); cpp now points to &cp[2]. cp[2] gets decremented (set to c+0, or &"ENTER"), which we dereference to "ENTER", and then add 3 to get "ER", which is printed. > printf("%s", *cpp[-2]+3); cpp[-2] is cp[0], equal to &"FIRST", which is dereferenced to give "FIRST", we add 3 and get "ST", which is printed. > printf("%s\n", cpp[-1][-1]+1 ); cpp[-1] is cp[1], equal to c + 2 (&"POINT"), which we dereference after subtracting one giveing c[1], or "NEW". Add one to get "EW", and print it, followed by a line-feed. > } > > When run it produces: > ERSTEW Yes, that is the result, if we ignore what happens in the first printf statement. > ========================================= > Another one is : > char input[] = "SSSWILTECH1\1\11W\1WALLMP1"; > main() > { > int i, c ; > > for (i=2; (c=input[i]) != '\0'; i++){ > switch(c) { > case 'a': putchar('i'); continue; > case '1': break; > case 1: while((c = input[++i]) != '\1' && c!='0' ); > case 9: putchar('S'); > case 'E': > case 'L': continue; > default: putchar(c); > continue; > } > putchar(' '); > } > putchar('\n'); > } Because this has a loop, I will roll it out, and show only the important parts: __i__ __c__ __switch_action__ 2 'S' prints an 'S', restarts loop 3 'W' prints a 'W', restarts loop 4 'I' prints an 'I', restarts loop 5 'L' restarts loop 6 'T' prints a 'T', restarts loop 7 'E' restarts loop 8 'C' prints a 'C', restarts loop 9 'H' prints an 'H', restarts loop 10 '1' breaks out of case, and prints a ' '. 11 1 begin a while loop 9 i gets incremented; test succeeds. 'W' i gets incremented; test succeeds 1 i gets incremented; test fails prints an 'S'. restarts loop. 15 'W' prints a 'W', restarts loop. 16 'A' print an 'A', restart loop. 17 'L' restart loop 18 'L' restart loop 19 'M' prints an 'M', restarts loop. 20 'P' prints a 'P', restarts loop. 21 '1' breaks out of case, and prints a ' '. 22 0 at this point, the for loop test fails, and we drop out of the loop, print a line feed, and exit. > > which produces: > SWITCH SWAMP Yep, that's what I got too. > > ...and to think I thought I knew C. > I would sincerely appreciate some explanation. Thank You. Yes, these are quite obscure. I would wonder why they gave such a test. Even very experience programmers could get caught up in the complexity and flounder around. Also, were you told that the first one will print what it did, because it is very dependant on the compiler and machine, and could very possibly cause an illegal reference. -- Trent Tobler - ttobler@csulx.weber.edu