The difference between statements and expressions is very important, but it is considered trivial and therefor never explained in class. As with most of these 'trivial' concepts, I found this too important and too beautiful to be left unexplained.
Statements and expressions are both strings of characters, but they have an entirely different meaning. This post is dedicated to the semantics of these kinds of strings and the beauty that you can find in this knowledge as a programmer.
Expressions and Mathematics
Expressions are a way of talking about a value. They represent a value, or, in other words: Expressions are something. They don't, inherently, do anything.
In mathematics, there only exist expressions. Some computation might be required to determine the value, but the expression represents the value rather than the computation. Examples of expressions are the Boolean values: True and False, numbers: $5$, $\pi$, collections: $\{$'A', 'x', 'f'$\}$, functions, etc ...
Statements and Programming
Statements are a way of saying what to do, or, in other words: Statements do something._ Statements don't, inherently, have a value. They might, however, provide a value through computation.
Examples of statements are: the increment statement ...
i++ # Java inc <register> # Assembler
or a more complex statement that you've defined yourself:
robot.shoot()
As programming is a way of telling your computer what to do, at the lowest level in programming, only statements exist. It's true that, in higher programming languages, expressions do certainly exist, but at the machine level they don't. One might argue that the operand to an assembler statement can be seen as an expression, but that too is just a way of telling the computer which bits to set.
The bridge
As a programmer, you might try to implement a highly abstract idea like an application to connect with people, or a program to solve some complicated puzzle. The idea is often so abstract that it can only be described in some branch of mathematics, or a natural language. What you're describing it the abstract value that this program would have to you, in expressions.
Now, as there are only statements in programming, your program will have to produce that value through the use of statements. Of course, few people still only code with statements in assembly. Higher languages have been developed that allow you to talk about expressions (to the computer) in a less minimal manner. Compilers have been written so that a programmer may tell the computer what to do at a higher level. Sometimes, these tools become so immensely complex, that the programmer can just tell the computer what he wants it to do without also telling it how to do it.
As you can see, the difference between an abstract idea and a concrete implementation couldn't be greater. Two arrows are drawn. The topmost arrow is an illustration of the inherent difficulty of implementing an abstract concept. The more abstract (higher), an idea is, the more difficult it is to implement it. The bottom arrow represent the efforts that programmers make to make a developer's life easier. Programmers have tried to make it as easy as possible to talk about ideas with computers.
As a programmer, your work forms the bridge between some value that you want to obtain and the implementation that's going to get you there. You form the bridge between expressions in mathematics and natural language, and the statements in the machine you control. Realising this, I found a new powerful, beauty in programming and new courage in the late hours when I'm trying to fix that last annoying bug.