Atari ST Basic To C
Atari ST Basic To C
Atari ST Basic To C
Olaf Hartwig
Abacus
Second Printing, May 1988
Printed in U.S.A.
Copyright © 1986 Data Becker GmbH
Merowingerstr.30
4000 Dusseldorf, West Germany
Copyright © 1986 Abacus Software, Inc.
P.O. Box 7219
Grand Rapids, MI 49510
Every effort has been made to insure complete and accurate information
concerning the material presented in this book. However Abacus Software
can neither guarantee nor be held legally responsible for any mistakes in
printing or faulty instructions contained in this book. The authors will
always appreciate receiving notice of subsequent mistakes.
GEM, GEM Draw and GEM Write are trademarks or registered trademarks
of Digital Research Inc.
ISBN 0-916439-58-5
Table of Contents
Appendix A 225
Appendix B 227
Index 229
Chapter 1
What interests us is that many programs for the Atari ST and the GEM
operating system are written in C.
3
Abacus Software Atari ST BASIC to C
But now that you have an ST, you should change to C as soon as possible.
Although ST BASIC is a highly refined language, it does not allow you to
write more advanced programs.
The main reason for this is that GEM is inaccessable from BASIC. And the
fantastic possibilities of GEM and mouse input, the fast MC68000
microprocessor and the ample RAM in the 520 ST or 1040 ST, are the
outstanding capabilities of this computer.
It may not make sense to program in machine language on the ST. The
speed of C approaches the speed of actual machine language-and it takes 6
to 10 times longer to program in machine language than it does in C.
Furthermore, machine language programs are much more difficult to modify
than programs written in C.
The programs you now run on your ST are therefore more likely to have a
future if you write them in C. If you later change to a different computer
system at a later time, you can still use your old C programs.
The power of C is demonstrated by the fact that not only GEM, but illl of
the Digital Research routines not written in machine code were written in C.
4
Abacus Software Atari ST BASIC to C
This book gives you the opportunity to move from BASIC to C. Although
the common difficulties mentioned above do hinder the programmer from
changing from BASIC to C, they can all be overcome. To make things
easier, the entire concept of this book was developed especially for the
BASIC programmer, and is directed specifically toward the capabilities of
the ST.
The examples in this book use the Aleyon compiler that is part of the Atari
Developer's Package. It was chosen because it is considered the "standard"
among ST C compilers. Other C compilers such as Megamax, Lattice, and
Mark Williams are very similar and can be used with very few syntax
changes.
5
Chapter 2
r
First steps for (former)
BASIC programmers
Abacus Software Atari ST BASIC to C
Yes, it's possible. This chapter includes all of the important structures of
C-and you'll need just one day to work through it. You will be able to
write your flrst C programs on the ST by the time you finish this chapter.
Of course, this method alsc has its disadvantages. If we leave out complete
details for a while, we cannot avoid repeating parts of this chapter later on.
However, we believe that this ongoing review is not annoying, but helps
you learn even more.
9
Abacus Software Atari ST BASIC to C
main ()
{
printf("Hello, how are you?\n");
gemdos(Oxl);
}
gemdos (OxI)
This causes the program execution to stop until a certain key is pressed.
You must keep this GEM-specific characteristic in mind with the following
examples. Always add the GEMDOS call to the end of your program.
10
Abacus Software Atari ST BASIC to C
main ()
This line represents a special C function. C programs are normally
composed of a series of individual functions.
input ()
{
The commands of the function
input go here.
The braces surrounding the program in our simple example start and end all
the statements that make up a function. The last closing brace is like the END
command in BASIC.
11
Abacus Software Atari ST BASIC to C
printf ( );
Now we'll explain the meaning of the '\ n' in the program text. This
symbol is not printed, but executes a line feed (end-of-line).
If you had left this symbol off and printed the line like this:
main ()
{
printf("Hello, H);
printf ("how");
printf("are H);
printf("you?");
printf("\n");
gemdos (Oxl) ;
}
12
Abacus Software Atari ST BASIC to C
main ()
{
printf ("Hello,
how
are
you?\n") ;
gemdos(Ox1) ;
}
We have now had our first experience with program format, looked at
functions, and learned how to print text on the screen. But printing numeric
variables to the screen is not as easy.
13
Abacus Software Atari ST BASIC to C
10 A=1
20 B=3.14
30 PRINT A;B
40 END
main ()
{
int a;
float b;
a = 1;
b = 3.14;
printf("%7d %5.1f\n", a, b);
gemdos (Ox1) ;
}
All variables within these routines must be declared at the beginning of the
function. In BASIC, this is usually not necessary.
The declaration tells the computer which variables it should use and thereby
defines the variable names. In this case, they are a and b.
int a;
14
Abacus Software Atari ST BASIC to C
The declaration:
float b;
a = 1;
b 3.14;
This may appear strange and unnecessarily complicated to BASIC
programmers. When you programmed in BASIC in the past, all the
variables were automatically set to zero when the program was RUN.
However, this does not happen in C. The initial declaration does not assign
a value to the variables.
15
Abacus Software Atari ST BASIC to C
PRINT A; B
You already know the basic structure of the printf command from our
earlier examples.
The only new elements are the control instructions between the quotation
marks. These act as format instructions. One example of this is the format:
n%5.1fn
Every format statement is prefIxed with a % character. This lets the computer
know that it should output a value (here the value of the variable b) in a
specifIc format.
The format itself is determined by the element 5 . 1. The 5 . 1 means that the
number should be printed in a space comprised of five characters and
containing one place after the decimal.
16
Abacus Sortware Atari ST BASIC to C
We cannot write very meaningful programs using only text and numeric
output. We also need loops, like the FOR-NEXT loop in BASIC.
You should have an easy time understanding the for loop in C, because
it's closely related to the FOR-NEXT loop in BASIC. You'll notice this right
away in the following example program. The program prints a list of the
numbers from one to twenty and their squares:
main ()
{
int X;
for (x = 1; x <= 20; x = x + 1)
printf("%2d %3d\n", x, x*x);
gemdos (Ox1) ;
}
18 324
19 361
20 400
17
Abacus Software Atari ST BASIC to C
The corresponding BASIC commands are clearly similar to C's for loop:
The first thing done is to set the first x value to one. The BASIC
construction:
FOR X=l
x = 1;
Note that it is not necessary to give the variable x a value beforehand under
these circumstances. An additional x = 1; is not necessary before the
for loop. The initialization takes place right in the loop instead.
The second part of the C for loop is the outer interval limit.
TO 20
is replaced in C with:
x <= 20;
18
Abacus Software Atari ST BASIC to C
Many other delimiters are possible, of course. One example would be:
x < 21;
which has exactly the same effect as the instruction x <= 20.
The third part of the for loop is the step width. In BASIC, you don't have
to include the step width of +1.
When you omit the STEP instruction from a FOR-NEXT loop, the BASIC
interpreter automatically sets the step width to + 1.
You must change your thinking a little in C, however. The step width must
always be specified explicitly, as it is in this case with:
x = x + 1
This is comparable to the BASIC instruction:
STEP +1
Note also that the loop declaration may not be followed by a semicolon:
You've probably noticed that we have always talked about the for loop in
relation to a BASIC FOR-NEXT loop. But where do we find the
corresponding NEXT statement in a C program? In other words, how many
statements does the C compiler repeat within the for loop?
The answer is simple: one. If we want to repeat more than one statement,
we can place them in braces, making a statement block.
19
Abacus Sortware Atari ST BASIC to C
This is an example:
main ()
{
int X;
for (x = 1; x <= 20; x = x + 1)
{
printf("Value of X is ... ");
printf("%2d\n", x);
printf("X squared is ... ");
printf("%3d\n", x*x);
}
gemdos (Oxl) ;
}
Here, a whole block ofprintf calls follows the for statement. The entire
block must be enclosed in braces.
This program prints the values of x together with the values of x squared,
each printed on a separate line:
Value of X is 1
X squared is 1
Value of X is 2
X squared is 4
(through)
Value of X is 20
X squared is 400
This loop is probably less familiar to you as a BASIC programmer than the
FOR-NEXT loop. For our purposes, while can best be expressed as
"as long as ."
20
Abacus Software Atari ST BASIC to C
The algorithm of the loop used in our previous example program should
look something like this:
x = 1;
as long as x <= 20 do the following:
{
x = x + 1;
print x
and x squared
10 X=l
20 '
30 IF X<=20 THEN PRINT X;X*X:GOT030
40 '
50 END
Below is the corresponding C program with the correct syntax for the
while loop:
This program prints out a value table just like our last example, which used
a for loop.
21
Abacus Software Atari ST BASIC to C
x = 1;
For example, if only one instruction needs to be repeated, the braces can be
dropped, just as they are in our for loop example. Also parallel to the for
loop syntax is the fact that no semicolon follows the wh i 1 e loop
declaration.
The step width must be handled inside the loop instruction, as it is in this
case with:
x = x + 1;
We also could have specified any other step width, such as "2" or "0 . 5 " .
2.5.3 Comments in C
The only thing missing now is an explanation of the fIrst program line:
This command corresponds to a REM line in BASIC. You could add the
corresponding BASIC line to the previous BASIC program:
22
Abacus Software Atari ST BASIC to C
The text between the slashes and asterisks is ignored by the compiler.
/* Comment text */
At this point you're ready to write your fIrst programs. But there is still one
very important element missing: the ability to enter data.
Just as the printf instruction can do much more than the normal BASIC
PRINT instruction, there are many different variations of data input with
different capabilities in C.
To keep things simple, we'll first simulate the BASIC INPUT command
with two different C commands.
letter = getchar()
This function, which assigns a character read from the keyboard to the
variable letter, mru~es it easy to enter a single character in a running
program. It is comparable to a BASIC routine containing a GE T command:
23
Abacus Software Atari ST BASIC to C
Longer character strings must be built-up using a repeat loop. It can look
like the following in C:
#inc1ude "stdio.h"
main ()
{
int Lt;
Lt = getchar () ;
while (Lt 1= EOF)
printf("%c\n", 1);
Lt = getchar();
}
gemdos (Oxl) ;
The program takes the characters from the keyboard and prints them on the
screen. The input is ended with <ControbZ.
get char () doesn't really read a character from the keyboard, but the
ASCII value of the character. This value must be passed as type int rather
than type char.
The expression " %c" in this p r in t f call tells the computer to print a
character.
24
Abacus Software Atari ST BASIC to C
Another new thing here is the EOF. This means End Of File. It indicates
when the input was ended-in other words, when <RETU:RN> was entered.
One further comment: ! = in C stands for "is not equal to." It corresponds to
the BASIC inequality operator <>.
The command
iinclude "stdio.h"
combines the standard library of the compiler with the program. This
defines a set of standard functions and constants. In our example, these are
the EOF constant and the function getchar ().
getchar ()
{
char c;
return ( read(O, &c, 1) > 0) ? c & 0377 : EOF);
This function addii ion must be made to all programs that use the
getchar () functi
At the time this boo is being published, it is not certain whether or not the
function is irnplem in the official Alcyon C ST version.
On the ST, the sig al for the end of a line is <Control>Z. To end the
program, you must u e this control character instead of <RETURN>.
25
Abacus Software Atari ST BASIC to C
The output for our program using the Alcyon C package can look like this:
abcd"'Z
The output would then read:
a
b
c
d
You don't have to worry about this function anymore for the time being.
You can now input single characters into the computer. This is very easy to
do, as you have already seen.
But this is not enough, obviously. We will now find ways to implement the
BASIC commands like INPUT A or INPUT A$ in C.
In C, we get:
main ()
{
int a;
scanf("%d", &a);
gemdos (Ox1) ;
}
26
Abacus Software Atari ST BASIC to C
Aleyon C stores ASCII inputs, and therefore the scanf () function stores
the input as files, each with a line feed at the end. A <ControbZ (Ox1a)
stands for the End Of File.
The input for scanf () must therefore be ended with this control code.
This is not enough for the input to be accepted, however. A character which
does not match the format must be entered before the terminating
<ControbZ. The reason for this is that the scanf () function terminates as
soon as the input does not agree with the format. For example, the input of
the integer 1245 must be written as follows:
1245 "z
The space (_) doesn't match the input, since it doesn't represent a number.
The "Z represents the terminating <ControbZ character. <Return> must be
pressed after this input.
This complicated input procedure is unacceptable for the user. We hope that
an updated version of the Alcyon C for the ST will provide a standard input
ended simply with <RETURN>.
Now let's explore the further use of the &a variables in a program.
Our BASIC program, which uses the variable A% after input, might look
like the following:
27
Abacus Sortware Atari ST BASIC to C
10 INPUT A%
20 PRINT A%; A%A2
30 END
main ()
{
int a;
scanf("%d", &a);
printf("%d %d\n", a, a * a);
gemdos(Oxl);
}
The address operator & is used here only with the scan f instruction.
2.7 Arithmetic in C
1. x = x + 1;
2. x * x;
3. while (x <= 20)
4. for (x = 1; x <= 20; x = x + 1)
5. a = 2/ (3*3) ;
28
Abacus Software Atari ST BASIC to C
Here you see once again that C expressions like a =2/ (3 * 3) are identical
to BASIC expressions in their syntax, logic, and placement of parentheses.
In addition, all of the following C operations correspond to their BASIC
counterparts:
<>
is written in C using:
!=
C also distinguishes between:
which is the equality operator. The symbol for value assignment, as used in
the following line:
x = -1;
29
Abacus Software Atari ST BASIC to C
if (x == 1)
statement
C uses the equivalence operator == to test for the equality of two values.
AND
is formulated in C with:
&&
OR
is represented in C with:
II
is translated in Cas:
if(a == 1 && b 2 II c 5)
{
30
Abacus Software Atari ST BASIC to C
At first glance, this looks somewhat unusual. However, all that is new is
the form of some of the arithmetic expressions in C. You already know the
syntax and possible uses of these expressions from BASIC, and there are
no major changes.
x++;
x = x + 1;
x--
in place of:
x = x - 1
The increment and decrement operators are unusual in that they can be used
either before or after the variable they modify, and have different operations
in each case. Since they are operators, their result is an expression. More on
this later.
31
Abacus Software Atari ST BASIC to C
Now, we'll quickly cover the if and i i-else control structures and
make ourselves familiar with them.
The following BASIC program asks you to guess a number, and prints an
appropriate message if you guess the right one. It shouldn't be taken too
seriously-its main purpose is to demonstrate the if structure.
10 INPUT X%
20 '
30 IF X%=13 THEN PRINT "CORRECT!":
PRINT "THAT WAS THE ANSWER!"
40 END
main ()
{
int Xi
scanf ("%d", &x);
if (x == 13)
{
printf("Correct!\n");
printf("That was the answer!\n");
}
gemdos(Oxl);
}
32
Abacus Software Atari ST BASIC to C
As you can see, there are really no differences in the normal if structure for
the BASIC programmer. The construction is the same, and the syntax
corresponds to the while loop, which we've already covered.
However, they can be left off if only one command is to be executed after
the if statement.
10 INPUT X%
20 '
30 IF X%=13 THEN PRINT "VICTORY!";
PRINT "THAT WAS THE ANSWER!"
ELSE PRINT "TOO BAD! WRONG GUESS!"
40 END
33
Abacus Software Atari ST BASIC to C
main ()
{
int x;
scanf("%d", &x);
if (x == 13)
{
printf("Correct!\n");
printf("That was the answer!\n");
}
else
{
printf("ToO bad! Wrong guess!");
printf("\n") ;
}
gemdos (Ox1) ;
Just as in BASIC, the else statement is simply placed after the if.
The syntax of the else statement should be clear and self-explanatory now
that you've had some exposure to C control structures. Just as with the if
and while statements, there is no semicolon after the else statement.
34
Abacus Software Atari ST BASIC to C
2.9.1 Variables
C has more variable types for other purposes, such as greater mathematical
precision. We will cover these other types in later chapters.
2.9.2 Constants
C can also define symbolic constants. This is done with the #de fine
instruction. It might look like this in a program:
#define INCREMENT 1
#define LO . BOUND 0
#define HI.BOUND 20
main ()
{
int X;
for(x = LO.BOUND; X <= HI.BOUND; x = x + INCREMENT)
printf(" %2d\n", x);
gemdos(Oxl) ;
35
Abacus Software Atari ST BASIC to C
This short C program counts from the lower bound of an interval (defined
with the value zero by the constant LO . BOUND) until the upper bound
HI. BOUND is reached. The increment is set at one.
The three constants defined before the main program are used later in the
for statement. You might ask why we even bother with symbolic
constants. Granted, in this short program they are somewhat complicated
and really unnecessary.
Constants are much more useful in larger programs. If there are values
which you use over and over in a program and they do not change, you
should define them as constants. This way, if you want to change this
value, you only have to change it once instead of every occurrence.
You should note that no semicolon follows the #de fine construction, just
as none follows a comment. You can assign text to a symbolic constant as
well as numbers. The compiler then converts the constant text during
compiling, and replaces all of the constant names with the corresponding
text. As you would expect, constant names within quotes are not replaced.
2.9.3 Arrays
10 DIM S(20)
or any other variable type that the elements of the array are to have.
36
Abacus Software Atari ST BASIC to C
Note that unlike most BASIC arrays, which start at 1, arrays in C start
numbering the elements with zero. This means that int s [20]
dimensions an array with a total of 20 elements, which are then numbered
s [0] through s [ 1 9 ] .
DIM S (20)
main ()
{
int s[20];
int i;
for(i = 0; i < 20; i = i + 1)
s[i] = 0;
/* additional program steps ... */
gemdos (Ox1) ;
}
For practice, here is a short program that uses the get char () function to
read a character from the keyboard and put it into the array. In BASIC, it
would look like this:
10 DIM T$(50)
20 1=0
30 A$=""
40 GET A$
50 IF A$="" THEN 40
60 '
70 1=1+1
80 T$(I)=A$
90 IF A$<>CHR$(13) AND 1<50 THEN GOTO 30
100 END
37
Abacus Software Atari ST BASIC to C
getchar ()
{
char Ci
return((read(O, &c, 1) >0) ? c & 0377 :EOF );
All of the structures in this program have already been explained in the
section on data input and the get char () function.
Something new here is the string assignment section. The syntax and details
of arrays were explained on the preceding pages.
You should not only read the above program, but also type it into the
computer. You should also experiment with the C you have learned so far
by changing or expanding the program. You'll learn C like any other
language, through active programming and practical application-not by
just reading! This advice applies to all of the programs in this book.
38
Chapter 3
First you should solidify your knowledge of C. This means that you should
experiment-sit in front of the ST and write simple programs based on what
you learned in the previous chapter. The time that you so invest now will be
worth twice its value later, when we work through the more complex
structures of C.
To help you with your first programs, the following pages contain a short
review of the material we have covered so far, with special emphasis on
comparisons to BASIC.
A program consists of individual jUnctions. Every function has a title and its
instructions are enclosed in braces.
Example:
square ()
{
instructions in the function "square"
}
The function with the title rna in () has a special position. It is always the
first function to be executed and it usually calls the other functions. Each
individual statement within a function is separated from the others by a
semicolon, in the same manner that BASIC commands on a single line can
be separated by colons.
41
Abacus Software Atari ST BASIC to C
3.2 Comments
printf("Text\n");
Numerical output requires an indication of the variable type and follows a
format like the following:
The format "7 .2" in the above example of the pr in t f instruction causes
a number with a total of 7 digits, including two after the decimal point, to be
printed out for the variable b.
42
Abacus Software Atari ST BASIC to C
Constants are defined using the #define construction before the main ()
function in a program, and they can be used in every function thereafter.
Example:
#define constant 33
Variables used within a function must be defined before they are used. The
most important variable types are as follows:
All variable types can be defined as arrays. For example, this is how an
array of 20 integers is defined:
int a[20]
a = 1;
43
Abacus Sortware Atari ST BASIC to C
3.5 Loops
The three parameters give the initial value of the initial loop value, end
value, and step size.
The increment is specified within the loop. In the example above, it is set to
one with:
x = x + 1;
Single characters can be read using the get char () function, similar to the
BASIC command GET:
int a;
a = getchar();
44
Abacus Software Atari ST BASIC to C
The scanf command can be substituted for the BASIC INPUT command:
int a;
scanf("%d", &a);
Just like the printf command, scanf must use one or more of the
variable types, of which %d, %f, and %s are the most important. In the
scanf command, the address operator & must always precede the variable
name, unless the variable is an array name, such as a string.
3.7 Arithmetic in C
if (x == 1)
{
then execute these commands
}
else
{
execute these commands.
}
45
Abacus Software Atari ST BASIC to C
if (x == 1)
This list is certainly not complete, because C has many more elements than
those mentioned so far.
Use this list to start programming. You can learn C only through practice!
46
Chapter 4
We have already covered text output in the previous chapters. First we'll
review briefly:
10 PRINT "HELLO"
main ()
{
printf("Hello\n");
gemdos (Ox1) ;
}
main ()
{
printf ("he");
printf(IIlloll);
}
49
Abacus Software Atari ST BASIC to C
This assembles the word "hello" from two words. It corresponds to the
following example in BASIC:
10 PRINT "he";
20 PRINT "110";
hello
The underline character ( ) represents the cursor position after the execution
of the command. -
10 X=3.14
20 PRINT X
main ()
{
float X;
X = 3.14;
printf("%f\n", x);
gemdos (Oxl) ;
}
10 X%=15
20 PRINT X%
50
Abacus Software Atari ST BASIC to C
10 PRINT 15
The corresponding C function looks like this:
main ()
{
printf("%d\n", 15);
gemdos (Ox1) ;
}
The format statements contain commands that determine the form of the
output. In our examples, the specification %d was chosen for the integer
15, just as %f was chosen for the floating point value 3 . 14. In the next
section we'll look at these conversion specifications more closely.
51
Abacus Software Atari ST BASIC to C
These commands can be divided into the format specifiers, which determine
how many places of a number are printed, for example, and the conversion
elements, which determine the output type, such as integer, float, or string.
First we'll look at the conversion elements.
However, C has some more type declarations that we left out of our initial
overview. The next sections contain a complete list of the conversion
characters which the printf function allows.
52
Abacus Software Atari ST BASIC to C
%x Works like %0, except that it puts the argument into base 16
(hexadecimal).
(-)m.nnnnnnE(+-)xx
In a printf call the format specifiers tell how many places before and after
the decimal point will be printed, and also whether the output will be right-
or left-justified.
%f Places six digits after the decimal point, while the number of digits
before the decimal point remains arbitrary.
53
Abacus Software Atari ST BASIC to C
If you want to change these formats or set other formats, a statement of the
following form can be used:
"%7.Sf"
10 PRINT 2*13
Translated to C, we get:
main ()
{
printf("%d\n", 2*13);
gemdos(Ox1);
}
Just like with BASIC, we can carry out a calculation right in the output line
instead of printing just a single number.
54
Abacus Software Atari ST BASIC to C
main ()
{
printf("%d %f %f %f\n", 2 * 13, 2.0 / 3.0;
3.14 * 2.222222,4.0 - 2.2);
gemdos (Ox1) ;
}
10 A=6
20 B=88
30 '
40 PRINT A/B
is translated in Cas:
main ()
{
float a,
b;
a = 6;
b = 88;
printf("%f\n", a/b);
gemdos (Ox1) ;
Here there are really no essential differences between the two versions.
Look closely at the variable declaration. You should make sure that you do
not create a new format as a result of calculations. This can happen when a
floating-point number results from two integer variables. When this
happens, the format must be changed to %f to avoid an errors or incorrect
output.
55
Abacus Sortware Atari ST BASIC to C
You can format text as well as numbers. Concrete examples are the best
way to show how this works.
main ()
{
float a;
a = 15;
printf("%f\n", a);
gemdos (Ox1) ;
}
then we get the output 15 . 000000. The six zeros are printed automatically
because we didn't specify any additional format instructions after the %
sign.
printf("%.Of\n", a);
56
Abacus Software Atari ST BASIC to C
If you want to leave two positions after the decimal point, then the printf
call would look like this:
printf("%.2f\n", a);
10 PRINT 2/3
main ()
{
printf("%f\n", 2/3);
gemdos(Ox1);
}
main ()
{
printf("%f\n", 2.0/3 . 0);
gemdos (Ox1) ;
}
0 . 666667
57
Abacus Software Atari ST BASIC to C
We have already gone into some detail about printing numeric variables.
Now welllook more closely at printing string variables. One example is the
following BASIC program:
10 A$="ATARI ST"
20 PRINT A$
main ()
{
printf("%s\n", "ATARI ST");
gemdos (Ox1) ;
}
Now we will combine two different variable types in our output Again we
start with a BASIC program:
10 A%=12345
20 B$="THE NUMBER IS ... >"
30 '
40 PRINT B$iA%
58
Abacus Software Atari ST BASIC to C
main ()
{
int a;
char *b;
a = 12345
b = "The number is ... >" ;
printf("%s %d\n", b, a);
gemdos (Ox!) ;
}
This program has exactly the same output as the BASIC version. The
variables a and b were defined as integer and string, respectively, and were
subsequently assigned values.
Note the space between the format expressions %sand %d. Because this
space is inside quotation marks, it is printed out. This means that an actual
space ends up between the string and the number. In BASIC, this
separation is automatically performed in the expression:
40 PRINT A$;B
10 T$="USER"
20 PRINT "HELLO ";T$
main ()
{
char *t;
t = "user";
printf("Hello %s\n", t);
gemdos (Ox!) ;
}
59
Abacus Software Atari ST BASIC to C
In this example, it is easy to see that all of the characters (not belonging to a
conversion specifier) inside the quotation marks are printed out. Most
interesting is that in the call
This can be seen if you decide to print the variable before the text. This is
done by changing the printf line to this:
printf("%s Hello\n",t);
user Hello
10 T$="W"
20 PRINT T$
main ()
{
char t;
t = 'W';
printf("%c\n", t);
gemdos(Ox1);
60
Abacus Software Atari ST BASIC to C
t = 'W';
This is the correct syntax for character variables. If t were a string, then the
line would be:
t = "W";
t = "w";
10 PRINT CHR$(67)
is written in Cas:
main ()
{
printf("%c\n", 67);
gemdos (Ox1) ;
}
This routine prints the character with ASCII value 67 on the screen. This
corresponds to the value of the letter C.
61
Abacus Software Atari ST BASIC to C
We can imitate the function ASC ("") in much the same way.
10 PRINT ASC("B")
main ()
{
printf("%d\n", 'B');
gemdos(Oxl);
}
main ()
{
char t;
t = 'B';
printf("%d\n", t);
gemdos (Oxl) ;
}
You can use these two functions (Le. the routines corresponding to ASC
and CHR$) to analyze strings or input to see what characters are present, or
to eliminate certain characters.
Until now we have used only the pr int f function to print out data.
However, there are two other functions for outputting data.
62
Abacus Software Atari ST BASIC to C
a = get char () ;
iinclude "stdio.h"
idefine putchar(a) putc(a,stdout)
main ()
{
char a;
a = Ip I;
putchar(a);
gemdos(Oxl);
}
This routine assigns the character I p I to the variable a and prints the single
character on the screen.
With put char () you can print single characters on the screen without the
trouble and expense of print f . However, this function is limited to screen
output.
Now let's look at the puts () function. This command stands for "output
string," and outputs strings of characters.
10 A$="FRED JOHNSON"
20 PRINT A$
63
Abacus Software Atari ST BASIC to C
iinclude "stdio.h"
main ()
{
char *a;
a = "Fred Johnson";
puts (a) ;
gemdos (Ox1) ;
}
main ()
{
char *a;
a = "Fred Johnson";
printf("%s\n", a);
gemdos (Ox1) ;
}
In both examples you can use shorter programs to get the same result,
taking as an example the following BASIC line:
10 PRINT "PH
iinclude "stdio.h"
idefine putchar(c) putc(c,stdout)
main ()
{
putchar ('P') ;
gemdos(Ox1);
}
The same program can be written using the standard print f statement:
main ()
{
printf("%c\n", 'PI);
gemdos(Ox1);
}
64
Abacus Sortware Atari ST BASIC to C
iinclude "stdio.h"
main ()
{
puts ("Fred Johnson");
gemdos(Ox1);
}
main ()
{
printf("%s\n", "Fred Johnson");
gemdos(Ox1);
}
As you can see, character output is much more elegant using putchar ()
and puts () than it is with printf (). In actual programming you will
use these compact fonns when no conversion fonnats are necessary. There
is no substitute for the formatting commands supported by the p r i n t f
function.
In addition, when more than one value is to be printed out on a line, only
the printf function will work, because puts () and putchar () both
execute an automatic new-line.
In our introductory chapters, we left out quite a bit about input as well as
output. In addition to what we have already learned about scanf and
getchar () , there are many other possibilities for data input. Most of all,
we need to look more closely at the two input functions we have already
learned. First let's examine the function get char.
65
Abacus Software Atari ST BASIC to C
10 A$=INKEY$ 10 GET A$
20 IF A$="" THEN GOTO 10 20 IF A$="" THEN GOTO 10
30 ' 30 '
40 PRINT A$ 40 PRINT A$
#include "stdio.h"
#define getchar() getc(stdin)
#define putchar(c) putc(c,stdout)
main ()
{
int a;
a = getchar();
while (a != EOF)
{
putchar (a) ;
a = getchar();
}
gemdos (Ox1) ;
}
In the formulation chosen here, we have used the put char () function for
output and get char () for input of a character. It should be clear to you
that these functions are related to each other.
66
Abacus Software Atari ST BASIC to C
character = getchar () ;
Along with the put char () statement for printing a single character, we
have the following function that prints a string:
puts ()
There is a corresponding command for data input as well. It is:
gets (string) ;
10 INPUT A$
20 PRINT A$
#include "stdio.h"
main ()
{
char *a;
gets(a);
puts(a);
gemdos (Ox1) ;
}
67
Abacus Software Atari ST BASIC to C
Notice that the output of a string is much more elegant using puts ( ) ,
because this function is much easier to use than the printf function. This
can be seen by comparing the previous example with the following:
#include "stdio.h"
main ()
{
char *a;
gets(a);
printf("%s\n", a);
gemdos (OxI) ;
}
As a result, we conclude:
The Alcyon C version in the ST development system has problems with the
get s function. These are due to an incorrect input format not found in
standard C compilers. This function runs with no problem on all other ST C
compilers. We hope that the commercial version of the Alcyon C makes use
of a standard input format
This command works not only for the input of numerical values, but also
allows the input of strings or single characters. Because of this versatility,
the scanf function corresponds more closely to the BASIC command
INPUT than does any other C function. This versatility is obtained at the
cost of a somewhat more complicated structure, however.
The scanf function offers the best way to enter numeric data into a
program. We will go over each of the two applications separately and in
detail in the following pages. First we'll look at the input of characters and
strings, and then work with numeric data.
68
Abacus Software Atari ST BASIC to C
10 INPUT T$
20 PRINT T$
main ()
{
char *t;
scanf("%s", t);
printf("%s\n", t);
gemdos (Ox1) ;
}
The input format specific to Alcyon C was already explained in the first
chapter. The number 15, for example, is entered as follows:
15 "z
and strings are ended with <Control>Z:
input text"Z
69
Abacus Software Atari ST BASIC to C
main ()
{
char t[30];
scanf("%s", t);
printf("%s\n", t);
gemdos(Ox1);
}
An array is treated like a pointer variable. This means that you can also use
arrays in conjunction with scanf calls.
Nevertheless, pointer structures are more flexible and use storage more
efficiently than array structures. If only twelve elements are placed into a
3D-element array, for example, the memory still holds places for 30
elements. However, the pointer structure would have only twelve elements
plus an end marker in memory. Thus, a great deal of storage space can be
saved by using pointers instead of arrays.
Now, let's look at one more small problem. The BASIC program:
'include "stdio.h"
main ()
{
char *x;
printf("Please type in the text ");
scanf("%s", x);
puts(x);
gemdos (Ox1) ;
}
In both cases, input directly follows the text without a new-line in between.
70
Abacus Sortware Atari ST BASIC to C
10 INPUT Z%
20 PRINT Z%
is translated to C as follows:
main ()
{
int Z;
scanf("%d", &z);
printf("%d\n", z);
gemdos (Ox1) ;
}
So far nothing is new. As we have already learned, the address operator &
is always necessary so that the computer knows where it must store the
value in memory.
10 INPUT Z
20 PRINT Z
And here is the program in C:
main ()
{
float Z;
scan f ( " %f", & z) ;
printf("%f\n", z);
gemdos (Ox1);
}
71
Abacus Sortware Atari ST BASIC to C
15.000000
The above line is the printed form of the integer 15 in the example. The
same section tells how to correct this.
printf("%.Of\n", z);
10 INPUT T$, A, B%
20 PRINT T$;A;B%
More than one variable can be entered using commas to separate the
individual variables in BASIC. And the same is true of C:
text, 2, 3.14
main ()
{
char *t;
float a;
int b;
scanf("%s %f %d", t, &a, &b);
printf("%s %f %d", t, a, b);
gemdos(Ox1);
}
72
Abacus Sortware Atari ST BASIC to C
You might complain that we have already covered this with the
getchar () function. That's true, but the get char () function does not
correspond exactly to the BASIC line:
10 A$=INKEY$
character = getchar();
does indeed read in a single character, just as the INKEY$ or GET function
does in BASIC. But it then expects a RETURN to end the input.
character = getch();
The function get ch corresponds exactly to the following BASIC routine:
10 A$=INKEY$
20 IF A$="" THEN 10
73
Abacus Software Atari ST BASIC to C
iinclude "stdio.h"
idefine putchar(a) putch(a,stdout)
idefine getchar() getc(stdin)
main ()
{
int a;
a = getch () ;
putchar(a);
gemdos(Ox1);
}
char bf [100] ;
int b=O;
getch ()
{
return«b > 0) ? bf[--b] : getchar(»;
}
Here you see how simple this operation is with the getch () function.
However, note that the variable read into getch () is of type integer. Just
as with the get char function, this function reads in the ASCII value of the
character entered-i.e. an integer.
putchar(a);
printf("%c\n", a);
The compiler version included in the Atari development package does not
include the above functions. But they are easy to simulate. The
getchar () function was already synthesized in the introductory chapter.
74
Abacus Software Atari ST BASIC to C
If you want to use these functions in Alcyon C, then add the following to
the end of your program:
/ * getchar () * /
getchar ()
{
char c;
return ( (read(O, &c, 1) > 0) ? c & 0377 : EOF);
#include "stdio_.h"
#define putchar(a) putch(a,stdout)
#undef get char
main ()
In Digital C, all input must be ended with a <ControbZ. All of the other C
compilers use the traditional C standard, so none of them need this
additional control character.
The above getchar function can also be defined as a macro. This reads:
75
Chapter 5
( Variable Types in C )
Abacus Software Atari ST BASIC to C
Variable Types in C
Now that we have looked at the screen input/output functions, let's take a
closer look at the data types in C. This topic includes explanations of
variable names and constants, which we have already touched upon. We'll
also cover data types and conversions and declaration headers.
In addition, we'll look at other important areas including arrays and the
differences between local and global variables in a program. Finally, we
will explain important details and special cases relating to pointers.
are seen as the same variable because the first two letters (VA) are the same.
C goes further here and identifies the first eight characters of variable
names. But just as in BASIC, variable names can be longer than the first
eight significant characters.
79
Abacus Software Atari ST BASIC to C
strnum
We could use the following name and make the meaning clearer:
str num
if else
while do while
for switch
case default
break continue
return goto
Choose suggestive variable names, i.e., names that immediately give away
the purpose of the name in the program. Y ou'll save yourself a lot of time
debugging large programs.
In BASIC you quickly learn to use short variables of one or two characters.
You should try to unlearn this when programming in C, especially when
working with more complex programs.
80
Abacus Software Atari ST BASIC to C
5.2 Constants
So far, we have declared only integer constants. However, all variable types
can be defined as constants, since the text following the constant name is
simply inserted in place of the name where it occurs. Note that this
replacement does not occur if the constant name appears in quotation marks
as an element of a string.
In the following example program, we define constants for each of the four
major variable types in C: INTEGER, FLOAT, CHAR and STRING.
#define INTEGER 22
#define FLOAT 1.2345
#define CHAR 'D'
#define STRING "This is a text"
main ()
{
printf("%d\n", INTEGER);
printf("%f\n", FLOAT);
printf("%c\n", CHAR);
printf("%s\n", STRING);
gemdos(Ox1);
}
As you can see, the use of these constants is identical to the use of
corresponding variables, despite differing types.
10 CHAR$="D"
81
Abacus Software Atari ST BASIC to C
The equals sign is not necessary in C, and single quotes C) are used instead
of double quotes ("). These differences may lead to mistakes because of
your familiarity with BASIC. One possible error is this:
On the other hand, string constants must be enclosed in double quotes, just
as with definition of string variables:
Note that the replacement is strictly text replacement and there are therefore
no constant "types." This means that the quotation marks ~ part of the
replacement text
The float constants can also be written out in scientific notation, like this:
or like this:
All floating-point constants are handled like double variables, i.e. like
float variables, but with double precision.
Long integer constants can be defmed with an L character:
12345678L
82
Abacus Software Atari ST BASIC to C
A% Integer
A Floating point
A$ Character/string
We will talk about arrays, which are more complex forms of the
fundamental data types, in a later section.
The data types above are also found in C. In addition, double values are
considered one of the elementary data types.
The following list shows the data types which are possible in C:
1. short int
3. unsigned int
83
Abacus Software Atari ST BASIC to C
unsigned int values are always positive. Unsigned integer values obey
the mathematical "modulo 2"u" rules, where n represents the number of bits
in an integer value.
short int ai
long int bi
unsigned int Ci
At this point, we would like to restate that all declared variables must be
given a value before they can be used in a program.
In the following sections we discuss the data types you know from BASIC
as strings and arrays.
In BASIC, variables are not often converted to other variable types. The
situation is different in C-data type conversions are very common. We
have already mentioned a few of these possibilities.
10 PRINT CHR$(66)
84
Abacus Software Atari ST BASIC to C
It reads as follows:
main ()
{
printf("%c\n", 66);
gemdos (Ox1) ;
}
The result of both programs is that the character B (ASCII value 66) is
printed out on the screen. When you look at the programs closely, you see
the same thing is happening in both: the number 66 is being converted to the
letter B. But C can do more. The following program is also possible
(although it may seem unusual to you as a BASIC programmer):
main ()
{
int value;
value = 123 + 'B';
printf("%d\n", value);
gemdos (Ox1) ;
}
The Atari ST development system version of Alcyon C does not perform the
conversion of character variables completely. As a result the following
program will not run on this compiler. It will, however, run on all other
standard compilers.
85
Abacus Software Atari ST BASIC to C
When converting characters into numeric values, you must pay attention to
whether a negative number results. The C compiler does not check to see if
a character value is negative or positive. If a conversion results in the value
-30, for example, the compiler would set it to the positive value +30.
The reason for this is that getchar () can be used for all possible inputs.
In addition, a separate value for the EO I (End Of Input) is necessary.
Character and integer values can be combined arbitrarily and used together
in arithmetic expressions. This is not possible in BASIC. This aspect of C
results in great flexibility, especially when programming character
transformations.
86
Abacus Software Atari ST BASIC to C
double double
long long
unsigned unsigned
If none of the above is true, the compiler converts all operands to type
integer.
87
Abacus Software Atari ST BASIC to C
main ()
{
char character;
int number;
character = I A I ;
number = 22;
number = character;
character = number;
}
The conversions shown in this section offer you a great new programming
flexibility which BASIC did not offer. All of these possibilities can seem a
little confusing at ftrst, but it does not take much practice to become familiar
with all of the conversion functions .
As we have already made clear, all variables must be declared and thereby
given a specific variable type before they are used in a program. The
declaration usually takes place in the header of a function. But it also may
occur anywhere else in the function. The important thing is that the
declaration take place before the variable is used.
88
Abacus Software Atari ST BASIC to C
The declarations in the previous sections and chapters were kept as simple
as possible. They generally looked something like this:
main ()
{
int a;
int X;
long y;
float b;
char c;
... the rest of the program ...
}
main ()
{
int a, b, c, d, e;
int X value, y value;
float-symbol 1
symbol_i;
This sequence is shorter and more compact than the previous example.
main ()
{
int number;
number = 123
89
Abacus Sortware Atari ST BASIC to C
It is also possible to put the declaration and definition together. This has the
following syntax:
main ()
{
int number 123;
Which version you choose depends upon whether you prefer a compact
version like that immediately above, or a more readable version with the
value assignment closer to the context of the variable's actual use.
This is all we will say about variable declarations for now. We will look at
the declaration of single and multi-dimensional arrays later in the chapter.
Until now, we have used only local variables, i.e., variables declared inside
a function (usually main).
Here you must decide if you want a variable to be global (applicable to all
functions) or if you want it to be local to one function.
Local variables, also called automatic variables, are declared in the function
in which they will be used. They are valid only within this function. They
are different from variables in BASIC, which are always valid in every
function. BASIC has only global variables, which apply to the entire
program, including subroutines.
These global variables in C are declared before a function, in the same place
that symbolic constants are declared.
90
Abacus Software Atari ST BASIC to C
To make the difference between the two variable types clear, take a look at
the following program. The program contains both automatic and global
variables, as well as symbolic constants:
5.7 Arrays
10 DIM A%(10)
int c[10];
91
Abacus Software Atari ST BASIC to C
We declare arrays in the same way we declare all other data types: first the
variable type, then the name. All data types in C can be declared as arrays.
The size of the array is enclosed in square brackets as a numeric index.
After the declaration, you must remember to assign a value to each before
using it.
This assignment can be done using a for loop, as in this example program:
main ()
{
int a[10];
int i;
for (i = 0; i <= 10; i i + 1)
a[i] = 0;
In the initialization condition of the for loop, it becomes clear that arrays in
C begin with zero rather than one, as in BASIC.
A C array with five elements:
int a[S]
a[O]
a[l]
a[2]
a[3]
to a[4]
Arrays in C are handled in much the same way as they are in BASIC. For
example, if you want to assign the number 12 to the second element of an
a [5] array (which is a [ 1 ] ), then you simply write:
a[l] = 12;
92
Abacus Software Atari ST BASIC to C
Value assignment can be done directly in the initialization, just like the
instruction:
int c = 12;
in t a [ 7] = [1, 6, 8, 2, 7, 1, 15];
The compiler performs this assignment from left to right. It assigns a value
from inside the brackets to each element in the array a.
The empty square brackets mean that the size of the array corresponds
exactly to the number of assigned elements.
In effect, the compiler counts these elements and places this number inside
the brackets.
Once more we would like to stress that this assignment technique does not
work with local arrays.
This program assigns the global array arr with the values from ten to zero.
These values are then printed out in a for loop in main.
93
Abacus Software Atari ST BASIC to C
10 DIM A%(5,5)
int a [5 J [5 J ;
Don't forget that again you must assign a value to each element before use.
With local variables, the best way to do this is with a for loop. With global
or static variables, the following initialization technique will declare the
array and ftIl it with numbers simultaneously:
5.7.2 Strings
For the sake of thoroughness we would like to mention some facts once
again about strings. Precisely defined, strings are nothing more than
one-dimensional arrays of characters. All information necessary for you to
use strings has already been covered.
"A"
'A'
94
Abacus Software Atari ST BASIC to C
This is because the string contains the null character in addition to the letter
A, to mark the end of the string. Thus the string consists of two characters:
the 'A' and the '\ 0 ' . The character consists only of the 'A'.
But this is possible only with global or static variables. The string
instruction %s in printf causes the global string to be printed.
main ()
{
char *string char;
string char =
"I am a string";
printf("%s\n", string_char);
gemdos(Oxl) ;
}
The next chapter contains a detailed explanation of how this works and why
it must be done this way.
95
Chapter 6
( C Pointers
J
Abacus Software Atari ST BASIC to C
C Pointers
Pointers and arrays are very closely related in C. All operations we've
carried out so far with arrays can also be done with pointers. Before we go
into exactly what this relation is, it would be a good idea to find out what
pointers really are-and what they can do.
But pointers are one of the primary features of C. You can't really tap the
potential of C without first mastering pointers.
Pointers let you work directly with memory addresses. It looks like this in a
program:
99
Abacus Sortware Atari ST BASIC to C
The * character preceding a pointer returns the ~ that the pointer points
to, instead of the value of the pointer itself (an address). This may seem
somewhat complicated, but it is really quite simple.
Assume that addr value1 is a pointer to the variable valuel. With the
assignment: -
value2 = *addr_value1;
For example, if the value. assigned to val u e 1 is 15, then the pointer
addr value1 contains the address of where this value is stored in the
ST.
value2 = *addr_value1;
main ()
{
int value1, value2, *addr_value1;
value1 = 15;
addr value1 = &value1;
value2 = *addr value1;
}
100
Abacus Software Atari ST BASIC to C
The preceding program has the same result as the following program, which
does not use a pointer:
main ()
{
int valuel, value2;
valuel 15;
value2 = valuel;
}
addr_valuel = &valuel;
value2 = *addr_valuel;
value2 = valuel;
Note: the prerelease version of A1cyon C does not handle the assignment of
pointer addresses and pointer contents correctly. The statement:
&value2 = *addr_valuel;
In summary:
101
Abacus Software Atari ST BASIC to C
Now that you know what pointers are and what they do, you need to know
the best ways to use them in programs. At times you'll find that pointers are
the only way to perform certain calculations. You will probably not run into
cases like these when you are first learning C, however.
Pointers are among the major strengths of C and are generally necessary for
tight, elegant programs. At the same time, pointers must be used with
extreme care.
Improper use of pointers can hopelessly mangle a program, and break: all
the rules for optimal, well-structured programming. The reason for this is
largely because it is easy to insert a pointer that points just "anywhere."
As we said at the beginning of this chapter, pointers and arrays are very
closely related. We have demonstrated this through the use of strings.
String variables must be used as pointers of the form:
char *string;
string = "Hello, how are you?";
We will explain this and many other details about arrays and pointers on the
following pages.
102
Abacus Software Atari ST BASIC to C
float x[15];
float *pointer;
The instruction:
pointer = &x[O];
As we have already found out, we can find the contents of the address to
which a pointer points with the following command:
value = *pointer
If *pointer contains the value of the first element of the x array (x [0]),
then we can defme the value:
*(pointer + 1)
103
Abacus Software Atari ST BASIC to C
pointer = &x[O];
can also be written as follows:
pointer = X;
The address of the first element of an array thus has the same value as the
name of the array. Why?
X [i]
*(x+i);
The two expressions for the i th element of the X array are completely
equivalent and interchangable. This means that:
X [i] and (X + i)
This equivalence also applies to the use of the address operator (&):
(X + i) and &x[i]
104
Abacus Software Atari ST BASIC to C
This is also true for the pointer. It can be used with the square brackets and
an array index as a replacement for the original array variable (provided the
two are equal):
pointer[i]
or in the form:
* (pointer + i)
All of these explanations were demonstrated with examples using
one-dimensional arrays, but everything said here applies without exception
to multi-dimensional arrays as well.
Make sure that you really understand all of the details in this section. If not,
then carefully go through the section again. You should also try out the
examples in some programs of your own.
You will need this information when we leave numeric arrays and look at
character arrays again. Everything we have said about numeric arrays and
pointers applies to all other data types, including characters.
105
Abacus Software Atari ST BASIC to C
The compiler terminates the array with a null character ( , \ 0 ' ). C has no
special functions for managing strings as such, because strings are simply
treated as character arrays.
main ()
{
char *string;
string = "ATARI ST";
printf("%s\n", string);
gemdos (Oxl) ;
}
The expression:
char *string;
char string[];
In this example it becomes clear that the strings in our previous programs
were one-dimensional arrays.
106
Abacus Sortware Atari ST BASIC to C
The statements:
char *string;
and:
char string[];
set up an array of undetermined length. This array will later be filled with
elements. This is done as follows:
At first this may seem strange to BASIC programmers. For now, we will
consider it enough to know what pointers are and how they are used. But
rest assured that you will encounter pointers again and again in this book.
Pointers are also important for working with functions. You will learn more
about this in the chapter specifically devoted to functions in C.
107
Chapter 7
~
"
~
)
Abacus Software Atari ST BASIC to C
If you worked through the previous chapter thoroughly, you should be able
to go through this chapter with somewhat less trouble. The elementary
arithmetic operations are practically the same as those you know from
BASIC. C, however, has a whole set of operators which we must go
through in detail yet. C possesses some very powerful arithmetic functions
which are not found in BASIC at all. We covered a few of these special
functions and differences from BASIC briefly in the introductory chapter.
On the following pages, we will explain these and other new arithmetic
properties of C, in detailed comparison to BASIC.
10 PRINT 1+5/7
the symbols + and / are the operators. They work with the constants 1,5,
and 7. Operators are used in C the same way they are used in BASIC.
Look over the following list comparing BASIC and C arithmetic commands:
111
Abacus Software Atari ST BASIC to C
Now that you have seen some of the similarities between the arithmetic
operations of BASIC and C, let's look at some of the differences.
10 A=A+1
a = a + 1;
Another form is possible in C:
a += 1;
This operator combination is possible with all of the operators we have seen
so far:
+ * /
and also with the following new C operators, which we will explore in
detail later in this chapter:
% » « &
value 1 *= 20;
112
Abacus Software Atari ST BASIC to C
is completely equivalent to
Note the parentheses around EXP 1 and EXP 2 in the above expression.
These are set internally by the computer and ensure that:
z /= x + 2;
really corresponds to:
z = z / (x+2);
and not:
z = z / x + 2;
where z is divided by x and the result divided by 2, rather than the intended
result of z being divided by (x + 2).
You will soon come to like this capability which C offers you. It lets you
write expressions more compactly and efficiently.
Using the new assignment operator, you can write it better as:
arrwt_le2[zz[aa]] *= 22;
One advantage of this capability is that you can avoid many unnecessary
errors by not having to repeat a complex variable on both sides of the equal
sign.
113
Abacus Software Atari ST BASIC to C
Also, assignments are much easier to understand, especially for other users
of your program. You don't have to spend a lot of time making sure that the
expression on the right of the equals sign is identical to the expression on
the left
remainder = a % b;
114
Abacus Software Atari ST BASIC to C
x = x + 1;
x += 1;
We will cover another, even more compact formulation using the increment
operator.
++x;
--x;
x = x - 1;
The increment and decrement operators are rather unusual in that they can be
used both before and after the operand. Both the prefix notation:
--x;
X--i
are possible.
115
Abacus Software Atari ST BASIC to C
This may sound a little dry but it can be easily demonstrated with an
example:
y = ++x;
the incrementation takes place before the expression is evaluated and the
variable y is assigned the value of 2 + 1, or 3. The variable x also now has
the value of 3.
y = x++;
the variable y is assigned the value 2. After the assignment the value of x is
incremented to 3.
For further clarification, let's look at the BASIC versions of these two
notations:
and
116
Abacus Sortware Atari ST BASIC to C
All of these BASIC operators are exactly the same in C. Here you should
not have any problems changing over to C.
= ........ equal to
and
-- ........ equal to
and
!= . . . . . . . . not equal to
It will be easy for you with your BASIC experience to confuse the
assignment operator, =, and the equivalence operator, ==.
Now we'll briefly show you the most important uses of the comparison and
equivalence operators. For the most part, they are used with control
structures. We'll explain these in the next chapter. The most common
control structure is the if statement.
117
Abacus Software Atari ST BASIC to C
10 A=2
20 IF A=2 THEN PRINT "OK!"
In C, the above becomes
main ()
{
int a = 2;
if (a == 2)
{
printf ("OK! \n") ;
}
gemdos (Ox1) ;
}
#include "stdio.h"
main ()
{
int a = 12;
while (a <= 11)
{
puts("All clear!");
}
gemdos(Ox1);
}
main ()
{
int X;
for(x = 0; X <= 20; ++x);
printf("%d\n", x);
gemdos (Ox1) ;
}
118
Abacus Software Atari ST BASIC to C
The loop counts from zero through twenty, using the comparison operator
"less than or equal to", <=.
<
<=
>=
>
all have the same execution priority. Comparing them to the equivalence
operators == and ! = , we find that the comparison operators have the
higher priority, while the equivalence operators share the same priority.
The logical operations in BASIC are AND and OR. Their meanings are
self-explanatory. The corresponding C operators are less obvious to the
BASIC programmer.
They are:
and
II ......... or
In spite of the different forms of the C expressions, they are used in exactly
the same way.
119
Abacus Software Atari ST BASIC to C
is translated to Cas:
main ()
{
int a = 1;
int b = 2;
if (a == 1 && b == 2 I I b == 1)
printf("Condition met!\n");
gemdos (Ox1) ;
}
As you can see, the makeup of the expressions is identical. You should
have no difficulty adapting from BASIC here.
This operator is similar to the BASIC bit operator NOT. C has two different
negation operators. The first is the logical negation operator! The second is
the bitwise negation operator - . When dealing with a logical expression,
such as one involving a comparison, the logical operator! should be used.
It changes a zero value to a one and a non-zero value to a zero. There is no
direct BASIC counterpart to the logical negation operator in C.
main ()
{
int value = 0;
if (value == 0)
printf("ZERO!!!\n");
gemctos (Ox1) ;
}
120
Abacus Software Atari ST BASIC to C
main ()
{
int value = 0;
if ( ! value)
printf("ZERO!!!\n");
gemdos(Oxl);
}
if (value == 0)
if ( ! value)
If this were the case, the command following the if condition would not be
executed. You could quickly demonstrate this by changing the assignment
statement in our example program to:
int value = 2;
if (value == 0)
if (!value)
The logical negation operator can also be used in conjunction with the other
logical operators to produce NAND, NOR, and other functions.
121
Abacus Software Atari ST BASIC to C
a = 15;
b = 15;
c = 15;
d = 15;
or alternatively:
d = 15;
c = d;
b C;
a = b;
All of the variables are assigned the same value by this combined
assignment statement.
We have now covered all of the important arithmetic operators. Now let's
look at the bit operators in the next section.
122
Abacus Software Atari ST BASIC to C
All of these bit operators are used in the same manner as the normal ones
which we have already explained in the sections on arithmetic. They may
not, however, be used with float or double variables.
A chart follows, showing a few ways in which these operators can be used
in arithmetic expressions:
We will now leave our brief introduction to bit operators and their
applications. This book was conceived for BASIC programmers and other
newcomers to C. Manipulation of bits is a theme you will not need until you
want to try your hand at advanced systems programming. A comprehensive
overview of this specialized aspect of C would really accomplish nothing
other than to scare the average BASIC programmer.
123
Abacus Software Atari ST BASIC to C
You can also try out a few of these operations on your own, even if you are
a beginner. But in practice you'll find you need these operations only for
specialized systems programming for which detailed system knowledge is
also necessary.
In summary, we can state that any bit operation which is carried out in
BASIC with the AND and OR operators is carried out using the bitwise
operators found on the previous pages.
10 X = 7 AND 1
is written in Cas:
x = 7 & 1;
124
Chapter 8
( Control Structures in C )
Abacus Sortware Atari ST BASIC to C
Control Structures in C
Control structures are the core of every programming language. They make
it possible to specify which operations the computer should execute at a
given time. In essence, they are used to determine the order in which actions
are carried out
IF . . . THEN
FOR ••• NEXT
ON .•. GOTO
and
WHILE . . . WEND
All of these BASIC structures are found in C, although some of the syntax
is a little different. In addition, you have a whole series of powerful
possibilities for the control of program execution which are not available in
BASIC.
127
Abacus Software Atari ST BASIC to C
10 X=15
20 Y=X
30 IF X=Y THEN [Execute the following commands]
is formulated in Cas:
main ()
{
int x, y;
x = 15;
Y = x;
if (x == y)
{
then execute the commands
here inside the brackets;
}
}
is expressed as follows in C:
if (expression)
[execute commands;]
128
Abacus Software Atari ST BASIC to C
We can shorten our statements with this background knowledge about the
logic of evaluation in the if statement. We already covered one of these
abbreviations, which used the negation operator (!) in the chapter on
artithmetic.
Let's review:
if(value == 0)
can be written with the use of the negation operator in a more compact form
as:
if ( ! value)
Another clear simplification involves the use of:
I
if (value)
instead of:
if{value != 0)
If this variable val ue does not equal zero, the condition is viewed to be
true, without having to use the ! =0 test, and the statements following the
if statement are executed.
<
>
<=
>=
as well as:
!=
129
Abacus Software Atari ST BASIC to C
=<
and:
=>
&&
II
An example: The BASIC line:
is translated in C to:
As the assignment and equality operators in BASIC use the same character,
you must pay close attention when translating an algorithm to C.
130
Abacus Software Atari ST BASIC to C
10 INPUT Y%
20 IF Y%=15 THEN PRINT "THIS IS THE ANSWER":
PRINT "THE NUMBER 15 IS CORRECT!"
we get:
main ()
{
int y;
scanf("%d", &y);
if (y == 15)
{
printf("This is the answer\n");
printf("The number 15 is correct!\n") ;
gemdos (Ox1) ;
With this example you see once again that if more than one statement is to
be executed, they must all be enclosed in curly braces. The braces may be
left off if only one statement follows the if statement.
if(a != 4)
if (b == 12)
if (x > 5)
printf("All conditions fulfilled!");
131
Abacus Sortware Atari ST BASIC to C
Let's say that you want to adapt our previous BASIC example to C:
10 INPUT Y%
20 IF Y%=15 THEN PRINT "THAT'S THE ANSWER!"
30 END
The main difference is END (line 30). Now for the C translation:
main ()
{
int y;
scanf("%d", &y);
if (y == 15)
printf("That's the answer!\n");
exit(O);
}
You are already familiar with the program from the previous pages and it
needs no further explanation. It is almost an exact duplicate of the previous
C program.
Until now, however, we have not seen the function exit () , which is
called in the statement:
exit(O);
The argument we use is not important for this application. The argument, in
this case zero (0), is passed backed to the function which called ex i t ( ) .
In our example this is passed back to main () .
10 INPUT Y$
20 IF Y$="STOP" THEN END
25 REM
30 PRINT "LET'S KEEP GOING ... "
132
Abacus Software Atari ST BASIC to C
main ()
{
char *y;
scanf("%s", y);
if (y == "s t op " )
exit(O);
printf("Continuing ... \n");
gemdos (Oxl) ;
}
The exi t (0) call is quite important in this program. It ends the program
just like BASIC END instruction and ensures that the pr int f command
which prints "Continuing ... " is not executed if you've told the program to
stop.
In the first C program in this section, the exi t () statement was not
needed. The program would have ended automatically because there were
no additional commands. In the program above, however, we needed it to
accomplish our purpose. This exit command is very useful in conjunction
with goto statements. More about this later in the chapter.
The Aleyon C for the Atari ST also offers another similar function. Its
syntax is
abort(O);
This function exits the current program and generates an error.
Every normal if statement test can also have a e 1 s e part added. Some
versions of BASIC allow the following program which contains an ELSE
statement.
133
Abacus Software Atari ST BASIC to C
10 INPUT A%
20 IF A%<20 THEN PRINT A%*A% ELSE PRINT "THE NORMAL
VALUE IS:";A%
main ()
{
int a;
scanf("%d", &a);
if (a < 20)
printf("%d\n", a * a);
else
{
printf("The normal value is: ");
printf("%d\n", a);
}
gemdos (Oxl) ;
}
if (condition fulfilled)
{
execute command block 1
}
else
{
execute command block 2
}
134
Abacus Software Atari ST BASIC to C
if(a -- 2)
if(b != 15)
a = a * 2;
else
a = a * 3;
Here we have to figure out which if statement the else statement belongs
to, the first or the second. An else statement always applies to the if
immediately preceeding it So in this case the else statement belongs to the
second if statement, if (b ! = 15).
H the e 1 s e is supposed to belong to the first if, you have to indicate this
by adding braces. In our example, this change would look like this:
if(a == 2) if(a == 2)
{
if(b != 15) if(b != 15)
a = a * 2; a = a * 2;
else else
a = a * 3; a = a * 3;
if(condition 1 fulfilled)
execute command block 1
else if(condition 2 fulfilled)
execute command block 2
135
Abacus Software Atari ST BASIC to C
The conditions are evaluated in order and when one is met the
corresponding block of commands is executed and the search through the
else-if chain is terminated.
else
execute command block n
The last statement is often used because it handles the situation when none
of the conditions are fulfilled. It can recognize errors or illegal input and
take care of the trouble before it can cause problems later in the program.
136
Abacus Software Atari ST BASIC to C
The fIrst part in our example, x = 1;, detennines the initial value of the
loop. This part could be translated to English as "Start the loop with the
x-value of 1." This part corresponds to the BASIC FOR X=1. After that
comes x <= 20, comparable with TO 20 in BASIC, which defInes the
end of the interval during which the loop is repeated. The third part, x = x
+ 2, determines the step size and is roughly equivalent to the BASIC STEP
+2.
x = x + 1
or more compactly as
++x;
If you leave the three parts-the initial value, the end value, and the
increment size-{)ut of a for loop, the result is an infinite loop and it looks
like this:
137
Abacus Software Atari ST BASIC to C
for(ii)
{
commands to be repeated endlessly
}
The reason for the infinite repetition of the commands is that the compiler
interperets the middle parameter (the end interval of the loop) as the test of a
condition. In other words, the result is checked only to see if it is true or
false. It makes no difference to the compiler what condition is used for the
middle parameter.
main ()
{
for(;;)
printf("%c", 'H');
}
Here, however, you must make sure that there is a difference between the
lower and upper bounds.
138
Abacus Software Atari ST BASIC to C
Since only the middle statement of the loop declaration matters here, the
following program also causes an infinite loop.
iinclude "stdio.h"
#define putchar(c) putc(c,stdout)
main ()
{
char y;
for (y = 'H';;)
putchar(y);
}
This example also prints the letter H on the screen repeatedly, but the
variable is assigned right in the for loop this time. The middle parameter is
still empty, however, so the compiler still considers it to be true.
For this reason, the following program does not result in an infinite loop:
main ()
{
int a;
for (a = 1; a < 20; )
{
printf("%d\n", a * a);
a++;
}
gemdos (Ox1) ;
}
10 FOR A=l TO 20
20 PRINT A*A
30 NEXT A
but much more like the following version in which the incrementation also
takes place within the loop:
139
Abacus Sortware Atari ST BASIC to C
Infinite loops are not often used in BASIC programs (not on purpose,
anyway), but they more common in C because of the availability of the
goto and break statements.
This special C operator is most often used in conjunction with the for
statement, but it can be used in other applications as well. Two expressions
separated by a comma are evaluated from left to right. This means that the
data type and value of the result of one statement are automatically the data
type and value of the operand to the right of the comma.
main ()
{
int a, C;
for (a = 1, c = 15; c < 30; a--, c++)
printf("%d n%d\n", a, c);
gemdos (Ox1) ;
}
As you can see in this example, the flexibility of the for loop can be greatly
increased using the comma operator. It can be used in both the initialization
and in the incrementation sections of the loop declaration.
The loop declaration:
140
Abacus Software Atari ST BASIC to C
a = 1, c = 15;
a--, c++
The increment and decrement instructions joined together by the comma are
executed at the same time.
Just as in BASIC, C for loops can be nested within each other. A BASIC
example is the program:
10 FOR A%=l TO 50
20 FOR B%=20 TO 1 STEP -1
30 PRINT A%, B%
40 NEXT B%
50 NEXT A%
main ()
{
int a, b;
for (a = 1; a <= 50; ++a)
for(b = 20; b >= 1; --b)
printf("%d %d\n", a, b);
gemdos (Ox1) ;
}
The curly braces can be omitted here because the for loop consists of just
one line.
141
Abacus Software Atari ST BASIC to C
10 FOR A%=1 TO 50
20 FOR B%=20 TO 1 STEP -1
30 PRINT A%, B%
40 PRINT "X"2 VALUE Y"2 VALUE"
50 PRINT A%*A%, B%*B%
60 NEXT B%
70 NEXT A%
In C, the two new PRINT instructions are simply added to the second loop
by making a statement block containing them and the original printf call.
main ()
{
int a, b;
for (a = 1; a <= 50; ++a)
for(b = 20; b >= 1; --b)
{
printf("%d %d\n", a, b);
printf("x"2 value y"2 value\n");
printf("%d %d\n", a * a, b * b);
}
gemdos(Oxl);
}
You must also use these brackets if you want to call additional functions
between the loops. A corresponding example of our previous BASIC
program reads:
10 FOR A%=1 TO 50
20 FOR B%=20 TO 1 STEP -1
30 PRINT A%, B%
40 PRINT "X"2 VALUE y"2 VALUE"
50 PRINT A%*A%, B%*B%
60 NEXT B%
70 PRINT "OUTER LOOP"
80 NEXT A%
142
Abacus Software Atari ST BASIC to C
main ()
{
int a, b;
for (a = 1; a <= 50; ++a)
{
for(b = 20; b >= 1; --b)
{
printf("%d %d\n", a, b);
printf("x A2 value yA2 value\n");
printf("%d %d\n", a * a, b * b);
}
printf("Outer loop\n");
}
gemdos (Ox1) ;
}
{
printf("%d %d\n", a, b);
printf("x A2 value yA2 value\n");
printf("%d %d\n", a * a, b * b);
}
is repeated twenty times via the second for statement, until the variable b is
equal to one. The outer loop is then executed.
printf("Outer loop\n");
++X;
should be used instead of the old form:
143
Abacus Software Atari ST BASIC to C
x = x + 1;
with which we are familiar from BASIC.
--x;
which should generally be used instead of:
x = x - 1;
Of course this applies only to increment/decrement values of one. The
expression for an increment size of +2, for example, must be written like
this:
x = x + 2;
or like this:
x += 2;
144
Abacus Software Atari ST BASIC to C
Now that we have covered the more common for loops, its time to tum to
a discussion of while loops. In the following examples, it must be noted
that not all versions of BASIC support while loops. The ST BASIC does
support them and the construction used is standard in Microsoft BASIC, so
we will include examples of while loops in BASIC.
Don't worry if you've never used while loops before. The syntax is easy
to understand and it is also easy to see where you might want to use them.
Let's take the following Microsoft BASIC program as an example:
As you can see, the WHILE construction forms a block beginning with the
WHILE statement itself and ending with WEND, which is short for "WHILE
END".
The commands inside this block are repeated for as long as the WH I LE
condition, in our case,
A%<10
is true. The command can be read "While the value of the variable A is less
than 10, do the following." The variable A, initialized to zero by the RUN
command, is incremented from 1 to 10, and each value is printed on the
screen.
145
Abacus Software Atari ST BASIC to C
How does this look in C? This is the program corresponding to our BASIC
example:
main ()
{
int a;
a = 0;
while (a < 10)
{
++a;
printf("%d\n", a);
}
gemdos (Ox1) ;
The syntax of the while statement in C is almost exactly the same as that
of the BASIC WHILE command:
Again, the statements in the command block are executed "so long as the
value of the variable a is less than 10." But make sure that the variables
used in the loop are declared and given values before the actual while
statement. This is not necessary in BASIC because the variable a is
automatically set to zero by the RUN command.
int a;
a = 0;
are necessary. They can both be done in one statement, as we have
mentioned before, like this:
int a = 0;
Note also that the incrementation, which in our example is ++a, must
always be specified explicitly within the loop.
146
Abacus Software Atari ST BASIC to C
You can arbitrarily combine these two types of loops in both BASIC and C.
The following program shows how we might do this in BASIC:
10 WHILE A%<20
20 A%=A%+l
30 PRINT "PASS NUMBER";A%
40 ,
50 FOR B%=l TO 15
60 PRINT B%;
70 NEXT B%
80 WEND
main ()
{
int a = 0;
int b;
while (a < 20)
{
++a;
for(b = 1; b <= 15; ++b);
printf("%d\n", b);
}
gemdos (Ox1) ;
}
Both of the programs fill twenty screen lines with the numbers from one to
futeen.
This example shows you how simply the two types of loop can be
combined in whatever ways you like.
147
Abacus Software Atari ST BASIC to C
10 WHILE A%<8
20 WHILE B%<2
30 B%=B%+l
40 PRINT A%, B%
50 WEND
55 '
60 B%=O
70 A%=A%+2
80 PRINT "OUTER LOOP"
90 WEND
Now the C version:
main ()
{
int a, b;
a = b = 0;
while(a < 8)
{
while (b < 2)
{
++b;
printf("%d %d\n", a, b);
}
b = 0;
a a + 2;
printf("Outer loop\n");
}
gemdos (Oxl) ;
}
148
Abacus Software Atari ST BASIC to C
The do-while loop is a special form of the normal while loop. With this
construction, the condition of the loop is checked at the end of the loop
instead of the beginning.
BASIC does not have the option of a do-while loop. It was therefore
simulated in this program using an infinite loop. In this loop, the variable a
"counts" from 1 to infinity.
The end of the loop is tested in the simulated do-while loop with the IF
line. This statement ends the program when the value of the variable B
reaches 100.
Now we come to the C version of the do-while loop. The above BASIC
program can be written quite simply as follows:
main ()
{
int a = 0;
do
{
++a;
printf("%d\n", a);
} while (a <= 100);
gemdos (Ox1) ;
}
Here the while condition is found at the end of the statement block which
was introduced with do. The do statements are repeated as long as the
while condition is true. When the while condition becomes false, the
compiler leaves the loop and continues with the program.
149
Abacus Software Atari ST BASIC to C
It is important to note that the commands within the loop are always
executed at least once even if the while condition is false to begin with.
Our BASIC version works only in the case where the program and the loop
are to be ended at the same time. If additional commands followed our C
loop, they would be executed, but because of the END statement, this is not
true in the BASIC loop.
This leads directly to our next C control structure, the break statement
main ()
{
int bi
for(b = 1 i i )
{
++b;
printf("%d\n", b);
}
gemdos(Oxl);
}
As we already know from the section on for loops, this program contains
an infinite loop. It counts from one on up using the variable b.
How do you get out of loops like this? If you have looked at the title of this
section, you might guess that the break statement will be of some help.
break is very easy to implement in our example.
150
Abacus Software Atari ST BASIC to C
main ()
{
int b;
for(b = 1 ;;)
{
++b;
printf("%d\n", b);
if (b == 100)
break;
}
printf("Loop broken\n");
gemdos (Ox1) ;
}
printf("LoOp broken\n");
is executed.
151
Abacus Software Atari ST BASIC to C
Here we see that the break statement is simulated by a GOTO jump in line
40 which does not end the program, as did the END command in the earlier
program. The endless loop is simply exited and the program continues in
line 60. This is very poor programming practice in BASIC, however.
The cont inue statement is the opposite of the break statement It causes
the next repetition of the current for, while or do-while loop to begin
immediately.
This means that if the compiler encounters the continue statement inside
a loop, the statements following it in the loop are not executed, but instead
the loop is started again from the beginning.
main ()
{
int a[5];
int i;
a[O] = 15;
a[l] -2;
a[2] 0;
a[3] 12;
a[4] -14;
for(i = 0; i <= 4; ++i)
{
if (a [i] <= 0)
{
printf("Value is negative!\n");
continue;
}
printf("Value is positive!\n");
}
gemdos (Ox!) ;
}
152
Abacus Software Atari ST BASIC to C
printf("Value is negative.\n");
The statement
continue;
printf("Value is positive.\n");
in our example, is then executed. It's not a good idea, after all, to first call a
number negative and then turn around right away and call it positive!
10 DIM A(5)
20 '
30 FOR 1=1 TO 5 STEP 1
40 IF A(I)<= 0 THEN PRINT "VALUE IS
NEGATIVE!":
NEXT A: REM "CONTINUE"
50 PRINT "VALUE IS POSITIVE!"
60 NEXT A
153
Abacus Software Atari ST BASIC to C
Even C offers a got 0 statement, and it is even more flexible than its
BASIC counterpart. In BASIC, a large part of the control structure is built
around GOTO commands. Frequent use of these statements can lead to
unreadable "spaghetti" code, however, in which it is virtually impossible for
someone reading the program to tell what is going on.
To prevent this from the start, we have not used any such goto statements
in our C programs. You will very seldom find a goto statement in a C
program, and even then only in isolated cases.
For situations where the circumstances demand the use of got 0 statements
in C, the following pages contain a complete description of this control
structure.
The ST's Alcyon C development system does not have this statement yet,
but the finished commercial version probably will.
10 A%=10
20 PRINT A%
30 A%=A%-l
40 IF A%>O THEN GOTO 20
154
Abacus Software Atari ST BASIC to C
main ()
{
int a = 10;
20:
printf("%d\n", a);
--a;
if(a > 0)
goto 20;
gemdos (Ox1) ;
}
Both programs are constructed the same way and both count down from ten
to one. As you can see, the goto statement in this example works just like
the BASIC GOTO statement. The command
goto 20;
20:
In C, the got 0 labels are seen as names and not as BASIC-like line
numbers. You could, in fact, replace the label 2 0 with a name if you like.
In the following program, the name IBeg in, short for "If Begin" has
replaced 20 as the beginning label of the loop. The program then looks like
this:
main ()
{
int a = 10;
IBegin:
printf("%d\n", a);
--a;
if(a > 0)
goto IBegin;
gemdos(Ox1);
}
155
Abacus Software Atari ST BASIC to C
This example also shows why got 0 jumps are extremely rare in C. Our
program can be written more effectively and compactly using a while
loop.
main ()
{
int a = 10;
while (a > 0)
{
printf("%d\n", a);
--a;
}
gemdos(Ox1);
}
Here it is clear that goto jumps can almost always be replaced by another
loop construction or by functions. Essentially, any program can be written
without goto statements.
In practice, it has been shown that the most common use of goto is to exit
several loops in one move. If, for example, you need to escape from a
deeply-nested loop structure, then goto is very helpful indeed.
You could use break, of course, but remember that break leaves only the
current loop. To escape a deep structure of nested loops, it is more effective
to use the goto jump than a long, complex series of interconnected break
statements.
In using got 0, it is important to note that the jump can take place only
within a function . This means that you cannot use goto to jump out of a
function or from one function to another.
156
Abacus Software Atari ST BASIC to C
8.8.1 Example
First the BASIC program, then the C version, which uses switch:
10 INPUT A
20 ON A GOTO 40, 50
30 PRINT "DEFAULT, VALUE I S NOT 1 OR 2": END
40 PRINT "A IS 1": END
50 PRINT "A IS 2": END
main ()
{
int a;
scanf(" %d", &a);
switch(a)
{
case 1:
printf("Value is l\n");
break;
case 2:
printf("Value is 2\n");
break;
default:
printf("Default, value is not 1 or 2\n");
gemdos (Oxl) ;
157
Abacus Software Atari ST BASIC to C
Both of these programs read in a number from the keyboard and then
determine if this number is 1, 2, or neither of these two.
switch (a) ;
The conditional statements which follow are then assembled into a statement
block inside curly braces.
case 1:
printf("Value is l\n");
If none of the case constants match the variable, then the statements after:
default:
158
Abacus Software Atari ST BAste to e
case conditions, by the way, do not have to follow in numeric order (1, 2,
... , default) as they do in BASIC. The following unordered sequence of 2,
3, 1, and default is also possible:
main ()
{
int a;
scanf("%d", &a);
switch(a)
{
case 2:
printf("Value is 2\n");
break;
case 3:
printf("Value is 3\n");
break;
case 1:
printf("Value is l\n");
break;
default:
printf("Value is not 2, 3, or l\n");
gemdos (Ox1) ;
159
Abacus Software Atari ST BASIC to C
main ()
{
char c;
c = 'h';
switch(c)
{
case 'y':
printf("Character y\n");
break;
case 'a':
printf("Character a\n");
break;
case 'h':
printf("Character h\n");
break;
}
gemdos(Oxl) ;
}
The only real difference between this s wit ch structure and the previous
ones is that the form of the case statements is
case 'character':
rather than
This can be done more efficiently using the ASCn values of the input (see
the chapter on screen input/output operations), but the program below
serves as a demonstration of this use of the switch structure.
160
Abacus Software Atari ST BASIC to C
main ()
{
char a;
a = 6;
switch (a)
{
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9':
printf("Character is a digit!\n");
break;
default:
printf("Character is a not a digit!\n");
gemdos (Oxl) ;
switch (x)
{
case a:
case b:
case c:
Execute commands when x matches a, b, or c
Take careful note of the use of break statement. Its role in the switch
structure is very important. If one case is found to be true, it doesn't usually
make sense to examine the rest of the cases. The break statement is used
here in order to avoid this wasteful procedure. Our previous examples are
all optimized using break.
161
Chapter 9
~
I
Common Mistakes of BASIC Programmers"
~
Abacus Software Atari ST BASIC to C
You have now reached a point where you should have a large part of C
mastered. Most of all, the relationships between BASIC and C should be
clear to you. What we have covered so far is a complete description of the
elementary elements of the C programming language.
Consider this chapter a quiz. First you will see a program containing one
mistake. Following it will be a complete explanation of this error.
Don't read the explanation right away if the answer does not come to you
immediately. Look carefully; many mistakes will not be apparent at fIrst.
9.1 Error # 1
main ()
{
int x;
x = 15;
print ("%d",x) ;
gemdos (Oxl) ;
Have you found the error yet? No? At first sight this program seems to be
completely in order. This is a typical mistake which can really be made only
by someone who has programmed in BASIC. Nobody learning C as his
fIrst programming language would make this error (except as a typo).
In case you still haven't noticed, the pr int () function is certainly familiar
from BASIC as the PRINT statement, but the actual name of the C function
is printf () and not print (). This type of mistake is especially
frustrating because it is so difficult to fInd.
165
Abacus Software Atari ST BASIC to C
9.2 Error # 2
main ()
{
int integer;
while(integer < 10)
{
printf("Value x ft 2 value\n");
printf("%d %d\n", integer, integer * integer);
++integer;
gemdos (Ox1) ;
This program uses a while loop to create a table of the squares of the
integers from one to ten. The mistake is again one typical of BASIC
programmers.
int integer;
there must be a value assignment before the start of the whi Ie loop:
integer = 0;
In BASIC, this is not necessary because the values of all variables are
automatically set to zero by the RUN command. In C, however, you must
never forget to set the initial value of every variable before it is used.
int integer = 0;
166
Abacus Software Atari ST BASIC to C
9.3 Error # 3
main ()
{
int i nteger;
for(integer = 0; integer <= 10; ++integer);
{
printf("Value xA2 value\n");
printf("%d %d\ n", i nteger, integer * integer);
gemdos (Ox1) ;
This program corresponds exactly to the previous one, except that the loop
is created using for instead of while .
Have you found the mistake yet? You might guess that there would be a
problem because the variable integer is not initialized before the loop. It
is initialized inside the loop, however, so this is not necessary.
167
Abacus Software Atari ST BASIC to C
9.4 Error #4
main ()
{
int value;
scanf("%d", &value);
if(value = 15)
printf("15 is the answer ! \n);
else
printf("That's not it!\n");
gemdos(Oxl);
This one may also have been difficult for you. It really looks completely
nonnal to a BASIC programmer.
9.5 Error #5
main ()
{
int value_I, value 2;
value_l = 15;
Here the variables value 1 and value 2 are declared, assigned values,
and multiplied together. Their product is then printed on the screen.
168
Abacus Software Atari ST BASIC to C
The error lies in the value assignments. Because value 2 was declared as
an integer, just like val ue _1, it cannot be assigned the floating-point value
3.5.
This program would run on most compilers, but with the unwanted side
effect that value 2 would be assigned the integer value of 3.5, which is
3. -
If, however, you want the value 3.5 to be used, you must first declare
value_2 as a float variable. Next, the printf call must be changed.
Instead of %ct, you must write %f for the number to be printed as
floating-point.
9.6 Error #6
main ()
{
a = 15i
printf("%d\n", a)i
gemdos (Ox1) i
Here we see another typical BASIC error. At first glance, the program looks
correct. There are no errors in the printf call and the braces around the
function main () are placed correctly. The value assignment of the variable
a is also in order.
int a;
or
f l oat a;
169
Abacus Software Atari ST BASIC to C
9.7 Error #7
main ()
{
printf("%f\n", 1 / 3);
gemdos(Ox1) ;
If you don't believe that the above program contains an error, just run it
through your C compiler and you will receive the (incorrect!) output
0 . 000000
The error can only lie in the pr int f call. This should print out the fraction
113. The output format is also correctly set at %f.
ma i n ()
{
printf("%f\n", 1.0 / 3.0);
gemdos (Ox1) ;
170
Abacus Software Atari ST BASIC to C
9.8 Error #8
main ()
int a, b, c, d;
scanf("%d", &a);
b = a + 6;
c = b * 4;
d = b - c;
printf("%d %d %d %d\n", a, b, c, d);
gemdos (Ox!) ;
Many of you probably noticed this error right away. The problem with this
error is that the compiler will generate several different error messages,
none of which give the specific reason for the error.
In this example, the fIrst curly brace after the rna in () function declaration
is missing. In this short program, the mistake was easy to find. In larger
programs, however, it may be exceptionally diffIcult to fInd these errors due
to the misleading error messages.
When you think about it, a large program would not consist of a single
block of commands, but would instead have a complex series of them,
intermixed and nested within one another to the point where it would be
very easy to leave a brace out
When you suspect that you have left a brace off a block somewhere deep in
a confusing series of nested loops you'll have to decide yourself where you
should look, because the compiler is not going to give you very helpful
error messages.
171
Abacus Software Atari ST BASIC to C
9.9 Error #9
main ()
(
int loop;
for (loop = 1; loop =< 10; ++loop)
{
printf("%d %d\n", loop, loop * 2);
gemdos (Oxl) ;
Look more carefully at the for loop definition. The error is found in the
condition loop =< 10;. In a few BASIC versions, the comparison
operator =< is permissible, but not in C.
Just remember that the equals sign always comes last in the "less than or
equal to" and "greater than or equal to" operators, resulting in <= and >=.
main ()
{
int x;
scanf("%d", x);
printf("%d %d\n", x, x * x);
gemdos (Oxl) ;
172
Abacus Software Atari ST BASIC to C
If you didn't notice the error immediately, do you remember now? scanf
always needs a pointer to tell the computer where in memory it should place
the value it reads in.
The correct scan f call changes the integer variable to a pointer variable
with the address operator & and looks like this:
scanf("%d", &x);
main ()
{
int a, b, c, d;
a = b 15;
for(c = a, d = c * 2; a < 5; a++, d ++)
{
printf("%d\n", a);
c = a * 12;
b = c - a;
printf("%d %d\n", c, b);
gemdos (Ox1) ;
Don't let this program confuse you. The nature of this error is very simple.
It does not lie in the for statement, although this is extended with the
comma operator.
You will find the error immediately if you again look at the information
given on the brace structure in error number 8. To be precise, the bracket at
the end of the for loop has been left out. This must be inserted after the last
printf statement.
173
Abacus Software Atari ST BASIC to C
main ()
{
int a, di
float bi
char *Ci
scanf("%d %f Is", &a, &b, &C)i
for(d = Ii d < ai ++d)
printf("%s\n", C)i
gemdos(Oxl)i
This time the scanf call contains the error. If you have not yet found the
error, look more carefully at this statement. The string variable c has
already been declared as a pointer and therefore does not need the address
operator to make it one. The correct call is as follows:
main ()
{
char *stringi
string = "I I" i
printf(%s "Error", string)i
gemdos (Oxl) i
174
Abacus Software Atari ST BASIC to C
I I Error
on the screen.
In its present fonn, however, the program will not do it. This is because the
%s expression is inside the p r in t f call. This and all other data type
assignments for printing must always be inside the quotation marks.
main ()
{
printf("There is a future\n in programming\n
in C!\n");
gemdos (Oxl) ;
Although this looks strange, it runs without a problem. It prints three lines:
There is a future
in programming
in C!
The new line marker \n, which represents the end of a line, can be put
anywhere in a string, not just at the end of a line.
175
Abacus Software Atari ST BASIC to C
main ()
{
int X;
for(x = 10; X > 0; --x)
printf("%d\n", x)
gemdos (Ox1) ;
Have you found the error yet? If not, you will probably kick yourself when
you finally discover it
This is an error most often caused by haste, and every C programmer makes
it at some point, but BASIC programmers are especially prone to it
For the solution, look more carefully at the printf call in the for loop.
This line is simply missing its semicolon.
In BASIC, we would not have to use a statement separator here. You must
always remember that the semicolon must be used to separate individual
statements from one another. In that respect, it corresponds to the colon in
BASIC, but the semicolon must follow every statement in C (remember
that the printf call is really part of the for statement).
main ()
{
int x 10;
=
while (x > 0)
{
printf("The number is %d"\n,x);
--x;
gemdos(Ox1);
176
Abacus Software Atari ST BASIC to C
The error is in the printf call. The new-line control character "\n", like
all other control characters, must be inside the quotation marks.
This example also shows how to print out strings and numeric variables
together, using one call. This is more efficient than two separate pr int f
calls. Remember this structure because you will certainly use it often in your
programs.
main ()
{
int X;
scanf("%d\n", &x);
printf("%d %d\n", x, x*x*x);
gemdos(Oxl);
Here we have a logical error in the scan f input call. Take another look at
this statement.
This error can occur because scanf and printf are almost identical in
their syntax, and pr int f very often uses the new-line character \n. The
scanf function, however, has no reason to look for this character because
the new-line after the input is automatic.
scanf("%d", &x);
177
Abacus Software Atari ST BASIC to C
main ()
{
int a, h;
char *c;
a =
b = 15;
c =
"DIGITAL GEM";
printf("%d %s %d\n", a, b, c);
gemdos (Ox1) ;
178
Abacus Software Atari ST BASIC to C
main ()
{
int x, y;
scanf("%d", &x);
y = 14;
if (x <> y)
printf("The x-value is not equal to the
y-value!\n");
else
printf("The x-value is equal to the
y-value\n") ;
gemdos (Ox1) ;
The error here is very typical of BASIC programmers, but you have enough
C experience that you should find it right away.
if(x != y)
179
Chapter 10
( C Functions)
Abacus Software Atari ST BASIC to C
C Functions
Even though C does not require you to use functions, it is not good
programming style to put all of your commands in one procedure (that is, in
the main () function) as is often the case in BASIC. Instead, you should
divide your program into separate functions which are called from rna in ( ) .
You will soon get used to this new programming style. Forget your BASIC
programming structure. Your C programs will be much easier to read and
understand if you build them up out of individual functions . Also, it is
much less complicated to change a program that is divided into functions
than one which is just a mass of statements.
One of the primary advantages of functions is that you can use what are
called "standard functions ." Once created, these functions can be used in
any program.
This is the main reason that functions play such an important role in C.
Functions allow you to virtually write your own programming language.
The C language itself is really quite compact and has relatively few
commands. Functions, however, extend the language greatly and handle all
of the machine-dependent tasks such as input/output
The C compiler libraries on the Atari ST are really nothing more than
functions which you can access. To use GEM in your C programs, for
example, all you have to do is link the corresponding libraries to your
program. The libraries then provide a large supply of useful functions for
you to use in your programs.
Naturally this raises some questions: How are these functions constructed?
How are they included in programs? How are they called from the
programs?
We will answer these and other questions in the following pages, using
many BASIC and C examples.
183
Abacus Software Atari ST BASIC to C
main ()
This function represents the program head; and it is always the first function
called when the program is executed. The general procedure is then to call
all of the other functions from rna in () so that the program is not actually
located in this main function, but the operations take place in the individual
subroutines. The function main () is therefore used primarily to manage
and call the other functions.
main ()
{
printf("Hello, how are you?\n");
main () ;
184
Abacus Software Atari ST BASIC to C
main() ;
10 PRINT "BASIC"
20 GOSUB 1000
30
,
40 PRINT "FORTH"
50 GOSUB 1000
60
,
70 PRINT "LISP"
80 GOSUB 1000
90
,
100 PRINT "PROLOG"
110 GOSUB 1000
120 ,
130 PRINT "C"
140 GOSUB 1000
150 END
160
,
1000 REM SUBROUTINE "KEYSTOP"
1005
,
1010 PRINT "PRESS A KEY ... "
1020 GET A$
1030 IF A$="" THEN 1020
1035
,
1040 RETURN
185
Abacus Software Atari ST BASIC to C
This program prints the names of several programming languages, one after
the other. After each language, the program uses GOS UB to jump to the
subroutine KEYSTOP, in which the message:
appears on the screen and the computer waits for a keystroke. When a key
is pressed, the RETURN command restores control to the main program.
.include "stdio.h"
fdefine getchar() getc(stdin)
main ()
{
printf("BASIC\n");
keystop();
printf("FORTH\n");
keystop();
printf("LISP\n");
keystop();
printf ("PROLOG\n") ;
keystop () ;
printf("C\n");
keystop();
gemdos(Oxl);
keystop ()
{
int a;
printf("Press a key ... \n");
getch (a) ;
char bf[lOO);
int b = 0;
getch ()
{
return«b> 0) ? bf[--b) getchar());
186
Abacus Software Atari ST BASIC to C
In this program, you see the function keys top called from the main
program rna in () with the statement:
keystop();
The fIrst thing this function does is to defIne a local variable of type integer.
Next, the message:
is printed out and the program then uses the call getch (a) to wait for a
key to be pressed on the keyboard. The return of control to the calling
program is then automatic. In Digital C, however, ret urn must be
specifIed explicitly.
As you can see, there aren't too many differences between BASIC and C
routines. In C, a function is called simply using the function name, whereas
in BASIC, the line number of the fIrst command of the subroutine is used.
or, if your BASIC does not include the PAUSE n command, as follows:
187
Abacus Software Atari ST BASIC to C
keystop ()
{
int x;
for(x 1; x < 30000; ++x)
;
This pause routine, as well as the previous keystroke function, can be put to
use in your own programs.
main 0
{
MO;
gemdos (Oxl) ;
eO
{
putchar ( 'e ' ) ;
sO;
putchar('! ');
M()
(
putchar ('M') ;
e();
sO
{
printf("ss");
188
Abacus Software Atari ST BASIC to C
In this example, it becomes clear how functions in C can call each other.
This can also be done in BASIC. The above C program looks something
like this in BASIC:
10 GOSUB 100
20 END
30
,
100 PRINT "M" ;
110 GOSUB 200
120 RETURN
130 ,
200 PRINT "E";
210 GOSUB 300
220 PRINT " " ,. ,
230 RETURN
240 ,
300 PRINT "55";
310 RETURN
Have you figured out what these programs do? Consistent with the nature
of the programs and their function calls, the outputs of the C and BASIC
programs are:
Mess!
and
MESS!
respectively. In this example you can see how C functions can be called by
and nested within each another.
189
Abacus Software Atari ST BASIC to C
This case was shown in the examples on the previous pages. The function
keystop () , called from main () ,generates only a fixed time delay.
PAUSE n
command like the one already found in BASIC.
pause(n)i
int n;
{
int a;
for(a 1; a < n; ++a)
;
pause(10000) i
or
pause(40000);
or pause (n) with any other number. This makes the for loop longer or
shorter, corresponding exactly to the BASIC command.
190
Abacus Software Atari ST BASIC to C
Let's look at our new pa use (n) function more closely in an example
program:
main ()
{
printf("Hello, ");
pause(30000);
printf ("how");
pause(20000);
printf(" are you?\n");
gemdos (Ox1) ;
}
pause(n) ;
int n;
{
int a;
for (a 1; a < n; ++a)
We will assume here that the version of BASIC we are using does not
include the PAUSE n command and must therefore be written as follows:
191
Abacus Software Atari ST BASIC to C
In this case, the variable N represents the length of the pause, which
controls the FOR-NEXT loop in the subroutine starting at line 1000.
So far we have covered the format of functions, how they call each other,
and how parameters are passed.
If, however, you want the function to return a value to the calling function,
you must follow a procedure which is somewhat unusual compared to
BASIC.
Let's take the following program, which computes the cube of a number, as
an example:
10 INPUT x %
20 GOSUB 100
30 PRINT Y%
40 END
50
,
100 Y% = X% * X% * X%
110 RETURN
main ()
{
int x, y;
scanf("%d", &x);
y = cube (x) ;
printf ("The cube of X is %d\n", y);
gemdos (Ox1) ;
cube(z)
int z;
{
return(z * z * z);
192
Abacus Software Atari ST BASIC to C
The statement
y = cube(x);
assigns to y the exact value which appears between the parentheses in the
ret urn statement in cube. This is hard to get used to, especially for
BASIC programmers, but it offers advantages which will become obvious
by the end of the chapter.
For comparison, let me show you an example of how functions may not be
used:
main ()
{
int x, y;
scanf("%d", &x);
y = square(x);
printf("%d\n", y);
gemdos (Ox!) ;
square (q)
int q;
{
q = q * q;
}
The procedure changes only the value of a variable, but does not
permanently assign the new value to a memory address. To accomplish this,
you use the return statement as before.
193
Abacus Software Atari ST BASIC to C
10 INPUT X
20 GOSUB 100
30 PRINT Y
40 END
50 I
100 Y = X * X * X
110 RETURN
main ()
{
float x, y, cube();
scanf("%d", &x);
y = cube (x) ;
printf("The cube of X is %d\n", y);
gemdos (Ox1) ;
}
float cube(z)
float z;
{
return(z * z * z);
}
As you can see, the function name must be declared as flo a t at the
beginning of the function main () if it is to return a floating-point number.
float cube();
This variable type must then be declared in the function cube () . Again,
this is not necessary for integer values.
194
Abacus Software Atari ST BASIC to C
Notice that the function was no longer introduced with just the simple
function name
cube(z)
float cube(z)
You must therefore declare the variable type again before the function name.
In practice, however, you will find or actually use very few flo at
functions in C programs. Instead, most functions which do not return
integer values will be declared as "double" functions in order to take
advantage of the increased accuracy of this variable type.
10 INPUT A
20 INPUT B
30 GOSUB 1000
40 PRINT A;B
50 END
100 ,
1000 REM SWAP
1010 HI=A
1020 A=B
1030 B=HI
1040 RETURN
Here, the subroutine SWAP exchanges the values of the variables A and B.
Some versions of BASIC include a special SWAP command for this
purpose. This, if it is offered, corresponds exactly to the subroutine above.
A command like this is very useful, and is used in sorting routines, among
others.
195
Abacus Software Atari ST BASIC to C
main ()
{
int a, b;
scanf("%d %d", &a, &b);
swap (&a, &b);
printf("%d %d\n", a, b);
gemdos(Oxl);
}
swap (c, d)
int *c, *d;
{
int temp;
temp = *c;
*c *d;
*d = temp;
}
The only real difference is the declaration of pointers. You must, of course,
declare a11local variables within a function as usual.
First, let's look at the call to the swap function in the line
The variables a and b must always be preceded by the address operator &
because the values in the function s wa p () are to be changed using memory
addresses. The memory addresses of the variables are passed to swap via
&a and &b.
196
Abacus Software Atari ST BASIC to C
Inside the called function, the variables c and d must be declared as integer
pointers so that they can receive the contents of the pointers &a and &b from
main () . The values in the two pointer addresses are then exchanged. The
variable temp which is used for this purpose need not be a pointer.
The two altered variables are then returned to the function rna i n () as
integer pointers. The contents of the variables a and b are thus swapped.
In this example, we passed two parameters to a function and got two values
back as well. ret urn can pass back only one value. Only the use of
pointers allows us to return more than one value.
The non-standard pointer operations are the biggest fault of this compiler,
and certainly must be fixed before the commercial version can be considered
ready. On all other compilers, the pointer operators function as described
above.
197
Abacus Software Atari ST BASIC to C
*define cube(x) x * x * x
main ()
{
int x, Yi
scanf("%d", &X)i
Y = cube (x) i
printf("The cube of X is %d\n", Y);
gemdos (Oxl) ;
*define cube(x) x * x * x
is what is called a macro. Macros are quick and easy to write. Their biggest
advantages are their flexibility and uncomplicated structure.
cube(z)
int Z;
{
return(z * z * Z)i
As you can see, this function is larger and less efficient than the macro.
Because of this, macros are found quite often in C programs.
198
Abacus Software Atari ST BASIC to C
pr intfs (a) ;
gemdos(Oxl);
}
199
Chapter 11
( Structures)
Abacus Software Atari ST BASIC to C
Structures
Structures are not available in BASIC, but they are available in many other
programming languages. In Pascal, for example, this variable type is called
a record.
In the following pages, we will describe everything important for you to
know as a BASIC programmer-the syntax of structures and how they are
used in programs.
To reassure you, we would like to make something clear from the start. In
our opinion, structures are not all that important for BASIC programmers at
the beginning. As we have already mentioned, any C program can be
written without them, using only the customary variable types.
struct item
{
int quantity;
char *description;
float price;
};
203
Abacus Software Atari ST BASIC to C
The example, when written out, makes it clear why we have referred to
structures as a way of associating variables. The structure name item
applies to all of the names which are defined under it.
Let's stay with our item example. The form of the structure i tern is
determined through the above declaration. In other words, we have declared
that the first element of the structure represents the quantity, the second
the description, and the third the price. In a table, it looks like this:
item n o. 1
item n o .2
item no . 3
item no.n
The first line of the chart represents the form of the structure item, which
was determined by the previous structure declaration. As is shown in the
left column, this form can be used with an arbitrary number of items.
The number of items you want and exactly how they should be addressed as
variables, are determined in the structure variable declaration. If, for
example, only three items (no_l through no_3) are to be declared as
variables of the structure, then the following notation is necessary.
204
Abacus Software Atari ST BASIC to C
This table shows how the individual variables are addressed later in the
program:
Here you can see how the individual elements of the structure item are
accessed. The general form is
First you must give the structure variable name, in this case, no- 1, no- 2,
or no 3, followed by a period and the name of the element from the
structure declaration must be included. In our example, these elements are
quantity, description, and price.
Structure variables formulated in this manner can be used just like normal
variables. For example:
no_2.quantity 125;
or
!his short example program demonstrates how structure elements are used
m a program:
struct item
int quantity;
char *description ;
float price;
};
main ()
{
struct item no_1, no_2, no_3;
no_1.quantity = 125;
no_1.description = "ATARI 520ST ";
no_l.price = 699.0;
no_2.quantity = 15;
205
Abacus Software Atari ST BASIC to C
Two things are shown in the main () function of this program. First, we
once again show how structure variable are declared, and second, we show
how elements of structures are used in a program.
You can now use structures and structure variables in your programs
without problems. In this section, you will learn how to simplify working
with structure variables. In the previous example, the structure variable
names were labeled no_I, no_2, and no_3.
In practice, things are almost never done this way. The articles can be
addressed more efficiently using arrays.
The structure variable declaration in the main () function looks like this
with an array:
Arrays make it much easier to access structure variables from a large group
of them.
206
Abacus Software Atari ST BASIC to C
struct item
int quantity;
char *description
float price;
};
main ()
{
int n;
struct item no[3];
gemdos(Oxl);
In this example it becomes clear why nearly all structures are defined as
arrays.
207
Abacus Software Atari ST BASIC to C
The for loop, which prints out all of the elements of a structure, can be
used only with the help of arrays. This makes possible the generalized calls:
no [n] . number
no[n] . description
and
no [n] .price
Using arrays of structures also makes it easier to change the program later.
For example, if you want to change the number of items in our program
from 3 to 100, all you have to do is change the number in the declaration.
The declaration:
208
Chapter 12
( An Overview of C )
Abacus Software Atari ST BASIC to C
A C overview
12.1 Keywords in C
LOOP INSTRUCTIONS
for
do
while
DECISION INSTRUCTIONS
if
else
switch
case
default
JUMP INSTRUCTIONS
break
continue
goto
STORAGE CLASSES
auto
extern
static
211
Abacus Software Atari ST BASIC to C
DATA TYPES
int
short
long
unsigned
float
double
char
struct
OTHER EXPRESSIONS
return
exit
type
define
include
printf
scanf
These key words, especially important for those learning C, represent the
language's core vocabulary . You can see that this fundamental vocabulary is
considerably smaller than that of BASIC.
212
Abacus Software Atari ST BASIC to C
In this summary you will get one last look at the important language
elements and their syntax and how they are implemented in C programs.
Syntax.:
break;
Syntax:
case constant:
statement 1;
statement 2;
213
Abacus Software Atari ST BASIC to C
Syntax:
continue;
Syntax 1:
Syntax 2:
The macro name is defined and places the n parameters in the text
statement, which is substituted for name in the program. One example is
the macro
x = square(value_l * 2);
which is replaced with
214
Abacus Software Atari ST BASIC to C
Syntax:
default:
program expression;
Syntax:
do
{
statements
}
while (condition)
The program statements within the do loop are executed as long as the
condition in the while statement is true.
It should be noted that statements within the do loop are executed at least
once because the while condition is not checked until the end of the loop.
215
Abacus Software Atari ST BASIC to C
Syntax:
else
statement;
Syntax:
else if (condition)
statement;
Syntax:
The step size determines the change made in the loop variable each time
the loop is executed. The statement is repeated within the loop.
216
Abacus Software Atari ST BASIC to C
Syntax:
goto label;
The execution of the goto statement causes a direct jump to the position
within the program which is identified by
label: statement
Syntax:
if (condition)
statement;
If the condition is true, or logically unequal to zero, the statement will be
executed.
Syntax:
,.
This expression does absolutely nothing while the program is running. It
must often be used, however, to fill in the requirements of the specific
syntax of some statements (for example, in do, for, and while loops).
217
Abacus Software Atari ST BASIC to C
Syntax 1:
return;
return (expression);
Syntax:
struct name
{
variable declaration 1
variable declaration 2
variable declaration n
};
First, the structure variable name is declared with n variables. The variables
may be of any type. Before it can be used in a program, variable names
must be assigned the structure's form.
First the name of the structure is entered, followed by a period and the name
of the element declared within the structure.
218
Abacus Sortware Atari ST BASIC to C
Syntax:
switch (expression)
{
case constant 1:
statement 1;
statement 2;
break;
case constant 2:
statement 1;
statement 2;
break;
default:
219
Abacus Software Atari ST BASIC to C
Syntax.:
while (expression)
statement;
The statement (block) in the loop body is repeated as long as the while
expression is true, that is, as long as the logical value of the expression is
not zero. The expression can be replaced by a condition.
220
Abacus Software Atari ST BASIC to C
The variable types can be divided into two parts: integral and floating-point
variables. The variations of these two elementary types are as follows,
although some C compilers do not support them all.
221
Abacus Software Atari ST BASIC to C
12.4 Operators in C
PRIORITY LEVEL 1
() Parentheses, function call
[] Array element
-> Structure pointer operator
Structure variable operator
PRIORITY LEVEL 2
Negative operator
++ Increment operator
Decrement operator
Logical negation operator
* Pointer operator
& Address operator
PRIORITY LEVEL 3
* Multiplication operator
/ Division operator
% Modulo operator
PRIORITY LEVEL 4
+ Addition operator
Subtraction operator
PRIORITY LEVEL 5
<< Left-shift operator
» Right-shift operator
222
Abacus Software Atari ST BASIC to C
PRIORITY LEVEL 6
< Less than relation
<= Less than or equal relation
> Greater than relation
>= Greater than or equal relation
PRIORITY LEVEL 7
Equality relation
,- Inequality relation
PRIORITY LEVEL 8
& Bitwise AND operator
PRIORITY LEVEL 9
1\
Bitwise exclusive OR operator
PRIORITY LEVEL 10
Bitwise inclusive OR operator
PRIORITY LEVEL 11
&& Logical AND operator
PRIORITY LEVEL 12
II Logical OR operator
PRIORITY LEVEL 13
? : Conditional assignment
223
Abacus Software Atari ST BASIC to C
Appendix A
Now that you worked through this book, what should you do next?
225
Abacus Software Atari ST BASIC to C
Appendix B:
More books on C
227
Abacus Software Atari ST BASIC to C
228
Abacus Software Atari ST BASIC to C
Index
229
Abacus Sortware Atari ST BASIC to C
exponential notation 53
extern 211
float 87, 212,221
for 17-19, 136-144, 147, 211, 216
FOR-NEXT 17-20, 137, 191
fonnatinstructions 15, 16,52,56
fonnat specifiers 52, 53
functions 11, 41, 184-197
GEMDOSI0
getchar () 23-25, 37, 38, 44, 63, 65-68, 73-75, 86, 186
global variables 79,90, 91, 93, 191
goto 154-157,160,211,216,217
header 79, 88,195
hexadecimal 52
if 32-33,128-130, 211,213,217, 222
if-else 32, 33, 45, 133-135
IF-THEN-ELSE 33
increment operator 31,45, 115-116, 144,222
indirection operator 58 '
inequality operator 25,29,45
infinite loop 137-140, 149, 150
input functions 65
integer constants 81, 82
integer data types 84
jump instructions 211
justification 54
keywords 211-212
Lattice 5
libraries 3, 183
local variables 90, 93-95, 196, 204
logical AND 45, 131, 223
loops 44, 138
macro 75, 198, 199, 214
main () 10-14
MC680004
Megamax compiler 5
Microsoft Corporation 145
mistakes 82, 165, 178
modulo operator 114, 222
NAND 121
negation operator 120, 121, 129, 222
nested for loops 141-144
230
Abacus Software Atari ST BASIC to C
231
Optional Diskette
ATARI ST
BASIC to C
Optional Diskette
For your convenience, the 'C' program listings contained in this book are
available on an SF354 formatted floppy disk. Due to diskette directory
limitations the BASIC programs were not included. You should order the
diskette if you want to use the programs, but don 't want to type them in
from the listings in the book.
All programs on the diskette have been fully tested. You can change the
programs for your particular needs. The diskette is available for $14.95 plus
$2.00 ($5.00 foreign) for postage and handling.
When ordering, please give your name and shipping address. Enclose a
check, money order or credit card information. Mail your order to:
Abacus Software
5370 52nd. Street SE
Grand Rapids, MI 49508
INTERNALS GEM Programmer'. Ref. TRICKS & TIPS GRAPIICS & SOUND BASIC Tr.,nlng GuIde
Essential guide to learning the For serious programmers in Fantastic collection of pro- Detailed guide to understand· Indispensible handbook for
Inside information of the ST. need of detailed Information grams and In'o for the ST. ing graphics & sound on the beginn ing BASIC program-
Detailed descriptions of sound on GEM . Written with an Complete programs include: ST. 20 & 3D lunc1ion plotters, mers. Learn fundamentals of
& graphics chips , internal easy-to-understand format. All super-fast RAM disk; time- Mot" patterns, various reso- programming. Flowcharting,
hardware, various ports. GEM . GEM 8xClJ'lllies are written in saYing printer spooler; color lutions and graphic memory, numbering system, logical
Commented B lOS listing. An C and assembly. Requ ired print hardcopy; plotter output fradals , waveform generation. operators, program strudures,
In dispens ible reference for reading for the serious pro- hardcopy. Money saving tricks Exarrples written In C, LOGO , bits & bytes, disk use, chapter
your library. 45Opp. $19.95 grammer. 45Opp. $19.95 and tipo. 200 1'4). $19.95 BASIC and Modula2. $19 .95 qu~z.. . 200pp. $16.95
PRESENTING THE ST MACHINE LANGUAGE LOGO PEEKS & POKES BEGINNER' S GUIDE BASIC TO C
Gives you an in·depth Program i n the fastest Take control of your Enhance your programs Finally a book for those If you are already fam iliar
look at this sensational language for your Atari ATARI ST by learning with the examples found new to the ST wanting to with BASIC, learning C
new computer. Discusses ST. Learn the 68000 LOGO-the easy·to· use, within this book. Explores understanding ST basics. w ill be all that much
the arch itecture of the assembly language, its yet powerful language. using the different lang- Thoroughly understand easier. Shows the trans·
ST, working w~h GEM, numbering system, use Topics covered include uages BASIC, C, LOGO your ST and its many iti on from a BASIC
the mouse, operating 01 registers, the structure structured programming, and machine language, devices. Learn the lunda· program, translated step
system, all the various & important details of the graphic movement, file using various interfaces, mentals of BASIC, LOGO by step , to the final C
inlerlaces, the 68000 instruction set, and use 01 handling and more. An memory usage, reading and more. Complete with program. For all users
chip and its instructions, the internal system excellent book for kids as and saving from and to index, glossary and iIIus- interested in taking the
LOOO. $16.95 routinOS. 280pp $19.95 well as aduIIs. $19.95 disk, more. $16.95 Iralions. .200pp $16.95 next step. $19.95
PowerPlan ST
AssemPro Full-powered Spreadsheet
37 math fu nctions · 14 cigh precision
Large size · owr • .2 billion cells
The complete 68000 Multiple windows · ~ to 7
Graphics . 7 ~s of graphs
assembler development
package for the ST
TextPro
Wordprocessing package
for the Atari ST
'TextPro seems to be well thought out, easy, flaible
anf fast . The program maJces excellent use of the GEM
interface and provides lots of small enhancements to
make your work go more easily ... if you have an ST
and haven't moved up to a GEM word processor, pick Word Proceooor lor the Atorl
up this one and become a text pro."
-John Kintz
ANTIC
f,,,,,,tUil
'TextPro is the best wordprocessor available for the ST'
-Randy McSorley
• , t
I'at 11' ........11: o·
Pacus Report TM. 1. .. ".,'1 If tMt
D..,. CM.utl,. htuilit. ~:- tC~":~t1f:: f-:;::~~
th.. t~IS' IIttlltlll t.
TextPro is a first-class word processor for the Atari ST "trl'S'1M" l'tntu',I"",- Iftt.l, ...rhll rllult.. PI"
that boasts dozens of features for the writer. It was dntl. ..
tllllllli eUef ..,. IItu, .,..- ~1:~ ,r!:!IIIIvt~T ~,:~I.:!:
,,-hU .. _lttlt.lIl .
designed by three writers to incorporate features that ~1,," ••ft"'I""lt
In. ,It.t nll.lth ,utlllIMrt
II the Rltre IIMfut, •• ,,,.
~ wanted in a wordprocessor-tbe result is a superior .,' ..., ..,nd ... "II. , ... te-
tI,n hI t.l", t,n .f ,.d
package that suits the needs of all ST owners. ust...,. Ilk, ...
W, hn. en ut,nsl ..., 1111111' 'f
1I •• s ,1141 "f • .,., ..cilllS .
TextPro combines its "extra" features with easy
operation, flexibility, and speed-but at a very
reasonable price. The two-fmgered typist will find
TextPro to be a friendly, user-oriented program, with all
the capabilities needed for fine writing and good-looking TextPro ST Features:
printouts. Textpro offers full-screen editing with mouse
or keyboard shortcuts, as well as high-speed input, • Full screen editing with either mouse or keyboard
scrolling and editing. TextPro includes a number of easy • Automatic index generation
to use formatting commands, fast and practical cursor • Automatic table of contents generation
positioning and multiple text styles. • Up to 30 user-defined function keys, max. 160
characters per key
Two of TextPro's advanced features are automatic table • Lines up to 180 characters using horizontal scrolling
of contents generation and index generation • Automatic hyphenation
--capabilities usually found only on wordprocessing • Automatic wordwrap
packages costing hundreds of dollars. TextPro can also • Variable number of tab stops
print text horizontally (normal typewriter roode) or • Multiple-column output (maximum 5 columns)
vertically (sideways). For that professional newsletter • Sideways printin2 on Epson FX and compatibles
look, TextPro can print the text in columns-up to six • Performs mail merge and document chaining
columns per page in sideways roode. • Flexible and adaptable printer driver
• Supports RS-232 me transfer (computer-to-computer
The user can write form letters using the convenient transfer possible)
Mail Merge option. TextPro also supports GEM- • Detailed 65+ page manual
oriented fonts and type styles---text can be bold,
underljned, italic, superscript, outlined, etc., and in a TextPro works with Atari ST systems with one or more
number of point sizes. TextPro even has advanced single- or double-sided disk drives. Works with either
features for the programmer for development with its monochrome or color ST monitors.
Non-docurnent and C-sourcecode modes.
TexPro allows for flexible printer configurations with
TextPro Suggested Retail Price: $49.95 most popular dot-matrix printers.
AlariST. 52QST. 1040ST. TOS. STBASlCmI STLOOO ore _ or rqil_ ..- or Alari Cap. ---------~
OEM loa rqla_ _ oCDiplai R _ ....
Selected Abacus Products for the AtrM~ ~ ~
., :>
PaintPro
Design and graphics software for the ST
PaintPro is a very friendly and very powerful package
for drawing and design on the Atari ST computers that
has many features other ST graphic programs don't
have. Based on GEMIM, PaintPro supports up to three
active windows in all three resolutions-up to 640x400
or 640x800 (full page) on monochrome monitor, and
320 x 200 or 320 x 400 on a color monitor.
PaintPro's complete toolkit of functions includes text,
fonts, brushes, spraypaint, pattern fills, boxes, circles
and ellipses, copy, paste and zoom and others. Text can
be typed in one of four directions-even upside down-
and in one of six GEM fonts and eight sizes. PaintPro
can even load pictures from "foreign" formats (ST
LOGO, DEGAS, Neochrome and Doodle) for
enhancement using PaintPro's double-sized picture
format. Hardcopy can be sent to most popular dot-
matrix printers.
PaintPro Features :
• Works in all 3 resolutions (mono, low and medium)
• Four character modes (replace, transparent, inverse
XOR)
• Four line thicknesses and user-defmable line pattern
• Uses all standard ST f1ll patterns and user definable
f1ll patterns
• Max. three windows (dependng on available memory)
• Resolution to 640 x400 or 640x800 pixels
(mono version only)
• Up to six GOOS type fonts, in 8-, 9-, 10-, 14-, 16-,
18-, 24- and 36-point sizes
• Text can be printed in four directions
• Handles other GOOS compatible fonts, such as those
in PaintPro Library # 1
• Blocks can be cut and pasted; mirrored horizontally
and vertically; marked, saved in LOGO format, and
recalled in LOGO
• Accepts ST LOGO, DEGAS, Doodle & Neocbrome
graphics
• Features help menus, full-screen display, and UNIX>
using the right mouse button Lk UEI'sioo
• Most dot-matrix printers can be easily adapted
W....A.Ut. ..u iP-& ~
Old c.- - . om~ fDn10
PaintPro works with Atari ST systems with one or Illaiudall p8 HIlrr1 .dltar
Chartpak ST
Professional-quality charts and graphs
on the Atari ST
In the past few years, Roy Wainwright has earned a
deserved reputation as a topnotch software author.
Chartpak ST may well be his best work yet Chartpak
ST combines the features of his Chartpak programs for
Commodore computers with the efficiency and power of
GEM on the Atari ST. - lUl - vum
Chartpak ST is a versatile package for the ST that lets IIldr; Slack ferformdnce
the user make professional quality charts arid graphs /1
fast. Since it takes advantage of the STs GEM Stli4 lilt il lus l I~ U If ulltlli ..
functions, Chartpak ST combines speed and ease of use Du!rI /jits Ut J If""i, ,;,, liltl
The user first inputs, saves and recalls his data using
"Chartpak ST's menus, then defines the data positioning,
scaling and labels. Chartpak ST also has routines for
standard deviation, least squares and averaging if they are
needed. Then, with a single command, your chart is
drawn instantly in any of 8 different formats-and the
user can change the format or resize it immediately to
draw a different type of chart
ST.
AssemPro is a complete machine language development Dnk rile flSS!l'lbJer Dtbulttr flitter Surefrl 110[11 IIfl
ihSMbhr
package for the Atari ST. It offers the user a single, r : U888 T Xl: RU :
AssemPro Features: