Alexios' Home Page

C Programming on the Oric, Part 2 of 8 

HomeWritten ramblings ► C Programming on the Oric, 2/8 ►

4 Express Yourself

The focus of this month's C tutorial will be on expressions: a very important concept in the language. This is rather natural, since C handles almost everything as expressions (borrowing a little of that Lisp functionality). Let's start with a very simple program:

#include "stdlib.h"

void main()
{
	int result;
	result=10*3+100/2;
	printf("result: %d\n",result);
}

There are two new things here. One is the way we print numbers using printf(). The function interprets a set of format specifiers, all of which start with a percent sign (%). The specifier is replaced by the value of a variable, passed to printf() as an additional parameter. You can have any number of specifiers and any number of additional parameters, as long as their numbers are equal: weird things will happen if you have more specifiers than parameters! You can print other things except numbers, too (footnote: In larger compilers, format specifiers are a lot more complicated. For example, you can specify padding, number formats, etc. The Oric libraries are small, however, and do not implement a complete version of printf() yet). Here's a short table:

Specifier Description
%d Print an int
%x Likewise, but in hex
%f Print a float
%s Print a string
%c Print a single character

C, as usual, doesn't care what parameter you pass. It will try to print a string as an int (and fail completely), so be careful in matching specifiers and parameters!

The second and most important element of our program is an expression: we assign the result of a calculation to a variable named result (yes, C variable names can be of any length). If you know the first thing about programming, this will be quite obvious to you. The syntax is no different than BASIC's. The interesting part is that the expression is result=10*3+100/2, and not 10*3+100/2 as the case would be in BASIC.

This happens because in C, a variable assignment (denoted by =) is an operator, and not a statement (as in BASIC). The = operator calculates the expression at its right hand side, and assigns the result to the variable at the left hand side. It then returns the value assigned. This gives C its cryptic style, because you can actually write x=(y=10). In this case, y will be assigned the value 10, and x will be assigned the value assigned to y (footnote: In fact, the parentheses are unnecessary, since assignment works from right to left, and has very low precedence).

Getting used to this fact of life (or C, rather) is fundamental. It makes most of the difference between beginners and seasoned programmers. It also accounts for most of C bugs, but that is another story. Apart from this (and some of the weird symbols used), C expressions are everyday programming language expressions.

Another point: C does not have any conditions as such: like conditions in Oric BASIC, if statements, loops, etc. evaluate an expression, and consider it true if it is non- zero. In BASIC, you could write:

a=10: IF A THEN ? "A IS NON-ZERO"
A IS NON-ZERO
Ready

Exactly the same thing goes on in C. Tests for equality and inequality are (surprise!) operators which return 1 if the test succeeds (BASIC functions return -1), and 0 if it fails.

Now, you'll probably begin to wonder: since even assignments are expressions, what happens to the result of an assignment? In (old, non-Turbo) Pascal, you can't have a result that isn't used. Well, in C you can do that. Once a semicolon (;) is met, the result of the expression is thrown away. In this sense, result=3*10+100/2 evaluates the expression, stores the outcome in the named variable, and then throws it away. Strangely enough, the same thing is done with function calls: printf() could well return some value (it doesn't, really), but we'll never know what that is, because it's discarded. Yes, you could do result=printf("blah"), but there would be no point: the function returns void (i.e. doesn't return anything), so you'd get a warning or error from the compiler.

Finally, here's another thing: until you get accustomed to C expressions and their little quirks (they have many), use plenty of parentheses. They won't make your program slower and they won't make it bigger. They will make clear to the compiler what you want evaluated first.

Here's a quick list of the types of operators:

5 C Operators

Now we'll discuss the various operators you can use in C expressions. We'll start off with the easy ones, and move on to more exotic cases.

5.1 Arithmetic Operators

(The operator tables were drawn from The Waite Group's Turbo C++ Bible by Naba Barkakati, SAMS, ISBN 0-672-22742-8)

OP Name Example Description
+ Addition x+y Add x and y.
- Subtraction x-y Subtract y from x.
* Multiplication x*y Multiply x times y.
/ Division x/y Divide x by y.
% Modulo x%y Remainder of x/y
++ Increment x++ or ++x Increase variable by 1
-- Decrement x-- or --x Decrease variable by 1
- Unary negation -x Negate the value of x

Most of these are extremely straightforward and don't even deserve discussion. A couple of them need some clarification, though.

5.1.1 Modulo or Remainder

This calculates the remainder of the division of its two parameters. Oric BASIC doesn't have it, but Pascal users will be familiar with it, as the Mod operator.

5.1.2 Increment and Decrement Operators

These two are two very useful operators. Given a variable, they increment or decrement its contents by 1. The ++ or -- operator can be put before or after a variable. It behaves differently, depending on its position. When put before a variable, it changes the variable's value before that variable is used in the expression. If put after a variable, it alters its value after the variable has been used in the expression. This sounds obscure, and requires an example (or two):

Assume we have two variables, x=10 and y=20. We calculate the expression x=x+(++y). The contents of y are incremented before the variable is used, so the result will be x=10+21, or x=31. The value of y is 21.

Now let's again assume x=10 and y=20. In calculating x=x+(y++), the contents of y are used before it gets incremented. Thus, x=10+20, or x=30. The value of y at the end of the calculation is again 21, but the result of the expression is not the same. This double syntax comes very handy when programming loops.

5.1.3 Unary Negation

This is no other than our very own - operator, as used on single operands. For example, assuming x=10, the result of -x is -10. This should be simple enough.

5.2 Conditions, Comparisons and Logic

OP Name Example Description
> Greater than x>y 1 if x>y, else 0
>= Greater/equal x>=y 1 if x>=y, else 0
< Less than x<y 1 if x<y, else 0
<= Less/equal x<=y 1 if x<=y, else 0
== Equal to x==y 1 if x = y, else 0
!= Not equal to x!=y 1 if not x==y, else 0
! Logical NOT !x 1 if x is zero, else 0
&& Logical AND x&&y 1 if both x and y non-zero, else 0
|| Logical OR x||y 1 if either x or y non-zero, else 0

As you can see, all these operations return one of two possible values: 1 to signify Boolean true, 0 for Boolean false. The same thing goes on in Oric BASIC. Although the logical and conditional operators return only 1 or 0, they consider any non-zero value as True.

5.2.1 Greater Than, Less Than, etc.

BASIC users, beware! The ‘greater than/equal to’ and ‘less than/equal to' operators have to be written exactly as shown: C won't recognise ‘=>’ as ‘greater than or equal to’.

5.2.2 Equality (==)

You should be very careful of this one. Do not confuse it with the assignment operator (=). To check two expressions for equality, only use ==. In many cases the compiler will warn you if you confuse them, but not always.

5.2.3 Inequality (!=)

No surprises here. Just remember that <> does not work in C!

5.2.4 AND (&&), OR (||)

These work just as they do in all programming languages. An important note: && and || are Boolean operators. There is another set of operators for dealing with bit values. This means, for example, that 255 && 31 will return 1 (remember, this set of operators considers all non-zero values as 1). I cannot stress it enough, but remember: careless use of these logical operators is the source of many bugs in C programs.

5.2.5 NOT (!)

This is a unary operator. Put it before an expression, and it will return 0 if the expression is non-zero, and 1 if the expression evaluates to zero. Just your ordinary Boolean NOT operator. Let me again caution you: ! will not reverse bit values! It, too, only deals with zero and non-zero values. Bit-wise negation is handled by another operator.
To be continued.