tutorials SAM Coupé

Talking C

Introduction to SAM C (a small-C variant) for SAM Coupé BASIC programmers

Originally published in Vol.9 No12 (August, 1996) edition of Format Magazine, this is a short tutorial I wrote based on SAM C, intended for people currently writing programs in BASIC -- I never actually wrote part II.

This is the first in a series of articles on SAM C, helping you to understand the language and get the most out of it. Each month I'll introduce new commands and give you programs to inspect and modify, and there will be no C jokes at all. So let's C how we get on then shall we... (ho ho).

The basics of a C program

The whole of the C language is based around functions, the most important of which is the main() function. This is called (sometimes with parameters) whenever the program starts, and contains the main part of the program, between the curly brackets following the command,.

Other functions can either be defined in the program itself, or can be loaded in through one of the library files using the #include "xxxxxxxx.x" pre-processor command. There are two types of file which can be loaded in using the #include command -- header files and c files. Header files have the extension .h and are loaded at the top of the source and "C" files have the extension .c and are loaded at the bottom. The .h usually have corresponding .c files, the only built-in exception being the stdio.h file.

There are only a few keywords -- including things like main() mentioned earlier and int, char, etc. These do not need a library file to operate.

So the basic C program would look like this:

c
#include "stdio   .h"   includes the standard C header file
#include "xxxxxxxx.h"   includes another header file

main()                  the main function called when the program is first run
{
.
.                       your program fits between the curly brackets
.
}

All lines in C must end with the standard C end of line marker, the semi-colon ;. The only exception is following a loop keyword where there is a { to signify the start of the loop or another keyword followed by a semi-colon to signify a single-line loop. Because of this flexibility you can spread one line over many lines of source, or put many lines of source on one line.

Variables in C

Unlike in BASIC, in C you have to declare each individual variable before it can be assigned a value. To do this you use the commands int and char, e.g. int a; sets up a variable a for use.

In SAM C you must always set up the variables at the start of the function.

What's the difference between int and char? An INTeger can hold a number between -32768 and +32768 and CHARacter can hold a number between -128 and +127. Here, another command comes in: unsigned. This allows you to disable negative numbers and by doing so double their positive range, i.e. unsigned int a; sets up a variable called a which can hold a number between 0 and 65535.

Variable Type Size (bytes) min max
int 2 -32768 +32767
char 1 -128 +127
unsigned int 2 0 +65535
unsighed char 1 0 +255

As in BASIC you can set up dimensional arrays to hold groups of numbers, e.g.

int a [10][2]; would set up an array of 20 numbers (10*2) each with a range of -32768 to +32767. You can build arrays of char's and this is how you store strings - a char can only hold one single letter (a character) by itself.

The first part of an array is section 0, so to store the very first position in an array k[10][10]; in variable x you would use x=k[0][0];.

char a[100]; would set up a string array 100 characters long, which can be altered using commands in the string .c library.

Letters are held by the ASCII code (0-255) explaining by the max range of an unsigned char is 0-255.

It is possible to convert between the different types of variable, but if you convert from an int of a value over to 255 to a char (max value 255) the higher byte of the int will be lost, leaving you with a number which is probably of no use. Phew!

In C there are various ways to alter the value in a variable:

C Notation C shorthand BASIC equivalent
a=x; a=x; LET a=x;
a=a+x; a+=x; LET a=a+x;
a=a-x; a-=x; LET a=a-x;
a=a+1; a++; LET a=a+1;
a=a-1; a--; LET a=a-1;

The advantage of using these shorthands is that it saves you typing, and perhaps more importantly (well almost) it helps increase the speed of the compiled SAM C program.

The ++ and -- can be placed before or after the variable to choose when the increment or decrement is to take place, e.g.

c
x=4;
y=10;
c=y-x++;

This evaluates to c=10-4 and then x will increment.

c
x=4;
y=10;
c=y-++x;

First x will increment and then c=10-5 (5)

Over 10,000 developers have bought Create GUI Applications with Python & Qt!
Create GUI Applications with Python & Qt6
More info Get the book

Downloadable ebook (PDF, ePub) & Complete Source code

To support developers in [[ countryRegion ]] I give a [[ localizedDiscount[couponCode] ]]% discount on all books and courses.

[[ activeDiscount.description ]] I'm giving a [[ activeDiscount.discount ]]% discount on all books and courses.

stdio.h Library Functions

I'll leave variables for now and move onto some functions available in the stdio .h file.

Printing using printf("",x,x)

This is the standard C function for printing characters to the screen, much like the BASIC command PRINT, e.g.

c
printf("Wibble!");

Would print "Wibble!" on the screen. You can choose the position of the text by using the library function at(y, x) e.g.

c
#include "stdio   .h"

main()
{
    at(11,11);
    printf("Arf");

    at(12,12);
    printf("Arf");
}

Would print:

python
    Arf
     Arf

...somewhere near the middle of the SAM Coupe screen. The printing of numbers and letters from variables is controlled in C by the use of control codes.

Code Prints
%d signed decimal
%u unsigned decimal
%b or %() binary (unsigned)
%x or %X hexadecimal (unsigned)
%c ASCII character
%s ASCII string

These are embedded in the text and cause values to be printed from a list following the quotes, e.g.

c
printf("%d", 10)     will print 10 (decimal)
printf("%b", 10)     will print 1110 (binary)

A \n can be placed in the text to force a new line at that position, e.g.

c
#include "stdio   .h"

main()
{
    int a, b;
    a=10;
    b=72;
    printf("Hello number %d \nWhich number %d",a,b);
}

Would print

python
Hello number 10
Which number 72

printf() will be explained in further detail in a later article in this series.

Reading the Keyboard using getc()

Also in the stdio.h file are functions for reading the keyboard. getc() is a very simple command which first of all waits for a key-press and then returns the ASCII value of the key pressed in your chosen variable, e.g.

c
#include "stdio.h"
main()
{
    char k;
    k=getc();
    printf("%c \n %d",k,k)
}

The above program will wait until a key is pressed, then print that character on the screen, with the ASCII character written underneath (remember the %c control code prints a character, while the %d prints a number).

Like I said, it's a simple command -- that's all there is to it.

Looping in C

There are a large number of looping methods available in C, just as in BASIC. Here is a brief explanation of the main types.

FOR...NEXT

Take for example the following BASIC loop

basic
FOR a=b to c STEP d
NEXT a

The C equivalent is

c
for(a=b;a<=c;a+=d){

}
  1. a=b set starting value for the loop variable (here, set to b).
  2. a<=c loop round while true (loop continues while a is less or equal to c)
  3. a+=d increment/decrement value (a increases by d each loop)

So...

basic
FOR a=1 TO 10:PRINT a:NEXT a

Would become...

c
for(a=1;a<=10;a++){
    printf("%d",a);
}

Or simply...

c
for(a=1;a<=10;a++) printf("%d", a);

If there are no other actions or only one other action in a loop, this can be placed on the same line as the loop, followed by a semi-colon.

In SAM C the variables for a for... loop must be set up before use.

for(a=0;b=2;c++); is a perfectly valid loop, which would on entry set a to 0, loop round while b=2 and with each loop increment c by one.

for(a=0;;a++) would set up a continuous loop because there are no end conditions.

DO...WHILE

Just as in BASIC the DO...WHILE loop can be used for setting up loops where no loop variable is required. For example, the BASIC loop:

basic
DO WHILE x=10
LOOP

...becomes...

c
while (c==10){

}

...and the BASIC loop:

basic
DO
LOOP WHILE x=10

...becomes...

c
do {

} while (x==10)

The difference between the loops is the while(x==10){} loop will check the condition before starting the loop, whereas do{}while(x==10); will execute the loop once before checking the condition.

An infinite loop can be set by giving it an argument that is always true, such as while(7>6){} or while(1){}.

IF...THEN

Before this months program I thought it would be a good idea to describe the C equivalent to BASIC's IF...THEN procedure.

The basic principle is the same as in BASIC and follows roughly the same idea. Take a look at the following C if statement.

c
if (x==0) printf("Hello");

This would print 'Hello' on the screen if x was equal to zero (note the double equals). The < and > can be used with the equals, or along just as in basic.

c
if (x>0) printf("Hello");
if (x<=0) printf("Wahey");

The logical operators in C are as follows

Operator Action
|| OR
&& AND
! NOT

The ! can be used with the equals and <> e.g.

c
if (x!=0) printf("x not equal 0");
if (x!>0) printf("x not greater than 0");

So this example...

c
if (x==0 && c!<10 || d>=1) printf("Bugle");

...would print 'Bugle' on the screen if x equals 0 and c isn't less than 10 or d is greater or equal to 1. Simple huh?

If there is more than one outcome from the if statement then you can enclose the instructions in curly brackets (as with the loops) but if (like the examples here) there is only one outcome, then you can put it on the same line followed by a semi-colon.

Just as in BASIC there is an else command and this is placed after the last set of instructions, e.g.

c
if (a==10) x=1; else x=2;

This would let x equal 1 if a=10 else x would equal 2.

Attack of the Killer Xs

Now it's time for the monthly program, which includes most of what has been learnt so far. This month it's a little game where the aim is to dodge the X's as they home in on your O. OK, so it's not very exciting, but it explains stuff and gives you a chance to try out programming a game! I'll explain it in sections as you type them in, so here we go...

c
#include "stdio   .h"

main()
{
    int score;
    char k,a,x,y,ox,oy;
    char pos[3][2];

    score=0;
    for (a=0;a<4;a++){
        pos[a][0]=a*0;
        pos[a][1]=a*5;

    }

    x=11,y=11,a=1,ox=x,oy=y;
}

This section of the program sets up the program by loading the stdio.h header file, then initializes the int, char variables and a character array called pos to hold the x and y coordinates of the killer Xs.

Next the for loop assigns x and y variables to the pos array, where the x=a*9 and y=a*5. The x and y variables are set to the starting point for your 'O' (at 11,11). Finally, ox and oy are set, these are the old x and y of your character -- so the old position can be cleared as you move.

c
do {
    k=getc();
    if (k=='q') y--;
    if (k=='a') y++;
    if (k=='o') x--;
    if (k=='p') x++;

This section sets up the loop (the exit condition is at the end) and then checks the keyboard with getc() returning the key ASCII code in k.

The value in k is checked against the letters in the if statement and the x or y position is altered according to which key has been pressed. For example, if q was pressed the y variable would decrease (moving your character up the screen).

c
a(y,x);
printf("O");
at(ox,oy);
printf(" ");
ox=x;
oy=y;

Next your "O" is printed on the screen and old position is printed over with a blank space.

c
a++;
if (a==3)a=0;

at(pos[a][1],pos[a][0]);
printf(" ");
if (pos[a][0]<x) pos[a][0]++;
if (pos[a][0]>x) pos[a][0]--;
if (pos[a][1]>y) pos[a][1]--;
if (pos[a][1]<y) pos[a][1]++;

at(pos[a][1], pos[a][0]);
printf("x");
score++;
at(0,0);
printf("%d", score);

} while (x!=pos[a][0] || y!=pos[a][1])

This section is for controlling the killer X's. First a is incremented (a holds the number of the current X to be controlled -- only one is moved for every move you make) and then if a==3 it is set back to 0 to start the loop again.

A blank space is printed at the position held in the pos array (which is effectively the old x and y position of the X) and then the x and y of your "O" is checked against the position of the current killer X, and depending on this the position of the current X is altered.

For instance, if the x position of the current killer X is higher than your O's x position, then the killer X will move to the left (pos[a][0]--). The new position is then printed on the screen as an 'X'. The value in score is incremented and this is printed at position 0,0.

The while(...) at the end of the loop checks to make sure that x is not equal to pos[a][0] or y is not equal to pos[a][1] and if this is true the loop ends. This has the effect of quitting the game if you an X.

Well that's all for this month, but just before I go... if you have any ideas for little programs you'd like to see me write in C in this little section then write to me via the FORMAT office and I'll see what I can do. No promises, but if it is small and I can use it to illustrate this series then I will try -- so get writing and keep reading and you never know what a future episode will bring.