An expression_statement consists of an expression (expr) followed by a semi-colon:
expr ;
Where expr can be one of the following:
( expr )
expr + expr
expr - expr
expr * expr
expr / expr
expr % expr
'-' expr
expr '&' expr
expr == expr
expr eq expr
expr != expr
: expr <> expr
expr > expr
expr < expr
expr <= expr
expr >= expr
expr '?' expr ':' expr
expr streq expr
expr strneq expr
expr || expr
expr or expr
expr && expr
expr and expr
! expr
not expr
This is a recursive definition so might require some thinking about, but it accurately describes the syntax of all possible combinations of expressions and defines a ‘tree’ structure where the ‘leaves’ of the trees are all rvalues.
An rvalue is a ‘right hand value’ i.e. something that can appear on the right hand side of an equals sign such as a number, a string, a variable name, a pointer to a variable etc. By comparison an lvalue is something that can appear on the left hand side of an equals sign and does not include all things that are rvalues. For example, a variable name is both an rvalue and a lvalue since it can appear on either side of an equals sign:
a=b;
b=1;
etc
But it doesn’t make sense to have a string or a number on the left hand side of an equal sign:
// Makes no sense!
"abc"=a;
5=c;
The full list of valid rvalues is as follows:
<number>
<string>
indentifier
indentifier [ expr ]
-- indentifier
++ indentifier
indentifier --
indentifier ++
& indentifier
* indentifier
Where <number> is any signed integer (E.g 10, -115, 121111111) or a hexadecimal value preceded by 0x (e.g. 0xff).
<string> is any string of characters surrounded by double quotes (E.g. “This is a string”, “100” etc)
identifier is the name of a variable and identifier [ expr ] is the name of an array and the index into the array (E.g. myarray[12], myarray[6*2]).
-- and ++ are decrement and increment operators (see arithmetic expressions) and & and * are the indirection operators (& - obtain pointer to a variable, * - get the contents of the pointer to a variable).