Puzzle Structure
Learn about how the different parts of puzzles are organized.
We'll cover the following
There are 25 programming puzzles, some perform specific tasks, while others may attempt to do something that doesn’t quite work. All of the code is written in C. No additional files or libraries are required. The programs run in the text mode environment, specifically, under Linux in a terminal window.
For each puzzle, your job is to guess what happens. You can predict the output, guess what the program is trying to accomplish, or identify a potential problem. The code is discussed in the next lesson that follows each puzzle, including an insight into understanding the code, what it does, and how or why it fails to do what you might think it does. The point is to learn more about C programming, witness a few tricks, and put your new knowledge to work in your own programs.
Here’s a sample puzzle.
Puzzle code
Read carefully the code given below:
int puts(const char *s);#define lineout(a) puts(a)#define end return(0)int main(){lineout("Hello there!");end;}
Your task(s)
Can you guess the output from this code?
It’s C source code, though we’ve taken some liberties with the way things are expressed. If you can guess the output, can you identify the liberties we’ve taken in the source code?
Try to complete the tasks on your own before you turn to the next lesson to see our explanation and further exploration of the puzzle.
Answers with explanation
Here are the answers:
The output is the string "Hello there!" followed by a newline. This is the output generated by the
puts()
function, normally declared within thestdio.h
header—but this header is missing in the source code!Instead of including the entire
stdio.h
header, we write theputs()
function prototype. This is a legal move, as you can prototype any function you’ve created. But, here we just looked up the main definition forputs()
and copied it into our source code. Properly prototyped, the function works just fine. (Remember that the function’s mechanics are stored in the library, not in the header file.)Here, the two
#defines
create the unusual statements found in themain()
function. The first defines a functionlineout()
equivalent to theputs()
function. Thea
in both represents the function’s argument. Solineout()
replacesputs()
in themain()
function, carrying out the same task.The second
#define
assigns thereturn(0)
statement to the wordend
. The result is themain()
function’s statements appear alien—very non-C-like. Still, the preprocessor replaces bothlineout()
andend
with the proper C statements.
Your goal
This unusual construction is one of the things we adore about the C language. While as a programmer your goal should be to write easily readable text, you can add your own quirks to the language just to keep things interesting. But on a grander scale, you can use these tricks to help simplify some complex operations. So, while there was an attempt to obfuscate the code, you can use the same tools to make a program more readable. And hopefully, you’ll have fun while doing so.
Further reading
For more detailed explanations and further reading on the concepts used in the puzzles, please refer to the Appendix section.