Amiga C For Beginners 1990 Abacus PDF
Amiga C For Beginners 1990 Abacus PDF
C for Beginners
. >'
Schaun
This book is copyrighted. No part of this book may be reproduced, stored in a retrieval
system, or transmitted in any form or by any means, electronic, mechanical, photocopying,
recording or otherwise, without the prior written permission of Abacus or Data Becker
GmbH.
Every effort has been made to ensure complete and accurate information concerning the
material presented in this book. However, Abacus can neither guarantee nor be held legally
responsible for any mistakes in printing or faulty instructions contained in this book. The
authors always appreciate receiving notice of any errors or misprints.
ISBN 1-55755-045-X
ii
Table of Contents
1. Introduction to C 1
1.1 Program Execution 4
1.2 Compiler vs. Interpreter 5
2. Beginning C 7
2.1 The Editor 10
2.2 The Compiler 11
2.3 The Linker 12
2.4 Putting It All Together 13
5. Loops 43
5.1 while Loops 45
5.2 for Loops 48
5.3 do while Loops 49
5.3.1 More Error Checking 49
5.4 AND and OR ."!".!" 52
6. Strings 55
6.1 Backtracking 57
7. Calculating in C , 59
8. Variables 63
8.1 Variable Names 65
8.2 Data Types 67
8.3 Type Conversion 70
8.4 The cast Operator ."........!!71
Hi
9. printf and scanf 73
9.1 More Escape Sequences 75
9.2 Format Specification 77
9.3 Octal and Hexadecimal 80
9.3.1 Conversion Program 82
9.4 Character Codes 84
9.4.1 About the Backslash 85
9.4.2 Going the Other Direction 86
11. Abbreviations 93
11.1 Increment and Decrement 97
11.2 Initialization, Definition, Declaration 99
11.3 Multiple Assignments and Directive Value in C 101
IV
17. User-defined Libraries. .151
17.1 The strcmp Function. .154
17.2 Itoa \ 157
17.3 Reverse \ 159
Appendices 263
A. Functions 265
B. The History of C 270
C. The Lattice C Compiler 272
D. The Aztec C Compiler 273
E. Reserved C Words 276
F. Operator Precedence 277
G. Storage Classes 278
H. Type Conversions 278
I. Modes for f open 279
Index 281
VI
1
Introduction to C
Abacus 1. Introduction to C
Introduction to C
This book is divided roughly into two parts. The first part introduces
the reader to the basic structures of C programming through operating
the editor, compiler and linker. It also contains many sample programs.
You'll be able to write your own short programs in C in only a few
hours.
This first part also takes the beginning C programmer through the
essentials of C—calculations, string handling, loops and more. It even
helps you find the errors made most often by new C programmers.
The second part, which begins at Chapter 10, explains the background
and peculiarities of each C statement and function. These include
preprocessor commands, arrays, loops, pointers, addresses and memory
classes. If these words don't mean anything to you now, they will when
you start reading the second section.
The second part also discusses macros, interfacing your Amiga to the
outside world, tricks and tips for the C language and graphic pro
gramming.
This chapter describes the general nature of C. You'll see its advantages
and disadvantages compared to interpreted languages, as well as advan
tages and disadvantages compared to other compiled languages. You'll
also see why C stands out above so many other computer languages.
1. Introduction to C Amiga C for Beginners
1 • 1 Program Execution
There are two kinds of computer languages. First, there are interpreted
languages such as BASIC and LOGO. Second, there are compiled
languages such as C, Pascal or Modula2. Section 1.2 contains detailed
information about the advantages and disadvantages of interpreters and
compilers.
Compilers Compilers are programs which translate the language statements into a
form understandable to the computer. This form consists of the
numbers 0 and 1 (the numbers used in the binary system). Since people
can't remember long strings of zeros and ones, the computer can be told
to interpret words and other number systems as binary numbers. For
example, a typical machine language instruction LDA means "Load the
Accumulator", which is easier to remember than the binary number
10011101.
A compiler A compiler translates the source program once into executable form.
This is similar to someone who translates foreign language literature
into his/her own language. This translator takes the time to select the
proper choice of words for the text, unlike the interpreter who mediates
a conversation between two people from different language back
grounds.
The compiler translates the program source only once. The compiler
may spend a few minutes compiling the program before it can be
executed. Afterwards, the compiled program executes much faster than
an interpreted program, since the compiler doesn't have to re-translate
the source program. This advantage becomes most evident in program
loops in which a command can be executed several thousand times. The
interpreter translates the command into machine language, repeating
this process a few thousand times. The compiled program already
knows what to do without repeating the translation. The advantages of
compiled languages lie in shorter execution times for compiled
programs.
The biggest advantage that C has over other languages is its transporta
bility. This means that you should be able to take a C source code from
an Amiga, transfer it to a PC, make changes to fit the PC's file
handling and other machine-specific tasks, and compile the C source
code on the PC with no problem.
2. Beginning C
One word of warning: Don't skip this chapter, even if you have
previous experience with C. You might learn something you didn't
know before about the language.
Programs begin with an idea. The user has a task that he wants to
accomplish using a program—and the program should perform the task
easier, faster or more accurately than a human could do it. This idea
could be for a drawing program; a spreadsheet for calculating payroll and
figures; a fast disk copier; or just a simple text display on the screen.
Once the general idea is developed, it helps if the programmer sits down
and writes out the goals of the idea, and how the program can do this.
This writing stage can be in plain English, since it should be as
readable for you as possible. This written documentation of the program
execution is sometimes called the pseudo code, since it tells what the
program should do without actually writing which statements the
program needs to perform the task. When writing the pseudo code of
this program, keep it broken down into smaller modules whenever
possible.
The editor, in which the user enters and corrects the source
program;
The linker, which joins the main program with other compiled
programs and functions to make a fully executable program.
The rest of this chapter discusses the use of each program in the devel
opment of C programs.
2. Beginning C Amiga C for Beginners
You need some sort of text editor to enter a C program from the
keyboard. An editor is nothing more than a simple word processor. It
usually contains only minimal text processing capabilities. The
program usually only allows you to type in, load, save and edit the text
of the source code: Nothing fancy like block functions or save and
replace capabilities.
Most word processor programs can be used for typing in the text of a C
program. If you use a word processor, you may not enter any special
control characters (e.g., bold fonts and text formatting) because the C
compiler would not recognize them. Many word processors provide the
option of letting you save a file as an ASCII file.
If you use a word processor as an editor, it must allow you to enter the
special control characters needed by C source codes. C programs use
braces ({}), brackets (D), the backslash (\), the number sign (#), the pipe
character (I) and the tilde character (~).
Maybe you can't afford a word processor, or maybe your word processor
doesn't have the necessary characters. The Workbench disk which comes
with your Amiga contains an editor named ED. ED is a basic text
editor, which you can find on the Workbench disk of the Amiga from
the CLi. Invoke the editor by entering the CLi, typing ed and the
name of the file you want to load/edit, and press the <Return> key.
The editor is loaded and then the C program is typed in. This text,
called C source code, is stored on the disk under a filename. The charac
teristic that sets this apart from normal word processing files appears in
the file extension: C source codes must contain a file extension of .C.
Examples of names can be sort.c or archive.c; note that these
names indicate the contents of each file. Try to use meaningful names
like this instead of cryptic names like a.c or this.c. The extension of
.C is especially important, since several files with the same name but
different extensions are generated by a C compiler. After a file is created
and saved, you can then call the C compiler to compile the C source
code.
10
Abacus 2.2 The Compiler
2 . 2 The Compiler
Calling the compiler loads the C compiler into memory. The compiler
reads the source code and begins to convert the source code into
compiled machine language. Most compilers read the source code twice
(two pass compiler). During the first pass, if it encounters an invalid
expression or keyword, it stops compiling and displays an error
message on the screen or writes the error to a disk message file.
Whenever an error is found, you must reload the editor, and correct the
source code. Once you've fixed the errors, you save the source code file,
exit the editor and restart the compiler. If the compiler finds errors
again, you must repeat the above procedures.
Before going any farther, you should realize one thing. Writing the C
source code requires proper preparation. If you just enter source code
without giving any thought to what you're typing in, you'll spend
more time learning about error messages and the editor than you will
spend learning about the C language. In the beginning, prepare to see
plenty of errors, and be patient with yourself as you go from compiler
to editor to compiler.
When you've corrected all of the errors in the source code, the compiler
can finish the first pass without stopping and performs the second pass.
This second pass does the final transformation into object (compiled)
code. The compiler saves the object code to disk under the same name
as the source code, but with an extension of .0. For example, a source
code named source.c generates an object code file named source.o.
The object file needs one more step before it can become executable
program code—this is the linker.
11
2. Beginning C Amiga C for Beginners
We're not done quite yet The object file must still be run through the
linker. The linker searches for all functions used by the program from
the C libraries, and links the necessary functions into one program.
The linker identifies the functions required for a complete program and
adds them to the main program. This saves a programmer a lot of work.
The functions simply require the passing of values instead of retyping
the source code for each function from scratch.
The linker cannot handle non-compiled source code. It can only link
compiled functions together. Source codes can load other source codes
during compilation, but we'll see more on this later.
12
Abacus 2.4 Putting it all together
The CLI The Amiga's CLI (Command Line Interface) is used to specify the
parameters for the editor, the C compiler and the C linker. For example,
entering the following line in the CLI calls the Lattice C linker:
The MAKE file The inputs required to compile and link a C source code can be written
to a file called a make file. This make file calls all the necessary
programs such as the compiler or linker. The C system reads the file
just as if the user had input the text direct from the keyboard.
AmigaDOS' Execute command reads this file and passes the informa
tion to the C compiler sections needed to make the final executable
program. See Appendix C for one example of a make file and its
contents.
13
3.
The First Program
Abacus 3. The First Program
#include <stdio.h>
void main()
{
printf("Hello, I am here!");
To see what the program produces, the text must be entered using an
editor. When you use the editor, please enter the text exactly as it is
printed here and in Section 3.1. This avoids error messages which will
cause problems. Once you've become more comfortable working in C,
you can change programs around to suit your own needs. But don't
change anything until after the program compiles and links exactly as
you see here.
Workbench 1.2 users who can't find the CLI may have it switched off
with the settings in Preferences 1.2. Using Preferences 1.2, you must
click on the ON gadget next to the word CLI. Once you close and
reopen the Workbench disk icon, the CLI icon should appear in the
window.
After you invoke the CLI or shell, a new window appears. This
window prompts for an input with the message:
17
3. The First Program Amiga C for Beginners
3.1 Using ED
First you'll need an editor to enter the program. The ED editor can be
called from the C: directory on your Workbench disk. The following
executes ED and creates a new file named hello.c:
1> ED HELLO.C
The computer places the 1> prompt at the beginning of the line. Some
versions of the CLI may also display the current directory (e.g., the
shell from Workbench 1.3).
The name hello.c will be the name of our first C language program.
It doesn't matter whether you type the name in uppercase or lowercase
letters.
If you made a typing error, press the <Backspace> key to delete the last
character typed. The <Backspace> key has an arrow pointing to the left
on some versions of the Amiga. If you prefer, you can press the
<Ctrl><X> key combination to delete the entire line of text.
Press the <Return> key to execute the command and invoke the editor.
A window appears and displays the text "Creating new file." The user
now enters the program. The editor allows you to move the cursor
around the file using the cursor keys to make corrections and changes.
Type the following text:
#include <stdio.h>
void main()
{
printf ("Hello, I am here!");
Once you've finished typing the text, press the <Esc> key, then press
the <S> and <A> keys. Pressing the <Return> key saves the text (this
combination will be called <EscxSA> from here on). Press <Esc>
<XxReturn> to save the text and quit the editor. The system returns
you to the CLI. Pressing <EscxQ> returns you to the CLI without
saving the file. See the book AmigaDOS Inside and Out from Abacus
for more information about ED.
18
Abacus 3.2 Compiling
3.2 Compiling
Lattice 4.0 Start the Lattice 4.0 compiler with the following:
1> lc -L hello
For Lattice C 4.0, the following should now appear on the screen. Your
screen may differ slightly. If you get error messages, see Section 3.3.
1> lc -L hello
Lattice Amiga DOS C Compiler Version 4.0
Copyright (C) 1987 SAS Institute Inc. All rights reserved
Compiling hello.c
Module size P=00000014 D=00000012 U=00000000
Total files: 1, Compiled OK: 1
Linking hello
BLink - Version 7.2
Copyright (C) 1986 The Software Distillery.
Copyright (C) 1987 SAS Institute Inc. All rights reserved
Box 8000 SAS Circle, Cary NC 27511-8000 - Telex 802505 (919) 467-8000
Aztec C To compile the program using the Aztec C compiler requires two steps.
The Aztec system first compiles the source code then assembles and
links it. A make file can be quite useful. Enter the following for the
Aztec C compiler:
l>cc +L hello
The above sequence may not function in some cases. If not, enter the
same line but omit the +L. Aztec C should display the following on
the screen. Your screen may differ slightly. If you get error messages,
see Section 3.3.
1> cc +L hello
Aztec C68K 3.6a 12-18-87 (C) 1982-1987 by Manx Software Systems, Inc.
Aztec 68000 Assembler 3.6a 12-18-87
Now enter
19
3. The First Program Amiga C for Beginners
Aztec C should display the following on the screen. Your screen may
differ slightly.
Success Did everything work as expected? If you didn't get an error, type the
dir command in the CLI to see the current disk's directory. TTie exe
cutable program is stored there under the name hello. Notice that this
file has no extension. There may also be other files with extensions of
.map, .0, .lnk and of course .C. This shows that the extension helps
identify the file. Call the executable program by entering the following
line:
hello
Hello, I am here!
20
Abacus 33 Error Messages
Lattice If you forgot to type in the semicolon following the print f function,
the Lattice C compiler displays the following message:
Aztec The Aztec C compiler displays the following message if the semicolon
is missing:
Let's try to determine from this compiler message what is wrong with
the file. The first line states the filename in which the error appeared:
hello.c. That filename specification is useful later on (more on this
later). Then follows the line number (5), error number (57) and the error
description in English. This indicates that a semicolon was expected in
line 5.
The user must now reload the editor to correct the error:
ED HELLO.C
To reach line 5, you can count down the lines (the fastest method for a
program this short). You can also press <EscxM><5xReturn> to
get to line 5. The editor then moves the cursor to the line indicated.
Line 5 consists only of the closing brace (}), but this is expected since
the error actually occurred in the previous line. The semicolon in the
previous line is missing. The error messages of the C compiler should
never be taken too literally, since the search for the error may have to
take the surrounding code lines into consideration.
21
3. The First Program Amiga C for Beginners
22
4.
Theory and
Practice
Abacus 4. Theory and Practice
Now that you've had some practical experience entering and compiling
a program, let's look at the theory of how the program in Chapter 3
works.
printf("Hello")/
Value (10);
music () ;
end();
value = old;
music;
end;
Arguments The information passed to a function during the call are arguments. The
arguments to be passed are placed within the calling function's paren
theses to ensure proper delivery. It is important to enclose any character
strings within quotation marks (e.g., printf ("Here lam!");).
After calling the printf function the text appears on the screen. The
printf function ends and the program continues at the point where it
was interrupted by the function call.
25
4. Theory and Practice Amiga C for Beginners
No other statements follow the line after printf. This means that the
main function has also reached its end, and the program ends. The
computer returns to the CLI, and additional commands can be entered.
The end of the program and the return to the CLI represent the termina
tion of the main function. The user should note how important this
function is. It represents the C program itself; program execution starts
and ends with the main function.
26
Abacus 4«* Program Format
4 .1 Program Format
Let's discuss the format of the program. The C compiler ignores any
spaces, linefeeds and end of paragraph marks added to the listing by the
user. Indenting lines of adding blank lines helps make source codes
more readable to the user. Formatting has no effect on the execution
speed or the length of the final program. The program you entered in
Chapter 3 could have been in one of the following formats:
void main () {
printf("Hello, I am here!");
void main ()
{
printf("Hello, I am here!")/
}
27
4. Theory and Practice Amiga C for Beginners
void main()
Don't expect miracles from the above program. When you compile,
link and start it, it loads, runs and does nothing. The computer returns
totheCLl.
Definition The function arguments enclosed in the braces are its definition. It de
fines what the computer should do when it executes a certain function.
void main()
{
printf("Hello, I have a question!\n");
printf("Do you believe in life without electricity?\n");
printf("Not me!\n");
}
This program has two differences from the program in Chapter 3. First,
there are three printf functions instead of one; second, the \n charac
ter appears at the end of each string within quotation marks. See the
next section for details on \n and other escape sequences.
28
Abacus 43 printf and Escape Sequences
The text at the end of Section 4.2 appears on the screen as it appears in
the source code, with three exceptions. The three \n characters do not
appear. The \n character is called the newline character, one of the
many escape sequences used for controlling the format of text. The \n
character tells the compiler to insert a linefeed at that place in the text,
just as if you pressed the <Return> key.
The user is not obligated to place the escape sequences at the end of the
character string. They can be placed between other "normal" characters
or even at the beginning of the text. If desired, all three lines can be
written within one printf function:
The newline character is not the only method of formatting text. The
printf is comparable to the PRINT command in BASIC or the
write statement in Pascal. The f in printf indicates that the text
can be output in a specified format This function can process and dis
play character strings and other values as specified by the programmer.
Since these capabilities are quite extensive, we'll introduce them to the
reader as needed.
29
4. Theory and Practice Amiga C for Beginners
4.4 Comments
void mainO
{
/* This program outputs a text which starts */
Now, think of your first program from Chapter 3. If you added com
ments to tell a future reader exactly what this program did and when, the
end result could look something like this:
30
Abacus 4.5 Variables and Arithmetic
Our knowledge of the C language is still rather small. Right now you
can display text on the screen and insert comments in source code.
scanf It would be nice to be able to have a program accept input from the
keyboard. The scanf function is the opposite of the print f
function—it reads input instead of displaying output (more about
scanf later).
Consider how a program would execute for questions and answers. First
the print f function displays the question on the screen. Next the
scanf function reads the user's input.
4.5.1 Integers
31
4. Theory and Practice Amiga C for Beginners
printf("Number: ");
scanf("%d", &input);
printf("\n\nYour input was: %d\n", input);
}
The first line of the main function, int input;, tells the compiler
what to do with the variables. This line assigns a name to the variable.
The program uses this variable name for access to the variable's
contents. This variable name (input) indicates its purpose. Variable
definition ends with a semicolon.
Format The following lines are the printf functions. Next, the scanf
specification function asks for the user's input in response to the text "Number:"
Since a large number of data types exists, the input routine must be
told what data can be expected. The format specification %d specifies
the data type. Format specifications are similar to the escape sequences
(the characters preceded by a backslash). The percent sign indicates a
format specification; the d tells scanf that the value to be read in
must be of type int. The name of the desired variable follows the
string in quotes, separated from the string by a comma. An ampersand
(&) precedes the variable name. This is important: If the system crashes
the user should first examine the scanf function parameters to make
sure they are correct.
If scanf contains the correct information, the user can enter the input
in the running program. Enter a number and press the <Return> key.
This value can be found in the variable input. The program can now
use this number.
This program accepts the input then displays the variable using the
printf function. The printf function must also be told what kind
of data it must process. A format specification identical to the one
which appears in scanf serves this purpose. Because of this, printf
knows that an integer number will be passed, which must be placed at
the location occupied by the format specification in the text. The
variable name input follows the string in quotes, separated from the
string by a comma. The input appears on the screen if the input was a 1
or 2 and not text (text is not allowed here). If you enter text, the input
becomes a large random number (in Lattice C) even though this number
never appeared in the input line. If you enter no input scanf scrolls
the screen one line upward and waits for a new (more useful) input.
It is rather boring to just let the computer repeat the input. It would be
better to respond to the input. For example, have the computer respond
to an entry of "1" with the message, 'That is very good!", or an entry
of "2" where the message could be, "I am sorry to hear that!" The
32
Abacus 4.5 Variables and Arithmetic
if(input == 1)
printf("That is very good!\n");
if(input == 2)
printf("I am sorry to hear that!\n")/
The conditions appear inside the parentheses so that the first printf
statement only occurs when input equals 1. The same is true of the
following i f statement, with the difference that the text executes if
input equals 2. Semicolons never follow the if.
The user who wants to experiment can try a semicolon after the second
if. If you do so, the program acts as if the line if (input == 2);
doesn't exist After each input "I am sorry to hear that!" appears.
Adding the four lines above makes the program run properly, but it
could be improved. Some users may be familiar with the BASIC
statement:
else The C language also has an else statement which can only be used
together with the if statement. The else statement executes only
when the condition has not been met. This eliminates the second test.
if(input == 1)
printf("That is very good!\n");
else
printf("I am sorry to hear that!\n");
/* scan2.c 4.5.2 */
void main()
{
int input;
33
4. Theory and Practice Amiga C for Beginners
if(input == 1)
printf("That is very good!\n");
printf("Hope you stay healthy!\n");/* Not like this! */
else
printf("I am sorry to hear that!\n");
Statement Since only one line is executed after the if, something else must be
block done. Up to now only one statement has been described. It is time to
describe a statement block. Placing several statements inside braces
creates a statement block which is valid as a unit. This block can be
placed following the if statement without problems:
if(input == 1)
{
printf("That is very good!\n")/ /* Right! */
printf("Hope you stay healthy!\n");
}
else
printf("I am sorry to hear that!\n");
The Amiga can do a lot of things, but what it does best is calculate (and
fast). Let's start with addition. To add two values use the plus sign (+):
The result for this example is stored in the variable sum. This variable
must be defined at the beginning of the function, just like all variables.
Using type int, the following definition results:
int sum
int numberl
int number2
All variables are separated by commas and the list is terminated with a
semicolon.
With this information it's possible to write a program that adds two
numbers. The scanf function permits data input, but this time two
34
Abacus 4.5 Variables and Arithmetic
numbers will be read in. This will not be done with two separate func
tion calls (this would also be possible), but a second format specifica
tion is written into the string of the scanf call. It contains %d%d
(notice no spaces) which reads the second parameter. And now the
listing:
/* scan3.c 4.5.2 */
void main()
{
int sum, number1, number2;
The user familiar with other languages such as BASIC can compare the
listings to other language implementations of the same program. The
last printf function with the three format specifications can appear
confusing. The following is a BASIC equivalent:
The reader can guess what would have to be changed to perform multi
plication instead of addition. The plus sign is replaced by an asterisk
(*). A hyphen (-) is used for subtraction and a slash (/) performs
division.
result = number * 4;
sum = var + 2 + var2 + 3 + var4;
result =4*5-7/ var;
value = 2 * (number - 7);
result =4+5*3-2;
counter = counter + 1;
35
4. Theory and Practice Amiga C for Beginners
result =4+5*3-2;
The result is 17, not 25. The product of 5 * 3 is calculated first, after
which 4 is added and 2 subtracted.
/* mathl.c 4.5.3 */
void main()
{
int numberl, number2, result, operator, error;
}
if(operator == 2) /* Subtraction */
{
result = numberl - number2;
error = 0;
}
if(operator == 3) /* Multiplication */
{
result = numberl * number2;
error = 0;
}
if(operator == 4) /* Division */
{
result = numberl / number2;
error = 0;
}.
if(error == 1) /* None of the above conditions */
printf("Wrong Code! Input only numbers 1 - 4!\n")/
else
36
Abacus 4.5 Variables and Arithmetic
The program is very easy to read. After all values have been entered, the
variable error is assigned a value of 1. During every operation that
follows, be it addition, subtraction, etc., the error variable is set to
zero. This makes it possible to determine whether one of the four
operations was performed. If this was not true, the value in operator
is illegal.
Test this program thoroughly with various values. Please note that the
integer variables are only permitted to store values between +32,767
and -32,768. Furthermore, division by 0 should be avoided. This would
cause a system crash and a Guru Meditation.
The error can be traced to the variable type. The int variable type is
only capable of processing whole numbers between ±32,000. The value
4.5 is a floating point number, not a whole number. If during a
division a remainder (the fraction after the decimal point) occurs, it is
ignored. This does not mean that the division 9/2 cannot be performed
on the Amiga computer. The only thing required is that the variable
type can be capable of storing floating point numbers. No problem
since C is equipped for this.
float To convert the current program for this new data type, the variables
number 1, number2 and result must be changed. This process
consists only of replacing int with float. The first lines appear as
follows:
main ()
{
float number1, number2, result;
int operator, error;
This alone is not sufficient since scanf and printf use the format
specification %d which expects an integer value. This is no longer the
case. The %d must be replaced with a %f. The f means a floating point
37
4. Theory and Practice Amiga C for Beginners
value is passed, just like the d is used for integer values. The first
scanf function now appears as follows:
/* math2.c 4.5.4 */
void main()
{
float number1, number2, result;
int operator, error;
Lattice The library for mathematical functions and floating point numbers must
be linked with the standard library. Example:
lc -Lm math2
38
Abacus 4.5 Variables and Arithmetic
Aztec If you work with the Aztec C compiler, the library for mathematical
functions and floating point numbers must be linked with the standard
library c.lib.
Example:
cc +L math2.c
In math2.o -lm -lc
char Besides the int and float variable types which accept numbers, you
need another category of variables to store characters. It would be better
if the program above could accept a plus sign instead of the number 1
to indicate addition. The data type char allows variables to be defined
which can accept characters.
char character;
This type of variable has its own format specification for the print f
and scanf functions. A c is used for the type char. To give the
calculation program a few extras, the operator is entered as a character.
This means that instead of entering a number as you had to before, you
can enter a math operator instead.
The tests which formerly checked the code now have to test the charac
ters for the operators. Nothing easier than that! Only the characters
must be placed in apostrophes (single quotes):
if(operator == '+')
39
4. Theory and Practice Amiga C for Beginners
After all the small changes, compare this version to the final program
below in which some other cosmetic changes were made. The reader
should now be able to understand the additions made.
During the input a small item has changed. Until now the <Return>
key had to be pressed (but not required) after inputting each number.
Now the entire input must be in one line. The reason for this is the fact
that a single character is read in with %c. This could be a <Return> or a
space. For this reason the first number is followed immediately by the
operator after which the <Return> key may be pressed, if desired.
Finally the second number appears as in this line:
/* math3.c 4.5.5*/
void main()
{
float number1, number2, result;
char operator;
int error;
40
Abacus 4.5 Variables and Arithmetic
Lattice The library for mathematical functions and floating point numbers must
be linked to the standard library. Example:
lc -Lm math3
Aztec If you work with the Aztec C compiler, the library for mathematical
functions and floating point numbers must be linked with the standard
library c.lib. For example:
cc +L math3.c
In math3.o -lm -lc
41
Loops
Abacus 5. Loops
5, Loops
void main()
{
int counter;
counter = 15;
while(counter > 0)
{
printf("Counter is %d\n", counter);
counter = counter - 1;
The block which appears after the while statement executes until the
conditions inside the parentheses are true. In the beginning, the variable
counter is set to 15. While the condition counter > 0 has been
met, the following block is executed which outputs the current value of
counter and then decrements it by one. In this case the printf
function is called 15 times until counter has been reduced to 0. The
conditional statements can be formed by using tests for equality (==),
greater than (>), less than (<), greater than or equal to (>=), or less than
or equal (<=). The comparison here is for counter to be greater than
0.
45
5. Lo o p s Amiga C for Beginners
Instead of
while(counter > 0)
while(counter >= 1)
In the comparison operators <= and >=, the equal sign (=) always
appears at the end.
4! =1*2*3*4= 24
/* factorial.c 5.1 */
void main ()
{
int num, i;
float factorial;
46
Abacus 5.1 while Loops
Now for a few hints in helping you compile this program with your
compiler.
Lattice The library for mathematical functions and floating point numbers must
be linked with the standard library. Example:
lc -Lm factorial
Aztec If you work with the Aztec C compiler, the library for mathematical
functions and floating point numbers must be linked with the standard
library c.lib. Example:
cc +L factorial.c
In factorial.o -lm -lc
47
5. Loops Amiga C for Beginners
NEXT I
for(i = 0; i <=100; i = i + 2)
48
Abacus 53 do while Loops
5 . 3 do while Loops
The last type of loop is the do while loop. The reader has already read
about the while loop; this loop is quite similar. Please compare the
two program sections below:
The do begins the do while loop, and the while ends the loop.
This leads to a small but significant difference in program execution. In
the first example the program checks if variable i is still greater than 0
and then executes the loop only if the conditions are met. In the second
example the test is executed only after the loop has already been
executed once. If i contains the value 0, the while loop is skipped,
unlike the do while loop which executes at least once.
Please notice the semicolon which must follow the while. It is often
forgotten since normal while loops don't use semicolons.
If this material is not clear without further example programs, the user
is encouraged to write some short programs (e.g., which output the
values of the variables used).
The next section deals with error detection. Up to now it was difficult
to make mistakes, except for errors in typing. When the program sud
denly reports errors, there's no need to panic. Study the messages the C
compiler returns. You may have to do a little thinking to detect cleverly
hidden errors.
49
5. Lo o p s Amiga C for Beginners
Find the Below is a new program. Based on what you know so far you should be
errors able to determine where the errors are hidden, and which lines could
cause problems. The listing contains errors which result in a long series
of error messages. Try to find the hidden errors on your own first. Fix
these errors, then try compiling the source code to see what you missed.
We've included the solution directly after the listing. The program
should add all numbers from 1 to 100 and display the subtotals and the
final total on the screen.
main ();
{
printf("I add all numbers from 1 to 100/n");
i = 1;
do
printf("Subtotal for %d. value: %d/n", i, sum);
sum = sum + 1;
i=i+l;
while(i < 100)
printf("Sum of all numbers to 100 is %d/n", sum);
Did you find all the errors? You should have found most of them, since
the program is almost completely wrong! Even if you found no errors,
you can follow the remaining material without problems.
Let's start with the first line which contains an error (of course). The
semicolon following main shouldn't be there. The missing void only
results in a warning, not an error. The next line with the brace is correct
(an exception in this program). The compiler accepts the first print f
function without problems. It doesn't contain a syntax error. The line
would even be right if you wanted to display the slash (J) and an n. The
slash (/) should have been a backslash (\). To be consistent, this error
occurred in all the print f functions in this program.
Within the loop, the values for i and sum should be displayed. Except
for the error with the escape sequence \n everything is correct here.
Finally the program increments the contents of sum and i are incre
mented. Trouble is, the sum variable was never defined. The C com
piler doesn't know what is meant by i and sum. A line must be added
before the print f function.
int sum, i;
50
Abacus 53 do while Loops
The while test remains which terminates the program after the num
ber 99. The change is simple:
/* errorfree.c 5.3.1 */
void main()
{
int sum, i;
printf("I add all numbers from 1 to 100\n");
sum = 0;
i = 1;
do
{
sum = sum + i;
printf("Subtotal for %d. value: %d\n", i, sum);
i = i + 1;
} while(i <= 100)
printf("Sum of all numbers to 100 is %d\n", sum);
51
5. Loops Amiga C for Beginners
Up to this point, only one exit condition can be checked in your loop.
This changes with the introduction of the && and I I operators. The <l>
key can be found on the right side of the keyboard above the <Return>
key. The & & represents the logical and and the I I the logical OR.
Why these operators are called logical will be revealed later since other
logical operators also exist in C. From BASIC the commands and and
OR are familiar and they are the same as the operators in C.
If one of the two criteria is not met (e.g. i = 4), the entire condition is
false and therefore not satisfied. Only if both tests are true can the loop
be executed.
Four tests were made, of which only one must be true. If several tests
can be positive, this is no problem since only one true condition is
sufficient That the if statement could be written in two lines should
be nothing new. Remember that the formatting of the C listing is of no
interest to the C compiler.
52
Abacus 5.4 AND and O R
All tests are made within the parentheses. If the expression inside the
parentheses is true, a valid character is present, the negation operator
goes into action. It simply reverses the matter. From the true test it
makes a false one so that die print f command is not executed. This
is similar to the false test result within the parentheses, when none of
the signs + - * / are stored in the variable. In this case the ! operator
makes it a true test. That is the same procedure as inserting a not into
a sentence. In everyday English double negatives can be used in one
sentence, but not many people will understand it.
53
Strings
Abacus 6. Strings
6. Strings
char name[number_of_fields];
Let's take the first character in a string. This first character appears in
the first position of the string, and is assigned position 0 (computers
always start counting with 0). All locations then shift by one. The
second character can be reached using the value 2, due to the index,
which acts as a position indicator. Every position contains a character.
All characters are arranged sequentially in a large or small string.
6.1 Backtracking
Let's write a program which displays the text backwards on the screen.
Before starting, you must assume that a string can be any length. The
string will always end with the value 0 (null). The last character of the
string must be processed first if you want the text displayed backwards.
The program needs a small for loop to find the last character of the
string (0):
char input[81];
int index;
The loop body (the statements executed during every pass through the
loop) is empty. A single semicolon follows the for loop. Since a
block of statements follow every loop, this semicolon ends a block that
57
6. Strings Amiga C for Beginners
do
{
index = index - 1;
printf("%c", input[index];
} while(index > 0);
You now have the information you need to write the entire program.
One other item before you enter and compile this program: If you have
the Aztec C compiler, this program will not compile using the +L
(longwords) option. Omit this option when compiling this program
with Aztec C. Here's the source code:
/* backwards.c 6.1 */
void main()
{
char input[81];
int index;
do
index = index - 1;
printf("%c", input[index]);
} while(index > 0);
Enter a string of characters, but do not include any spaces. The for
loop calculated the length of the input string and then the do while
loop printed it out backwards. Former BASIC programmers may
remember the len function. In C, the user can easily create a function
or routine to do this.
58
7.
Calculating in C
Abacus 7. Calculating in C
7. Calculating in C
You have already seen how fast the Amiga computes; addition (+), sub
traction (-), multiplication (*) and division (/) are familiar to you.
First the program calculates the expression to the right of the equal sign
and places the result in the variable to the left of the equal sign. Because
of this, statements such as the following are possible:
variable = variable + 1;
number = 3 * 32
number =2+6*7
number = 5 * (180 / 3 + 9) (5 - 2)
number = number - 1
number = number % 2;
Precedence Division and multiplication have precedence over addition and subtrac
tion. This rule is also observed by the C compiler. Therefore, the
expression 2 + 6*7 needs no parentheses to achieve the correct result
The modulo operator has precedence equal to division, and therefore
precedence over subtraction and addition. Example:
void main()
{
int number;
number = 3 * 12;
printf("Result: %d\n", number);
61
7. Calculating in C Amiga C for Beginners
A variable does not have to be used in this program since the %d char
acters tell print f that it can expect an integer value. The term 3 *
12 can be passed directly to the function as a parameter. The calculation
of the result occurs before the value is passed so no variable is required.
The following program is faster and shorten
main ()
{
printf("Result: %d\n", 3 * 12);
}
Note: The number -2.25 is rounded to -2 and not -3 since -2 is larger than -3.
Lattice C rounds numbers toward 0, but this can differ with other C
compilers. Only a test run helps to explain what happens with -5 / 2,
in which either -2 (toward zero) or -3 (rounded) appears as a result
62
8.
Variables
Abacus 8. Variables
8. Variables
The earlier chapters used variables. These are areas of memory used for
storing mathematical results, as well as different kinds of data.
8 .1 Variable Names
The names given to variables must follow some rules. The following is
a list which describes these rules:
6. Variable names are case sensitive (i.e., the compiler sees a differ
ence between upper and lowercase).
65
8. Variables Amiga C for Beginners
a) Number 1
b) 2_pi
c) first-var
d) Book__no__l
e) Book no 2
0 int
g) __flag
h) int_valu
i) number 1
j) secret Password
The following variable names are correct: a), d), e), g), h), i) and j). It
should be noted that a) and i) are different variables since upper and
lowercase letters are differentiated, d) and e) may refer to the same
variable on some C compilers, since the names are the same for the
first eight letters. Errors would occur on some C compilers since these
variable names are longer than eight characters: c), d), e) and j). h) uses
a C keyword as a variable name, but this is permitted since the rest of it
doesn't match the keyword.
Look at examples b), c) and f)- The variable in b) starts with a number
(not allowed). A hyphen appears in c) (the hyphen is considered a
special character). Finally f) uses a variable name which is a reserved
keyword of C.
66
Abacus 8.2 Data Types
Until now three data types have been described: int, float and char
(strings).
int Integer values are type int. The 16-bit int type represents whole
numbers between -32,768 and 32,767. The int type works well for
general use. The Amiga libraries use 32-bit integers, but for portability
of your source code to other computers you may want to use 16-bit
integers.
float Floating point numbers are assigned the data type float. A float
variable can store extremely large or small numbers, and numbers with
decimal places. In this type of variable the values can be presented in
scientific notation. Very small numbers such as 0.00000015 can be
written as 15E-7 (the use of E is an abbreviation). 15E-7 is scientific
notation for:
15 * 10
Even the float variable type has its limitations. The largest number
permitted \s 1038. Any number less than 10'38 converts to a 0. The
value 1040 when written out is a number which has a decimal point, 39
zeros and a one, in that order. The computer views it as 0. Floating
point variables remain accurate up to seven decimal places. Try the
math3.c calculation program from Section 4.5.5; enter the number
16.8. The program converts the number to 16.799999.
double If you need more accuracy, use the double variable type. Variables of
type double are about twice as accurate (11-14 decimal places).
However, double variables require more memory.
There are times when float and double variable types don't have
the accuracy of integer values. On the other hand, rounding numbers off
can cause incorrect results in multiple calculations. The result becomes
more inaccurate with every additional operation.
67
8. Variables Amiga C for Beginners
Note: You may crash the system as well as get the wrong answer with the
example above. If you want to try the two examples above, save any
important data you might have on the RAM disk to a floppy disk
before continuing.
char Other data types can be derived from the basic types int and float.
For example, the type char which can accept a character is really a
variable for whole numbers between -128 and 127. This small relative
of int represents the ASCII values of the characters.
long The long type is another type derived from int. Long accepts inte
gers between -2,147,483,648 and 2,147,483,647. If you must define
constants as long values, place an 1 or L behind the floating point
number instead of .0. For example:
1L
68
Abacus 8.2 Data Types
char character;
character = 65;
character = 'a';
The table below describes the length of the different numeric variable
types:
Lattice Aztec
8 . 3 Type Conversion
2. If after these conversions one of the operators should have the type
double, the second operand and the result also convert to
double.
70
Abacus 8.4 The cast Operator
long number;
number = 123 / (long)('a1 / 1.5);
(type) Parameter
Better format*
(type)(Parameter)
71
9.
ntf and
s can f
Abacus 9. printf and scanf
The scanf function gives the user the option of input to the com
puter. You have had a chance to work with this function as well.
Note: An escape sequence uses two characters in the text, but represents only
one character. Keep this in mind when calculating memory usage.
The following program uses the \t escape sequence for tab stops:
main ()
{
printf(An\tExample,\ttwo\tTabs\tspacing")/
printf("\tspacing\tText!\n");
}
75
9. PRINTF AND SCANF AMIGA C FOR BEGINNERS
It is not possible simply to place the text in quotation marks since they
already occur in the texL Escape sequences are necessary. The program
prints the quotation mark using the \" escape sequence, the backslash
with \ \. The necessary print f call appears as follows:
main()
{
printf("Small ");
printf("\"T est progra m")/
printf("\"\n\nWhere\nis the\ntext now?\n");
printf("\tEverything OK?\n");
}
76
Abacus 9.2 Format Specification
9 . 2 Format Specification
Without indication of the field width, the standard setting for %f in the
printf function is %.6f. The output therefore always has six decimal
places and any field size.
%<min>.<fraction>F
77
9. PRINTF AND SCANF AMIGA C FOR BEGINNERS
Number 12.35
%<Min>F
printf(">%4d<", 12) /
Output:
%<Min><real>s
The scanf function is much simpler. Only one number exists which
indicates the maximum input length possible. As soon as a character no
longer fits into the fonnat of a data type, or a control or blank character
appears, the input for the current field ends. This means that during
78
Abacus 9.2 Format Specification
int i;
float f;
char string[50];
scanf(%3d %f %*d %s", &i, &f, string);
Input: 1234567.89 12345all clear?
Value i contains 123, since the field should have 3 places, and only numbers
assignment can appear. The value 4567.89 is in f, because the space after "9" pre
vents additional reading of input. The same happens after the storage of
"all" in the string!]. The number sequence "12345", which normally
is assigned to an integer value, was skipped because of the asterisk.
This means that with the scanf no spaces can be read. This makes
scanf less than ideal for string input.
If the reader can't remember all of this material, don't worry. It is used
intensively during the course of the format specifications.
9. PRINTF ANDSCANF AMIGA C FOR BEGINNERS
5279
5,000 + 200 +70 +9
5 * 1,000 + 2 * 100 +7* 10 +9*1
Octal system If you used eight different numbers (0-7) instead of ten, the base in the
calculations would be 8. This base 8 system is better known as the
octal system. The following example shows the process of calculation a
number in the octal system. To differentiate the different number sys
tems, the base number appears in subscript or in parentheses following
the number:
6204
8
80
Abacus 93 Octal and Hexadecimal
5DA9
16
0X5DA9
OxFFFF
0612
0x5da9
0x123
0815
0X5da9
06543
The response depends on the compiler. The compiler can issue a mes
sage that a wrong number was entered, or accept it as a decimal number.
The Lattice C compiler converts the number from octal into decimal
notation. This produces something entirely different, namely 52510
which is equal to 10158
The user would soon get tired of entering every number for conversion.
A good C implementation does that conversion for you.
To write a program to convert numbers from various bases into the dec
imal system, the procedure must differ slightly. Nothing is simpler
than constructing a loop to save typing time. Starting with the last
position (9 in the last example), multiply it with the value of the posi
tion. The value at the last position is then 9*1 = 9. The next
position has the value 16, and the variable containing this value with
the base (16). The next position is therefore 10*16 = 160.
81
9. PRINTF AND SCANF AMIGA C FOR BEGINNERS
/* base-con.c 9.3.1 */
void main ()
{
long base, collect, value;
int index, help;
char test[100];
The program uses the long data type a lot. This can also be noted in
the format specification %ld for the input and output of these variables.
The scanf function which reads a number as a string has something
new. After the percent sign appears an 80, followed by the format
specification %s for the string. This value between the percent sign and
82
Abacus 93 Octal and Hexadecimal
In the following while loop the string which was input is processed.
To avoid the use of the expression test [ index] for every calcula
tion, the character at that location is copied into the variable help. The
user should have noticed that help was defined as an integer variable.
Yet an attempt is made to store a character at that location. Computers
view characters as numbers. Every letter has a numeric code, just like a
number. The char variables are nothing more than small integer
memory areas which, depending on the compiler, accept a value
between -128 to 127, or from 0 to 255. These peculiarities of calcu
lating characters with numbers and their codes will be discussed later.
83
9. PRINTF AND SCANF AMIGA C FOR BEGINNERS
character = '9';
character = 57;
Calculation with the variable requires the value 9 and not the stored
code 57. First subtract 48 from 57 (48 is the character code for zero (0)).
This is practical since all numbers are in sequential order with the
following codes.
Code Character
48 0
49 1
50 2
51 3
57 9
The letters of the alphabet also follow this order. The table starts with
A (code 65), B (code 66), etc. The lowercase letters are in a separate list
The first value there is 97 for the character a. Let's look at a program
section:
char test
test = 'B1;
test = test - 'A1 + 10;
84
Abacus 9.4 Character Codes
or
The codes are nearly identical on almost all computers thanks to the
ASCII standard. ASCII assigns a specific code to each character.
/* ASCII.c 9.4*/
main ()
{
int i;
printf ("\n\n");
for(i = 32; i <=127; i = i + 1)
printf("\t%-3d %c", i, i) ;
for(i = 160; i <= 255; i = i ,- 1)
printf<"%-3d %c \t", i, i);
printf("\n");
}
These are all of the characters that can be printed with the printf
function.
printf("\261");
The number 177 decimal corresponds to 261 octal. The conversion can
be avoided using a format specification as shown below:
85
9. PRINTF ANDSCANF AMIGA C FOR BEGINNERS
printf("%c", 177);
The character is not used directly in the string, but goes directly to the
printf function in the form of a character code, with the %c.
/* dec-conv.c 9.4.2 */
void main()
{
long base, test, help, rest;
int index;
char result[260] ;
86
10.
The Preprocessor
Abacus 10. The Preprocessor
10.1 #de£ine
Let's first consider the most important and most often used preprocessor
directive: #def ine. #def ine replaces a certain character string with
another string. The preprocessor exchanges the two text strings. Let's
think about what the text replacement could be used for.
fdefine TAX 4
Up to this line the text TAX can be used which is then replaced by the
preprocessor with the text 4. Also the following line could be used:
89
10. The Preprocessor Amiga C for Beginners
/* define.c 10 */
#define BEGIN 1
#define END 100
#define STEPS 2
void main()
int i;
printf("\n");
for(i = BEGIN; i <= END; i = i + STEPS)
printf("%5d", i);
for(i = END; i >= BEGIN; i = i - STEPS)
printf("%5d", i);
printf("\n");
The number zero in the octal system, the decimal and other number
systems is always zero. A conversion in this case isn't difficult. Using
the character with the code zero, or the code directly (zero) in the assign
ment is of no consequence. In future programs which use strings, the
definition of EOS should appear in one of the first lines.
If the reader thinks that the subject of #def ine is now finished, he is
wrong. The many capabilities which are provided with the #def ine
directive, will be discussed in more detail in a separate chapter.
90
Abacus 10.2 #include
10.2 #include
If you have a source code text that uses these #def ine directives, you
don't have to re-enter them. All you have to do is #include the file
def_new.h:
#include "def_new.h"
The file extension of .H stands for Header file. This ensures that all
#def ine directives are available throughout the listing. It is not a
requirement, but should be done anyway. Although this preprocessor
directive can appear at any place in a file, it is better to include it at the
head of the source code.
#include <def_new.h>
s t di o.h The compiler assumes that the file is now located in a subdirectory in
which all .h files can be found. The path to this subdirectory passes to
the compiler during the start. There is a series of these files which are
waiting to be used. One of the most popular of these files can be found
under the name stdio.h. This stands for STanDard Input Output
Header file. In Lattice C, it is in the include directory. This file can
be examined using the ed editor.
91
11.
Abbreviations
Abacus 11. Abbreviations
11. Abbreviations
We said earlier that C is an ideal language for lazy people who don't
like to type. This is still true, since C lets you compress many
functions into smaller packages using abbreviations. This chapter
describes the art of abbreviating code in C.
C abbreviations help save typing time. Let's start with the simplest
abbreviations—those used in arithmetic operations. The equation below
may look fairly familiar to you. Believe it or not, this can be converted
to a shortened form of the same equation:
number = number * 4;
What could be saved here? The variable number appears twice. This
doesn't have to be so. The C language allows you to abbreviate the
equation to the point where you only need to use the variable number
once instead of twice:
number *= 4;
Every time you use the same variable during calculation and for storing
the result of the equation, you can use this short form instead. The
multiplier gets moved to the left side of the equal sign. The multiple of
the variable number remains to the right of the equal sign.
The above abbreviation becomes most effective when using long vari
able names. In addition, it helps decrease the number of typing errors
(the less you type, the fewer mistakes you make). For example, look at
the following abbreviation:
95
11. Abbreviations Amiga C for Beginners
/=
%=
etc.
Consider the following expression. Can you see any possibilities for
abbreviating the code?
The line is already written in such a way that the operator to be abbre
viated becomes immediately obvious. It is the multiplication operator.
So, if you change the equation into abbreviated form, the source code
looks like this:
value *= (5 + number);
Since usually the right side of the equal side is calculated first, no
parentheses are required. Therefore, the final version of the short equa
tion looks like this:
value *= 5 + number;
Now for the same thing in reverse. The operator and the named variable
can be attached to the terms, using parentheses. The following equation
also has potential for becoming an abbreviated version:
corresponds to:
96
Abacus 11.1 Increment and Decrement
main ()
int i; "■■'
i = 1/
while(i++ < 100)
printf("%d ", i);
First the computer sees if i is less than 100. Then it increments the
value of i by 1, regardless of the results of the test. This corresponds
to the following if /else/while:
Here all four listed directives are executed within the parentheses. That
makes the increment operator very powerful.
97
11. Abbreviations Amiga C for Beginners
These operators help to write fast and compact programs. They are even
more efficient than the abbreviations using the equal signs.
98
Abacus 11.2 Initialization, Definition, Declaration
Initialization These three concepts are very important for the C programmer and
should not be confused. Let's begin with initialization. It describes the
first assignment of a value to a variable. After this point you know
what the variable contains. Before the variable can be initialized, it
must be defined or declared. Definition takes forms similar to the fol
lowing:
int index;
char string[80]/
When the compiler reaches this point, it knows the variables and sets
aside the necessary memory area for them. An integer value generally
requires two bytes. The variable string requires 80 bytes since every
char element requires one byte. Functions can also be defined. Up to
now only the definition of main was mentioned. If you declare a
function or variable, this only tells the program that such a variable or
function was defined somewhere. For this reason no memory is allo
cated.
Definition Here's a tip for saving lines of code. Variables can be initialized during
definition. That saves one program line:
int index = 0;
Some coding can seem exaggerated, but there is no limit to your imag
ination.
Declaration If you write a large program stored in several modules (files), a variable
used by all modules only requires a single memory allocation. The
definition is in one file and all the other files only contain the corre
sponding declaration. Declaration is made with the C word extern.
The compiler knows that the memory was reserved externally through
another file. Otherwise the linker stops linking. Example:
99
11. Abbreviations Amiga C for Beginners
The example above shows that the data type must also be specified.
This provides all the information necessary to the compiler about the
variable. The function declaration is similar.
If you define the function in the same file, the extern can be omitted.
The declaration is still required since the compiler knows the function
names and their data types only at the end of the file.
100
Abacus 113 Multiple Assignments and Directive Value in c
begin = 0;
sum = 0;
a=b=c=d=2;
d = 2;
c = d;
b = c;
a = b;
Examples can show this better. Here are some more values for expres
sions:
(2) 2
(a) a
(a *= 3) a*3
(a=(b =(a+2) -3)) a-1
101
11. Abbreviations Amiga C for Beginners
The last example must be dissected into its components to reach the
same result
(a=(b=(a+2)-3)))
(a=(b=a-l ))
<a=(a-l ))
(a-1)
102
12.
Functions
Abacus 12. Functions
12 Functions
Function First, the formal structure of a function definition. You must specify
structure the function name, preceded by the data type returned by the function.
The name must correspond to the usual rules for variable names.
main ()
105
12. Functions Amiga C for Beginners
The next step is to dissect the program into individual tasks. You can
write a short function for every partial task. For example, a function to
compute the square of a value requires no great mathematical training:
double square(x)
float x;
{
double q_number;
printf("The square of %f\n is ", x) ;
q_number = x * x;
return q_number;
}
The square The above routine defines a function named square which in turn
function returns a double value to the calling program. As a parameter to be
passed, a float value called x is required. At the end of the routine a
new C word appears, the return keyword. It delivers the desired result
of the specified data type to the caller and also ends the function.
double square();
main ()
{
float value = 3.0/
double result;
result = square(value)
}
The names of the parameters passed by the calling function need not be
identical to those of the called function. However the data types must be
the same. Notice the line in which the square function is declared as
a function which returns a double value.
106
Abacus 12.1 Functions with Arguments
The declaration can be omitted if integer values are returned. The same
is true for the definition of a function. If the function returns integer
values, a data type need not precede the function name. This is only
possible with data type int. All other types must be declared and
supplied with the proper data type during the definition. If one of these
data types is contradictory (perhaps because the declaration forgot a
double function) the resulting values will be wrong. While the C
language permits much freedom to the programmer, but this can cause
much trouble.
107
12. Functions Amiga C for Beginners
/* key.c 12.2 */
void key(string) /* Without Return value: void */
char string[80];
{
int i;
for(i = 0; string[i] > 0; i++)
printf("%c", string[i] + 1); /* From 'A1 make 'B1 */
void main()
{
char text[81]/
void key () /
The new defined functions are called exactly like the routines from the
libraries. In this example the main function stands at the end of the
file. The routine named key is declared as a function which returns
nothing, or void. That is important since the definitions would contra
dict themselves during usage in main. If the function had not been
declared, the compiler would assume that it should return int objects.
It returns nothing.
108
Abacus 123 Other Functions
Another function which does not return a result is strcpy. This rou
tine copies strings, and performs general string handling. Even though
it's included in every compiler's library file, it is interesting to see how
it can be programmed.
12.3.1 strcpy-Version 1
This copies one string to another. Unlike the previous example, you
don't know how many entries are in each string. This can be omitted. It
is enough for the compiler to know that it will get a string.
In the routine itself, a counter tests all entries. They are copied until the
routine reaches the EOS character (the end character must also be trans
mitted).
strcpy(to,from)
char to[], from[];
{
int i = 0;
while((to[i] = from[i]) != EOS)
109
12. Functions Amiga C for Beginners
The actual loop body has only a peripheral role. The main action occurs
in the ending conditions. Experiment with this function. Notice that the
string into which the copy is stored appears first. Here is a complete
example program:
/* copysrt.c 12.3.1 */
#define EOS '\0'
#define MAXLEN 81
strcpy(to,from)
char .to [ ] , from [ ];
{
int i = 0;
while((to[i] = fromfi]) != EOS)
void main ()
{
char si[MAXLEN], s2[MAXLEN], s3[MAXLEN];
Wrong:
main ()
{
char text[20] = "This_is_text!";
Right:
main ()
{
char text[20];
strcpy(text, "This_is_text!") ;
110
Abacus 123 Other Functions
12.3.2 strlen
strlen(string)
char string[];
{
int i = 0;
while(string[i])
return(i);
If the return directive passes data, it must be assured that the value
has the proper data type. If the function definition states that the routine
returns a char element, there should be a variable or constant of the
char type. Some compilers will not tolerate such mistakes and will
issue an error message. Others are indifferent and convert the result into
the data type indicated in the definition. It's better to do it right in the
first place.
Ill
Arrays
Abacus 13. Arrays
13. Arrays
Up to now strings have been used as if they were a special data type. A
string is actually multiple char entries. A string of similar objects is
called an array. Arrays can also be made using int or float data
types as well as char types. Any elementary data type can be stored in
an array. Several similar variables can be accessed through a single
identifier. A single element is accessed by using a subscript called the
index (counter). The definition of a long array differs little from string
definition:
long value[20];
This line reserves 20 elements of type long for the variable value.
To indicate the end of a string, the last entry contains the value 0, i.e.,
assigns the escape sequence \0. For this reason, the definition of a
string (character array) requires one element more than needed for the
actual string. No such requirements exist for other array types: Only as
many entries are defined as required by the data. A value assignment of
one element is possible only by providing the index. For example:
value[0] = 4711;
valued] = 707;
value[2] = 31415;
The index value of the first element always starts with 0. Using this
method, you can create a string one character at a time:
char string[80];
string[0] - 'OS-
string [1] = "K1;
string[2] = '\0';
115
13. Arrays Amiga C for Beginners
int field[8][8];
Both elements are of course between 0 and 7. You need two subscripts
to access a single Held:
long content[4][5][6][7][8];
Please observe that arrays can quickly occupy large amounts of mem
ory. The array above would require 4*5*6*7*8*4 (size of a
single long element) bytes (26,880 bytes or 26.25K).
Data can only be stored sequentially in memory. The user must get
away from the notion that a two-dimensional array is located in two
tables which are one in front of the other. How would a five-dimen
sional array be stored? Since all elements are stored in a long series
(one-dimensional) there is a rule which must be followed. The first
index changes only when all elements which belong to its group are
stored. During the second index that occurs more frequently and the last
index changes with every element. This concept is easier to understand
in a listing which shows the position of the entries in memory.
Assuming a definition of int pos [ 4 ] [ 3 ];, entries in memory are:
[0][0]
[0][1]
[0][2]
[l][0]
[1][1]
[1] [2]
[2][0]
[3] [1]
[3][2]
116
Abacus 13.1 Multi-dimensional Arrays
/* array.c 13 '*/
tdefine FALSE 0
tdefine TRUE 1
#define MAXENTRY 20
void main ()
{
int i, number, end = FALSE;
long sum, data[MAXENTRY];
Lattice The library for mathematical functions and floating point numbers must
be linked with the standard library. Example:
lc -Lm array
117
13. Arrays Amiga C for Beginners
Aztec If you work with the Aztec compiler, the library for mathematical func
tions and floating point numbers must be linked with the standard
library c.lib. Example:
cc +L array.c
In array.o -lm -lc
The && operator ends the for loop which connects two tests logically
with an AND. If not all entries are occupied, and the variable end is
unequal to 0, the loop executes.
Negation The negation operator converts end into the logical opposite. At the
beginning the variable contains the value 0 so that the expression
becomes ! end 1. The reverse occurs when end is set to 1 and the
negation ! end is used to leave the loop. This happens when the user
enters the number 0, indicating the end of the input.
The first entry in the array requires the index 0. Since the count usually
starts at I, a 1 is added to the current index during text output. In the
formulation of the scanf function, the following is most important:
Sentry[i]
If another array was input, no & character appears. That was the big
exception. Since entry [i] and not entry was written, this is not
an array, but a perfectly normal long variable. During the scanf
routine it is equipped with the & like all elementary data types. The fact
that this variable is in a long string of similar elements doesn't concern
the scanf function.
if(entry[i] == 0)
118
Abacus 13.1 Multi-dimensional Arrays
When the loop finishes, either because 20 entries had been made, or the
last entry was 0, the total number of the stored data is calculated. The
add function gets the necessary data (the array with the input and the
number of values to be added). This routine returns the sum. With this
information the deviation of each entry from the average can be calcu
lated. If the task of the program was only to add a series of numbers, no
arrays would be needed but all entries could be summed after their entry.
119
14.
More about Loops
Abacus 14. More about Loops
This chapter takes you through a few of the fine points of using loops
in C programming language. You've already seen for loops and
while loops.
We described the for loop earlier in this book. Now we'll look at the
limitations and flexibility of the for loop.
or also
This is the usual construction for a for loop. Since C permits other
variations, this example is presented:
You may recall that, under every condition, a null value is always
considered a false condition. Everything else is considered logically true.
The condition in the loop is always true. The only way to stop the
program is to press the <E> key, provided there is an input function.
123
14. More about Loops Amiga C for Beginners
14.2 break
If the test for if is true, the break statement is carried out. The
break statement ends the currently executing loop immediately and
forces the program to continue with the statement that follows the loop
that just ended. The break statement is the only way to break free of a
loop at any time.
for(;;)
A for loop can always be replaced with a while loop, and vice versa.
The general format is:
for(terml; term2;term3)
other directives
or
terml;
while (term2).
{
other directives
term3;
124
Abacus 143 continue
14.3 continue
int i;
for(i=0; i<number;
if(field[i] == 0.0)
continue;
continue here!
125
14. More about Loops Amiga C for Beginners
/* switch.c 15.4^*/
void main()
{
int number;
126
Abacus 14.4 The switch Directive
If the character passed for the test is for example a 5, all directives (also
those behind case 4, 3, etc.) are executed up to the next break
directive. This causes die direct termination of a loop, or in this case
the switch directive.
127
15.
Pointers and
Addresses
Abacus 15. Pointers and Addresses
15.1 Addresses
Let's start slowly. The pointer concept has close connections to the
address concept. During the call of the scanf function, the & (address)
operator had to be placed in front of most variables. This construction
allows the determination of a variable's memory address. All data,
whether floating point numbers, integers or characters, are stored
somewhere in the computer. The position where variable data can be
stored is determined by a number (the address). In general, an address can
be compared with the house number on a long street. This number is
obtained from the variable which is preceded by the & character.
Assume that the variable a was defined and is stored starting at address
100. The expression &a would return the value 100. Why are addresses
required, if you can work without them?
The user who experiments with his own functions, may soon find that
the called function should pass more than one returned value to the
calling function. It is also difficult to change the content of a variable
defined in another function. Consider the following section from a
program:
{
int number = 6;
change(number);
change(newnum)
int newnum;
{
newnum =5;
131
15. Pointers and Addresses Amiga C for Beginners
Now we have a way to pass the address of the variable. The calling
function can access them directly and the function does not contain a
copy of the variables. In what data type should this address be stored?
132
Abacus 15-2 Pointers
15.2 Pointers
char text[80]/
char *pointer; /* Define pointer to char-elements */
text[6] = 'a1;
pointer = &text[6]/
The first command defines a char array (string). The next line is the
definition of a pointer which is called pointer. An asterisk precedes
the pointer name, which labels it as a pointer. In addition (as in all
other variable definitions) the data type is indicated. In the next line, the
character a passes to the array element with the index 6 (7th entry).
Now the pointer appears, which gets the address of element 6 with the
address operator &. Since pointer now contains the address of this
element, it points to the character a. The pointer points to another
variable, text [ 6 ]. This is also called referencing, and the reversal of
this process is known as de-referencing.
Now access can occur to the letter through the initialized pointer. The
next directive could be:
if(*pointer == 'a')
printf(That's it!\n");
133
15. Pointers and Addresses Amiga C for Beginners
♦pointer = 'b1/
After this directive 'b' passes to the location to which the pointer is
pointing instead of 'a'. Without using the array, its content was
changed.
Now a routine which should change the value of the calling function.
The exchange function:
exchange(xp,yp)
int *xp, *yp;
{
in help = *xp;
*xp = *yp;
*yp = help;
}
This function expects two pointers to the int values passed as param
eters. For the exchange the first value which points to xp is saved in
the integer variable help. Then the values are exchanged. The call of
the function must also be changed in comparison with the previous
calls since pointers to their addresses, not int values, are expected.
exchange(&valuel,&value2);
Perhaps now you can understand why, in a scanf the address operator
always had to be used. With this function, data are written into the
variable, which is only possible with pointers and addresses.
&array[0]
134
Abacus 15.2 Pointers
char string[81];
scanf("%s",string);
15.2.2 strcpy-Version 2
Pointer In the strcpy routine above, the peculiarity of the pointer becomes
increments obvious. If the pointer increments by one, the pointer points to the
next element. If it increments by two, it points to the element after the
next. In this strcpy version, a character is transmitted from from to
to until the transmitted value is equal to 0. At that point the expres
sion (*to = *f rom) has the value 0. When this expression becomes
unequal to 0, the while loop terminates. The last transmitted character
is the just tested null byte which represents the end code of a string.
15.2.3 strcpy-Version 3
135
15. Pointers and Addresses Amiga C for Beginners
This should be one of the shortest and fastest versions for copying
strings which could be made faster only with a special trick. More on
this later.
the program is informed that the pointers from and to are pointing to
values of data type float. This data type generally requires 4 bytes per
entry. If such a pointer is incremented by one, for example after++,
it points to the following element. It is located four bytes from the
original element, but the compiler knows it through the definition of
the pointer. Through the incrementing of the pointer by 3, the address
would change by 12 bytes. In the data type double, which normally
uses 8 bytes, this can also be used. For each increment of the pointer,
the address is changed by 8 bytes. A pointer is a very nice feature.
136
Abacus 15.2 Pointers
After the definition of the variable i and the int pointer ip, which is
also initialized here, the variable i gets a value assigned. The number
100 is stored in it Now comes the big question, what does —*ip do?
137
15. Pointers and Addresses Amiga C for Beginners
During the use of pointers, you should note that they represent only a
pointer to a certain data type. The memory locations for the individual
elements must be defined separately and the pointer pointed to them.
The initialization of the pointer prevents the system from giving wrong
answers or crashing. If a crash occurs when using pointers, even during
the test run of a program, first check where the pointers or the array
index are pointing.
main ()
{
char *text_ptr;
Where in this program is the memory space for the string? The pointer
does nothing in this direction. It is stored somewhere in the program
text, just like in function calls (e.g., printf ("Hello\n");). Also
this string within the function must be stored somewhere.
Attention: If the text should be changed, for example with access through
text_ptr, the maximum length must be observed. In the string
above, this is only 28 characters, with one character representing the
end of the string \ 0. If 30 characters are written into this space anyway,
a system crash can be expected. It is possible that behind the string,
program code was stored which was overwritten. Should the computer
encounter such data which it cannot understand, it will go crazy.
The name of the array symbolizes the first element in the chain. Now
the question, what is the expression f ield [ 3 ] [2], if the following
definition has been issued?
Is it an element of this array? If so, which one, and if not, what is the
element? Examine the expression carefully. It only contains two
indices, but the definition contains three. It follows so that it cannot be
an extra element. It can only be a pointer which points to the first (?)
element. The first element isn't field [ 0 ] [ 0 ] [ 0 ], but the first field
to which field [3] [2] points.
138
Abacus 15.3 Pointer without Storage
139
16.
Storage Classes
Abacus 16- Storage Classes
16.1 Auto
auto Even though the name is unfamiliar to you, you've been using the
variables auto (local) variables all along. The auto variables represent the
default storage class in C language.
These variables belong to the auto class because they are automati
cally defined every time a function is called. On the function call, C
allocates memory space for the auto variables. The lifetime of an
auto variable is limited to the function in which the variable is
declared. After the function is abandoned through return, or the last
brace of this function is reached, the memory space allocated is released
and can be used for other assignments. These auto variables can only
be used in the function for which they were defined. The content of the
variable is lost and the name is not known to the rest of program.
143
16. Storage Classes Amiga C for Beginners
16.2 Static
static Unlike auto variables, static variables are retained until the end of
variables the program and are not deleted after leaving the function. They do not
have to be created again during a new call of the function. Leaving,
which means the termination of the executing function, should not be
confused with another function call within this function. Control may
briefly pass to another routine, but the calling routine remains active
(it's waiting for a result).
function ()
{
static int counter = 1/
During the first call of the function, the variable is defined and initial
ized with a starting value as in the example above. If the function is left
temporarily, a new variable isn't created during the new function call
because the variable still exists. Even its content remains and it does
not have to be initialized again. For example, a counter in this routine
could track how many times it had been called.
144
Abacus 16-3 External
16.3 External
extern The next storage class is the extern or global variable. These vari-
variable ables are defined outside the function and can be used by all functions.
A section of a program would appear as follows:
main()
The variables which were defined can also be used by functions which
are not in the source file. The linker is given a number of files for link
ing. These files contain functions which have already been compiled.
They may need global variables which must be assigned the right
values in their program. Such variables must be declared before using
them with the extern function, but they don't have to be defined:
This permits the use of the variable in a file in which error was not
defined.
145
16. Storage Classes Amiga C for Beginners
16.4 Register
register The last storage class is register. Those of you who have some
variable programming experience with assemblers know what this means. A
processor, the most important part of a computer, has various internal
memory locations. One such memory segment, which should not be
confused with the RAM of the computer, is called a register. The
number of registers which can be used depends on the type of processor
used. A 6502/10 used in the C64, or in the Atari 600/800/130, has
only three registers (2 registers and an accumulator). The MC68000
used in the Amiga, Atari ST and Macintosh has 17 registers. Each
68000 register is four times the size of a register in the 6502. For this
reason there are almost no compilers for 6502 computers which offer
the capability of register storage for variables. Of the 17 registers in the
computer, only three to five (depending on the compiler) are made avail
able for storage. The remaining registers are required for internal use.
int char
short unsigned
long
combinations of the above
pointers
Pointers are possible since they only represent the address of an object
In the Amiga they only occupy four bytes.
There are other restrictions. The defined variable can only be an auto
variable since it occupies a register of the central processor. They are
rarely used and can be occupied only for a short period of time. After
leaving the function in which it was defined, the register is released
again for other purposes.
146
Abacus 16-4 Register
/* countdown.c 16.4.1 */
#include <stdio.h>
void main()
{
printf("Time comparison with and without register\n");
printf("RETURN for Start\n");
get char () ;
printf("%cStart without", 7);
without_register();
printf("%cStop!\nregister routine\n",7);
printf("RETURN for Start\n");
getchar();
printf("%cStart with", 7);
with_register();
printf("%cStop!\n\n", 7);
147
16. Storage Classes Amiga C for Beginners
with_register()
{
register long i =5000000;/*Count from 5,000,000 to 0 */
while (i—)
without_register ()
{
long i = 5000000;
while (i—)
148
Abacus 16.5 Local
16.5 Local
local Local variables are the reverse of global variables. Different vari-
variables able groups such as register, auto or static local can be
defined. They are only valid in the block or the function in which they
were created. A local variable has precedence over a global vari
able, which means that, if two variables were defined with the same
name, the local variable is used. The local variable gets preference
while the global variable disappears for the moment An example:
/* local.c 16.5 */
int i = 1;
void main ()
{
int i = 2;
printf("%3dM, i);
{
printf("%3d", i);
{
int i = 3;
printf (fl%3d", i) ;
} -
printf("%3d", i);
}
printf("%3dM,i);
test();
printf("\n\n")/
test()
{
printf ("%3d", i) ;
{
int i = 4;
printf("%3dM, i);
149
16. Storage Classes Amiga C for Beginners
150
17.
User-defined
Libraries
Abacus 17. User-defined Libraries
Save these functions to your own file under the name string.c. You
can include these functions in your own programs using the
#include directive. The following line searches the main directory
for the include file string.c:
#include "string.c"
The following line also adds the string. c file to the main file:
#include <string.c>
Of the two syntaxes, the second line is much more flexible than the
first, since it searches many different directories for the same file.
#include <file.h>
Before starting with include, first you need something that can be
included. A useful function can be written to compare strings. Since
strings are not elementary data types, they can't be compared with:
153
17. User-defined Libraries Amiga C for Beginners
You now have to write a program to compare each element of the first
string one at a time with each element of the second string:
strcmp(s,t)
register char *s, *t;
{
while(*s == *t)
{
if (!*s)
return(0); /* End reached (*s == 0) */
return(*s - *t);
Store this function and the other two files below as stringf unc.c.
Since the older strlen routine could be improved, we will use
pointers this time. Instead of the indices, the pointer moves over all
entries of the string up to the EOS character. The start value must be
stored first so that the number of increments can be computed. That is
faster than counting with an additional variable. The stringf unc.c
file therefore appears as follows:
/* stringfunc.c 17.1 */
strcpy(to/ from)
register char *to, *from;
{
while(*to++ = *from++)
154
Abacus 17.1 The strcmp Function
strcmp(s,t)
register char *s, *t;
{
while(*s == *t)
{
if(!*s)
return (0); '/* End reached (*s == 0) */
Now let's see if they function properly. For this you'll use two strings
which are initialized in the program.
/* stringtest.c 17.2 */
#include "stringfunc.c"
main()
First we will look at the expected results of the function call strcmp.
The first call returns zero since both strings are really equal. The second
function call returns -16. This number is the result of the comparison
of the e and u characters. This means that the first different character in
the string ("Hello!") is smaller than the first different character in the
second string ("Huhu").
155
17. User-defined Libraries Amiga C for Beginners
int field[4][4]=
{ 1, 2, 3, 4 >,
{ 6, 3, 4, 9.},
{ 3, 4, 5, 6 },
{12, '9, 0, 2 },
int field[4][4]= { 1, 2, 3, 4, 6, 3, 4f 9, 3, 4, 5, 6,
12, 9, 0, 2 >;
When some elements are not initialized, they don't have to be listed.
All elements left out are automatically assigned a null.
in field[3][3]= {
{ 3, 2 },
{ 4 },
{ 3, 4, 5 },
156
Abacus 17.2 Itoa
17.2 Itoa
itoa(n, s)
char s[];
int n;
do
s[i++] = n % 10 + "OS-
while ((n /= 10) > 0);
The last place is converted and stored in s until the number which was
stored in n has reached 0 through constant division. The sign should
not be forgotten since it could cause problems for the loop (number
larger than 0). The simplest process makes the number positive before
the conversion and, if necessary, sets a flag for a negative value. After
the completed conversion, the string returns the minus sign.
The completed processing converts the number 123 into the string
"321", but only the last place is processed and stored in the string. The
solution to this problem is very simple. Write another function that
reverses the string. Assuming that such a function already exists (see
the next section for the function) the routine appears as follows:
157
17. User-defined Libraries Amiga C for Beginners
/•••••••••••••••••••••••••••••••••••a*****/
/* Name: itoa */
/* Parameter: n(int), s(string) */
/* function: Convert Integer to string */
/* comment: Requires reverse() */
/•••A*************************************/
itoa(n, s)
register int n;
register char *s;
{
register int i = 0;
register int sign = FALSE;
if(n < 0)
{
sign = TRUE;
n = -n;
}
do
s[i++] = n % 10 + '0';
while(n /=10);
if(sign)
s[i] = EOS;
reverse(s);
Program The large header contains important information. The function devel-
header oped by the user should be ready for use when it is finished. After some
time the function name and the parameters to be passed may have been
forgotten. At that time you could consult the header with its comments.
The function can be compiled independent of other functions. If the
compiler permits it, it can be stored in a library. Of course the source
files can be included into the current file with:
#include "itoa.c"
158
Abacus 173 Reverse
17.3 Reverse
The reverse Now to the reverse function which can reverse a string passed to iL
function Construction of the routine doesn't present a problem. Two pointers, or
indices, are needed for the beginning and end of the string. These point
ers exchange their elements between themselves and are then moved
toward each other. The pointer at the beginning is incremented and the
one at the end is decremented. Exchange continues until the two point
ers are equal, i.e., point to the same element. The routine is presented
complete with a commented header.
**/
Name:reverse */
Parameter: s (string) */
function: Reverse string */
comment: Requires strlenO */
**/
reverse(s)
register char s;
register int c, i, j;
c = s[i];
s[j]
}
The strlen The strlen function initializes the index j, which should point to
function the last element of s. Every C compiler package has strlen included
in one of its libraries, or you can use the strlen function defined in
the previous chapter. Both routines (itoa and reverse) should be
stored in the library labeled itoa.c since it will be accessed later.
Please note that the itoa routine also comes as standard equipment
with most C compilers. These standard everyday functions have already
been written by others.
159
18.
C Features
Abacus 18. C Features
18. C Features
c = (a>b) ? a : b;
if(a>b)
c = a;
else
c = b;
Take a look at stdio.h which you'll find with your compiler. There
you'll find the definition.
163
18. C Features Amiga C for Beginners
The sizeof The sizeof (size of) function returns the sizes of objects (variables)
function regardless of type. The unit returned by this operator is defined on the
basis of the char elements. The following example followed by
sizeof (character) returns 1:
The result is always the number of occupied bytes for the object under
investigation. The following short program determines how much
memory is used by the various data types in your compiler. This will
tell you if an int variable occupies 2 bytes (most C compilers) or 4
bytes (Lattice).
/* sizeof.c 18.2 */
main() /* Indicates memory required for data types */
{
printf("\ndatatype\tmemory in bytes\n")/
printf("char\t\t%d\n'\ sizeof(char));
printf("short\t\t%d\nM, sizeof(short));
printf("int\t\t%d\n", sizeof(int));
printf ("long\t\t%d\nII/ sizeof (long) ) ;
printf("float\t\t%d\n", sizeof(float));
printf("double\t\t%d\n", sizeof(double))/
printf("pointer\t\t%d\n", sizeof(char *));
164
Abacus 183 Bit M anipulation
This section describes the remaining operators, which deal with control
ling individual bits.
18.3.1 AND
The and operator consists of the & character. Maybe you thought this
is the address operator. This character can be used for both purposes,
but it's hard to explain why this is so. You must know the context in
which it is used. If it is placed alone in front of a variable, it represents
the address operator. If it is placed between two values in a normal
arithmetic equation, then it is the binary AND.
The concepts logical and binary help you distinguish between two
completely different operators. The logical AND is different from &&.
With and (&) individual bits can be reset. A set bit has the value 1, a
reset bit the value 0. The following table shows the connection between
various bit combinations.
AND OR EXOR
& 0 1 1
o 1 0 1
0 0 0 0 0 1 0 0 1
1 0 1 1 1 1 1 1 0
165
18. C Fe a t u r es Amiga C for Beginners
According to the and a bit is set (1) when both bits are set, otherwise
the result is a 0. This is comparable with:
18.3.2 OR
With the (I) OR operator bits can be set. A glance at the table above
will help you understand the various combinations of bits. In OR the
resulting bit is set if one or both bits were set. Only if both bits are 0,
is the result of OR also 0. The I sets individual bits and the & resets the
bits.
Example: Bit number 2 should be set in the variable flags (the count starts at
0):
#define MASK 4
int flags = 73;
flags | = MASK;
After this operation, the OR with the value 22 (number of the bit to be
set) = 4 (sets the second bit in the variable flags).
Every bit has its own value according to priority. For example bit 3 has
a value of 8 (23). The table below shows the individual bit values:
bit Number 45 67
Value 16 32 64 128
1 & 2 = 0
2 & 6 = 2
7 & 8 = 0
9 & 12 = 8
166
Abacus 18.3 Brr Manipulation
1001
& 1100
1000
1000(binary) = 8 (decimal)
112 = 3
2|6=6
7 | 8 = 15
9 | 12 = 13
1001
1100
1101
It is important that the characters & and & & are kept separate from each
other. & connects expressions bit by bit && only makes a logical com
parison from which either a 1 (true) or 0 (false) is returned. Therefore 2
& 1 = 0,but 2 && 1 = 1.
» « Operators for bit shifting are » and «. They permit bit shifting to
the left or right within a field. A shift to the left («) by one position
is the same as multiplying by 2, only it is much faster. All of this is
dependent on how data and numbers are stored and processed in the
computer. A shift to the right equals a division by 2. Depending on the
data type, either zero bits or set bits move into the free locations. For
unsigned values, zero bits are shifted in every case. For normal signed
int values it depends on the compiler used. For positive numbers, zero
bits should be added to the left, and for negative numbers, one bit. This
is compiler dependent and there is no guarantee of how this works.
167
18. C Features Amiga C for Beginners
5 « 3 = 40
101 (binary) shifted left by 3 bits (zero bits are shifted in): 101000
(binary) = 40 (decimal).
Use the program in the previous section for converting decimal num
bers to binary numbers.
18.3.4 EXCLUSIVE OR
EXOR 0 1
0 0 1
1 1 0
The one's complement operator ~ requires only one parameter. All bits
of the parameter are reversed. Set bits are unset and vice versa. It is
recommended to use this operator only for variables which were defined
as unsigned, or the sign is also affected.
In the variable all bits except for the first one are set (priority 0 and 1 =
1 + 2 = 3) so that the variable now receives the following bit sequence
(starting from a 16-bit integer):
168
Abacus *»-4 Goto
18.4 Goto
The use of the goto statement of course assumes a label (a marked line
to which the goto jump should be made).
if (error)
goto label;
The labels can be defined in the program text anywhere, but must
include a colon. They are only required for the goto statement and are
formed exactly like variable names.
Note: The label and jump commands must be used in the same function. It
is not possible to jump across all functions.
169
19.
Complex Data
Types
Abacus 19. Complex Data Types
Now that we've listed all the important commands, we now come to
the extra capabilities of C. Among these are data types which can be
configured according to the needs and demands of the user.
19.1 Struct
struct {
char firstname[20]/
char surname[30];
int age;
double income;
int sex;
} person;
The person This function defines the variable person. The variable person
variable consists of several partial variables which are described in more detail
within the braces. The first name has 20 characters, and the last name
30 characters. There are also fields for age, income and sex. Similar to
arrays, many entries are collected under one name. The difference is that
different variable types appear within the structure. Accessing individual
parts of this variable requires more specification than arrays, which use
an index. The structure uses either the . (period) operator or -> opera
tor. An assignment of 30 to the element age appears as follows:
person.age = 30;
person.sex =0;
person.income = 300000.0;
strcpy(person.firstname, "Rena");
strcpy(person.surname, "Bebewicz");
173
19. Complex Data Types Amiga C for Beginners
Pointer The parentheses above control the higher precedence of the (.) operator.
operators Usually a special operator is used as illustrated below:
pointer->age = 30;
All operations which affect basic data types, such as defining arrays
(vectors), can be used on the newly created structure. The line below
provides 100 structures for storing partial variables:
occ_upa = occupant;
Comment: The name represents the address of the first element. The following
could be written as an alternative:
occ_upa = &occupant[0];
(pointer->income = 25000.0)
The pointer can be used to search the entire array. The following
example sets the pointer to the first free element, provided that in an
unused entry the value zero was stored in age:
while(pointer->age)
pointer++; /* searches all entries */
174
Abacus 19.2 Bit Fields
The last remaining data type is the bitfield. Bit fields are really a form
of structure definition. Unlike regular definitions, bit fields are usually
taken apart rather than created. A variable is defined which consists of a
certain number of bits. This variable always represents whole numbers.
The value range depends on the number of bits used. This number can
be calculated with the formula 2numbcr-of-bits. These fields are arranged in
int objects so that the maximum field width is 16 bits. This also
applies to Lattice C which usually has a different concept of int. If a
field doesn't fit into the partially occupied integer value, it goes into the
next one. A lot of memory can be saved by clever selection of the field
width.
struct {
unsigned sex : 1;
unsigned married : 1;
unsigned children : 4;
} data;
As in other structure definitions, the data types are placed inside braces.
To ensure that the bit field contains unsigned whole numbers,
unsigned is used (an abbreviation for unsigned int). A colon
separates the fieldname from the field width in bits. The definition
above occupies 2 bytes (size of a 16-bit integer), but is not completely
utilized. Since only 6 bits are used (1 + 1 + 4), an additional 10 bits
can be assigned for other applications without requiring additional
memory:
struct {
unsigned sex : 1;
unsigned married ; 1;
unsigned nr_children ; 4;
unsigned age ; 7;
unsigned nr_cars / 3;
} data;
Additional data has been stored which occupies only 2 bytes. Access to
each bit field occurs with the (.) operator.
data.nr_children =2;
175
19. Complex Data Types Amiga C for Beginners
19.3 Unions
union Universa {
in i;
double d;
struct Person;
char c[100];
} result;
result = 2.8;
or
strcpy(&result, c);
176
Abacus 19.4 Enum
19.4 Enum
The C word enum defines a data type which assigns constant values to
the variables. Short for ENUMeration, enum lets you assign a consis
tent integer number (constant) to a variable. This is useful for assigning
numbers to strings. The following example assigns numbers to the first
three words in color and a specific value to the black variable.
Finally, the assignment to the white variable continues where the
number assigned to black left off:
/* variable Definition */
var = blue
if(*color_ptr == green)
*color_ptr = black;
The enum type assigns ah integer value to each name starting at zero
and adding one for ieach element. With direct assignment values can be
skipped. The values defined in color are:
red 0
green 1
blue 2
black 9
white 10
177
19. Complex Data Types Amiga C for Beginners
19.5 Typedef
The typedef feature can be used to create new data type names. A
name assigned with this command can be used as another data type
during the definition. The program below gives the word float the
same meaning as the double data type:
All pointers to char elements can be defined simply with the word
STRING. The typedef command has an advantage over the
# define directive in that the definition of the replacement occurs in a
different way. One text can be replaced with another text. A blank
marks the spot in which the text replacement appears. The redefinition
of type string into another word isn't possible since everything after
the space behind char already counts as replacement text. With the
typedef command this is just the reverse. The last string STRING is
the replacement for the data type char *. It or the blanks in the middle
always belong to the definition of the data type.
178
20.
Important Concepts
Abacus 20. Important Concepts
20.1 Declarations
181
20. Important Concepts Amiga C for Beginners
long *field() ;
Decoding First, the variable field is a function. Look at the left side of the line
expressions for the asterisk which defines the expression as a function. This
function returns a pointer. No additional information exists beyond the
parentheses. The left side of the line identifies the data type long.
Together this information creates a function which returns a pointer to
the type long.
After processing one side of the line, the information to the right of it
must be processed (if priorities permit). The last and most complex
example looks like this:
int *(*text_arr []) () ;
Start with the name text_arr. First test which operators are pro
cessed first according to priority (to the right or left of the name). These
are the brackets which indicate an array. The operator has been processed
on the right; now go to the left. A pointer there indicates that this is a
pointer array. The right side of the line informs you that the pointers
should point to functions (the parentheses are required because of the
high priority of parentheses over the asterisk). Changing sides again,
you note that the function returns pointers. Since on the right side there
is no additional information, continue on the left with the data type.
There it shows that the pointers point to integers. This line declares an
array of pointers to functions which returns pointers to int. Compli
cated expression, complicated sentence; but simple to analyze.
Only data types which cannot be used in definitions as values for pass
ing are prohibited. For example, no function can be declared which
should pass structures, arrays or functions. Pointers to such objects are
permitted and are the only way to access this information.
182
Abacus 20. Important Concepts
Comment: Some new compilers also permit structure passing. This may differ
from one compiler to another. The expression & structure is always
the address of the structure, but structure can represent different
things. In the older compilers this represents the starting address, like
the expression with the address operator. If structure is passed
with a compiler that can already pass the data structure, the entire data
field is made available to the calling function (not just the 4 bytes
which represent the pointer to it).
183
20. Important Concepts Amiga C for Beginners
2 0.2 Initialization
This word should also look familiar from earlier chapters. Before you
continue, here's a brief reminder of just what initialization does.
int i;
i = 0;
int i = 0;
The variables used were already initialized or number would have con
tained an undefined value.
Braces can improve visibility for arrays and structures, and separate
individual entries from each other. A pair of braces must be placed
before and after the data which are transferred to the variables. A comma
follows the fields, even if the braces were used. After the initialization
there is a semicolon which is often omitted, causing compiler errors.
Some examples for correct structure definition:
struct CAR {
char make[16];
int hp;
int cylinder;
double price;
184
Abacus 20.2 Initialization
"BMW",
120,
4,
40000.0
struct CAR {
char make[16];
int hp;
int cylinder;
double price;
} will_have =
{
"BMW",
120,
4,
40000.0
};
185
21.
Pointer Arrays
Abacus 21. Pointer Arrays
You worked with pointers and arrays in earlier chapters. As the title
indicates, they can be combined to construct an array of pointers. You
may be wondering what you can do with a pointer array. If you market
ed an existing program in a foreign country, you'd have to find every
piece of text in the source code and translate the text into that foreign
language. It would be simpler and safer to store all the text in one area
of the program, or even in a separate file, and let the translator change
it from there. A pointer array would point toward that area or file.
Let's start with a list of error messages that the user might see after
entering incorrect input. The use of error numbers makes sense, since
some errors occur at several different locations. In the current program
portion, passing the error number to the error routine is sufficient
because the function should do the rest
One solution to this problem would be a function that tests the occur
rence of this error or another error, and display a message if necessary.
error(e_number)
int e_number;
{
switch(e_number)
{
case 0:
puts("Everything OK, no error!")/
break;
case 1:
puts("Wrong key activated!");
break;
case 2:
puts("Please insert diskette!");
break;
default:
puts(Unknown error occurred!");
189
21. Pointer Arrays Amiga C for Beginners
error(e_number)
in e_number;
{
puts(error[e_number]);
But the work which was saved here, must be completed elsewhere. Each
string must be initialized with the strcpy function. The following
command sequence shows how:
As a last resort, the string arrays can solve almost all the problems
mentioned above. The definition of a string array is as follows:
char *error[32];
The pointer can be set to the beginning of an error message and can
make the message length dependent on a fixed array length. The next
string starts immediately after the last character of the previous string.
This avoids initialization.
/* error_msg.c 21 */
char *error[] =
{
"Everything OK, no error!",
"Wrong key activated!",
"Please insert Diskette!"
190
Abacus 21. Pointer Arrays
main ()
{
/* Display all error messages */
int i, error_msg = sizeof(error) / sizeof(char
Since the number of error messages are not counted, they aren't indi
cated during the definition. Because of this, additional text can be
entered between braces without making changes. In the actual program,
however, the number must be calculated. The memory requirement of
error can be obtained from sizeof. The error function is now an
array of pointers. Now sizeof reports that the variable consumes 12
bytes. That is the memory requirement for any pointer, and has no bear
ing on the memory needed for the text The 12 bytes are divided by the
space requirement of a char pointer (which is 4 bytes). The result is
the number of pointers, the maximum index minus one (The indexes
start with 0).
191
22.
Useful Macros
Abacus 22. Useful Macros
Much work has already been done with #def ine. The substituted text,
called a macro, was kept simple; one word exchanged for another. But
that's only half the job, macros also allow you to pass arguments.
Some useful macros have been developed to make parameter passing
easier for the user.
Construction Functions that do little and have concise coding can be written as
of a macro macros. Since macros replace the original text, the compiler translates
the C code directly to machine language at that location. Function calls
or parameter passing is not required. The required directives are located
at the exact location in the program. This makes the macros faster and
more efficient than function calls. If used frequently, however, macros
make the pogram code much larger. The same operations are repeatedly
stored in identical form at the exact place where they are needed in the
program code. An advantage of macros is that they are usually
independent of data types. This condition can be seen in the example of
the max macro created earlier in the book:
result = MAX(il,i2)/
195
22. Useful Macros Amiga C for Beginners
If the macro call just defined included some parameters which contained
operators, errors could appear. For example:
The > comparison operator has a higher precedence than the I character.
This means that first a test is made to see whether i2 is less than 2.
The result of this logical comparison (0 if false, 1 if true) is then com
bined with il using OR, bit by bit. This could not occur in the basic
calculations since they have a higher precedence than the comparison
operators (see the Appendices for a table of all precedences). A simple
remedy is to place all parameters found in the macro inside parentheses.
Use this definition:
/*bad_macro.c 22.1 */
#define QUADRAT(x) ((x)*(x))
main()
The square of 0 is 0
The square of 2 is 6
The square of 4 is 20
196
Abacus 22.1 Macro Error Sources
The square of 6 is 42
The square of 8 is 72
The square of 10 is 110
Where's the mistake? Examine the material left by the preprocessor for
the compiler. The line with the macro is the important line:
It becomes:
2*3
You may have wondered why the program uses two printf calls
instead of making do with one. There is another error source here which
must be considered as a separate entity, otherwise this overview would
not cover all possible side-effects. To demonstrate the errors which
occur in printf functions, let's try this with the same function, but
without a macro:
main ()
As a result you get two squared numbers which don't match the desired
numbers. 4 is offered as 3's square (the square is only calculated for the
preceding number). This is caused by the parameters being placed on the
function's stack (temporary storage), where the function expects to find
them. Unfortunately the storage of these values occur in reverse order,
i.e., first i * i++ is stored, and i is incremented. Then the first
parameter of i, which already has the wrong value, appears.
197
22. Useful Macros Amiga C for Beginners
Frequently-used macros are best stored in a library, from which they can
easily be inserted in source code with #include. This group includes
various conversion functions for letters (e.g., testing if a letter is upper
or lowercase). The following defines have the following tasks:
Test for blank, tab, linefeed, carriage return, formfeed (yes = 1, no = 0):
198
Abacus 22.2 Library Macros
#include <ctype.h>
Remember that for the test for letters, only the 26 letters of the
alphabet are considered. International special characters are not viewed as
letters. Maybe they can be implemented in a suitable manner. Perhaps
the strcmp can be converted with the new defines.
199
23.
Communication
Abacus 23. Communication
23. Communication
The programs written so far have only displayed data on the screen or
requested keyboard input. It's time to communicate with other devices.
The CLI is the easiest way to transfer data. In this chapter, we'll
communicate with the CLI as well as other devices.
All programs are called from the CLI by entering the filename and
arguments (if needed). Here is one type of call to invoke ED:
This complete line can be made available to the called program, though
not in this form. The operating system modifies this line slightly.
Now comes the question of data transfer. The main function containing
two arguments controls this. Until now every call appeared as follows:
main()
The next code passes two values from the calling program from either
the CLI or a make file. The first value represents the amount of
information and a pointer to a char pointer. This sounds somewhat
complicated, but looking at the input line of the program should make
it clear. First the new version of main with two arguments:
main(argc, argv)
int argc;
char *argv[];
The name of our fictional program is prg. Look at this sample entry:
203
23. Communication Amiga C for Beginners
After the program call, the variable argc contains the number of argu
ments (5). Why is 5 passed when only 4 arguments are available? The
fifth argument comes from adding the program name used during the
call. The name argc (ARGument Count) is a random choice, since it
is an auto variable of the main function. The name argv (ARGu
ment Vector) handles vectors.
Spaces or tabs separate every argument of the input line. After the call
the pointers of * argv [] point to:
argv[0] "prg"
argv[l] "Textl"
argv[2] "Parameter"
argv[3] "3"
argv[4] "-pi"
Let's examine the data. Use the following program to print the data:
/* arg_test.c 23.1 */
main(argc, argv)
int argc;
char *argv[];
{
while(—argc >= 0)
puts(*argv++);
What can be done with this? You can access a small math program by
entering the following in the CLi:
/* arg_math.c 23.1 */
extern double atof(); /* Declaration */
main(argc, argv)
int argc;
char *argv[];
if (argc != 4)
printf("\nWrong Entry\nCall: numberl # number2\n");
else
204
Abacus 23.1 Passing Data with the CLI
double zl = atof(numberl);
double z2 = atof(number2);
case '/':
return(zl / z2);
case '*•:
return(zl * z2);
case '-':
return (zl - z2);
case '+•:
return (zl + z2);
default:
printf("\nUnknown Operator >%s<\n", 7, op);
error =1;
return (0.0);
lc -Lm math2
cc +L math2.c
In math2.o -lm -lc
205
23. Communication Amiga C for Beginners
This type of data transfer does a lot of work, even though it may not
seem evident at first. For example, all data selected for transfer to disk
goes to a buffer first. When this buffer completely fills, the data goes to
the disk. The question is, why do it this way?
A disk drive reads and writes information much slower than the com
puter can send or receive it. This is caused by the mechanics of the disk
drive. Before writing any data, the read/write head must move to the
track where the data is stored. Then it must wait until the disk rotates to
the right location. Only then can data be written. Although this timing
is brief in human terms, the computer (actually its central processing
unit or CPU) is kept waiting a very long time.
Disk buffers If you transmitted every character with this method, the computer would
spend more time waiting to place a single character on the disk drive
than performing any other task. For this reason, smaller amounts of
data move to an area of memory in the computer before transmission.
Once this buffer fills, the data moves to the disk drive. This reduces
computer waiting time. As soon as the drive writes the first character to
the proper place, it can place the other data right behind it and write the
complete buffer in one pass. This reduces the number of disk accesses,
which accelerates program execution. The same principle is also used
for reading data.
The functions which perform this job are get c and putc, which like
their relatives get char and putchar, input or output a character.
These functions are not part of the C language. For this reason they can
be found in a library, or in this case as a define in a header file (.h).
The definition of getc and putc can also be found in the stdio.h
file with the familiar putchar and get char.
206
Abacus 23.2 Buffered Input/Output
Let's clear some of this up. The definitions of put char and
get char are all you need to know for now. Both can be traced back to
getc and putc and represent special versions of the two functions.
Before the first character can be moved with these functions, a channel
must be opened. A channel is just a data line to a certain device. No
cables actually open up a channel, but the system knows where to send
the information. A special code obtained from the operating system
during the opening of the channel allows addressing the device at any
time. Devices and individual disk files can be addressed.
Several files can be addressed on the same drive without having data
conflict The file pointer indicates the channel. Since a buffer is used for
input/output, the computer must be informed of where the data should
be stored intermittently and how large a space must be reserved. A
structure named file (notice the uppercase letters) defined in stdio.h
contains all necessary data for buffered input/output. The following list
ing writes a file and then reads it again:
/*fprint-fscan.c 23.2.1 */
#include <stdio.h>
main ()
{
FILE *input, *output, *fopen();
char filename[81], text[200];
The f open The f open function opens the channel and returns the file pointer,
function used for all future access, to this file. Since f open returns something
other than an integer, it must be declared as a function which returns a
file pointer. This routine requires two arguments: the name of the file
and the access mode. The user can enter the name. The access mode tells
the computer what should be done with the file. The mode can be one
of three letters:
207
23. Communication Amiga C for Beginners
A file opened for reading (r) can only read data, not write data. A file
open for writing (w) lets you write data. The append (a) mode writes
data to the end of an existing file. In normal write (w) mode, writing
starts at the beginning of the file and overwrites existing data. This can
easily lead to loss of data. The example above overwrites an existing
file and destroys some previously stored data.
After the opening, the file is ready for writing. The file handle appears
on the screen. The scanf function assigns the characters entered
through the keyboard to the string text. The fprint f function can
write data to a file. It is almost identical to the printf routine, but
differs in the first argument. Before the command string, a file handle
must be passed to assign the information to the correct file. After
writing, the file closes. This step is very important because of the
buffer. All input/output goes there for intermediate storage until the
buffer is filled. Some of the data input can still be stored in that buffer.
If the user assumes that everything was stored on the disk and switches
off the computer, the data still in the buffer would be lost. For this
reason the f close call closes the channel after writing the remaining
buffer contents to the open file.
Now the file reopens again, but this time for reading which is signaled
with mode (r). Since keyboard input always uses scanf, the f scanf
is used here. First the file pointer and the arguments of the scanf
routine must be passed to the read function.
The correct closing of the file follows. If you omitted this instruction,
data loss cannot result. However, it's good practice to close an opened
file immediately after use, not only because it is good housekeeping,
but also because a computer can maintain only a certain number of
open files. If more files are opened, a channel cannot remain open at a
certain time. Should an error occur, because the operating system
cannot make a channel available, the file pointer is returned as zero.
This happens when no channels are available, or the file which should
be read does not exist.
208
Abacus 23.2 Buffered Input/Output
After opening the two files, a character is read and displayed immedi
ately, until.... You don't know when all data has been copied. How can
you detect when the last character has been read? The problem has
already been solved, f get c returns a special character if no additional
information is available—end of file (EOF). The #include file
stdio.h contains this text as a define so that the incoming charac
ters only have to be compared with EOF.
EOF is stored there as -1. This has consequences which at first are not
evident Valid data have codes which in fgetc are between 0 and 255.
When -1 appears, no char variable can be selected to accept the charac
ter. Either negative numbers are ignored or data is lost. For this reason,
int variables are used even if only a char element is stored in them.
/* copier.c 23.2.1 */
Hnclude <stdio.h>
main(argc, argv)
int argc;
char *argv[];
{
long copyO; /*If it is interesting */
if(argc !=3)
{
printf("Bad Arguments!\n");
printf("From_file to_file\n");
}
else
copy(argv[l], argv[2]);
209
23. Communication Amiga C for Beginners
fputc( c, output);
counter++;
fclose(input);
fclose(output);
printf("\n%ld Bytes copied!\n", counter);
return(counter);
210
Abacus 23.3 More Buffered Input/Output
Besides f getc, fputc, f scanf and fprintf there are some other
important functions that use the internal buffer. Among them are
f read and f write. These routines transport any number of bytes.
For this reason two additional arguments are required for f read and
fwrite. One argument is the area which serves as the buffer and the
other the size of the units to be transmitted. This needs some explana
tion. The buffer in previously used functions was always located in the
file structure. Since only small amounts of data were transported, the
buffer did not have to be large (512 bytes). Since the user can now
determine how much data is transmitted, this buffer may be too small.
For this reason the user must define the memory area, thereby setting
the maximum size of the data transfer. The data size must also be indi
cated. In getc and putc only one character can be transmitted (1 byte)
and the size of the char object doesn't have to be indicated. If a long
value, instead of a character, is stored, 40 bytes must be transmitted for
10 of these values. The object size (in this case four bytes each) is the
second argument that must be passed. If the data type is unknown, the
si zeof operator should be used because it returns the correct value.
The first argument is the buffer from which the data is read. The buffer
should be the same type as the units to be transmitted. The second
value is the unit size. This unit is a data package which can be trans
mitted as one item. If long variables are transmitted, it makes sense to
indicate 4 bytes as data block length, since 4 byte units are the normal
memory requirement. If 100 double variables are stored, 100 is placed
at the element. Finally a file pointer is added, which was received from
fopen.
If data is read or written, the argument sequence and type remains the
same. The fwrite function stores the data using this syntax:
211
23. Communication Amiga C for Beginners
sizeof(table)/sizeof(int)
/* fread.c 23.3 */
#include<stdio.h>
Long data[] =
{
4711, 815, 1024, 1, 31415926, 0, -13, 10,
OxFFFF, 065432
main ()
{
FILE *input, *output, *fopen();
int i;
long test[NUM_DATA];
char filename[81];
This program writes a long array to the file after entering the filename.
The array size and the number of elements appear on the screen. The
define num_data stores all data on the disk. After closing the file,
another array accepts the data read. All data appears on the monitor.
212
Abacus 23.4 Unbuffered Input/Output
Besides the buffered functions just demonstrated, there are other routines
which do not require a buffer. The data to be transmitted don't have to
be stored in a buffer, but can be stored immediately. This cancels all the
effort required for the buffer and internal pointers. This also cancels the
need for a file pointer through which the operating system can access
the buffer. A channel number assigned during the opening must be used
as identification. This channel number is stored in an integer variable
and replaces the file pointer in all calls. The open function opens a
file. Filename and file mode (as an integer) arguments pass to the
function. In f open the mode must be a string, while in open the
mode is one of three values: 0,1,2 or 8. These numbers correspond to
the strings r, w and a.
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_APPEND 8
To use these defines, the file must be included in the source with the
sequence:
#include <fcntl.h>
fopen("filename", "w")
The open function always prompts for the name of an existing file.
The create function must be used to create a new file.
The create function returns an integer (the file handle). You don't
need to call open. If an error occurs and the file cannot be opened, both
create and open return the value -1. Before using the returned value
as a file handle, check the file handle for a value of -1, or the system
213
23. Communication Amiga C for Beginners
A file opened in this manner allows writing using the write function
instead of the f write function. Since this method uses no buffer,
only certain input/output functions can be accessed. Also, the read
function replaces the f read function. Buffered functions have an f in
front of their name (e.g., f open, f read, f close). Unbuffered func
tions omit the f. The close function closes an unbuffered file.
/* write-read.c 23.4 */
#define NUMBER (sizeof(data)/sizeof(double))
double data[] =
{
1.5, 2.0, 3.14159265, 2.718281828,
main ()
{
int handle, dummy =0, i, actual;
double data2[NUMBER]/
char filename[81];
214
Abacus 23.4 Unbuffered Input/Output
The open and create functions, which return a file handle, have a
peculiar variable named dummy. This variable represents a value which
may be unnecessary, but the compiler checks for this variable if needed.
The value stored in dummy, as the name suggests, has no significance.
In open the second argument represents the dummy value for reading
or writing.
The write and read functions have one less argument than fwrite
and f read. Furthermore (and this is important), the file handle is
placed at the beginning, not at the end as in the buffered functions. The
unbuffered functions transport the data one byte at a time only. This
means that the size indication is unnecessary. The return value is the
number of bytes transmitted so far.
215
23. Communication Amiga C for Beginners
The following functions provide the user with the ability to directly
access certain characters in a file. The difference from the usual read
lies in the fact that not every character must be read starting at the
beginning of the file until the program finds the particular characters.
To access the last ten characters in a file of 1,000 characters, 990 char
acters would have to be read first. With direct access, the command
starts the reading after the 990th character. A file pointer always points
to the last accessed data. During a sequential read or write, when
one character after another is processed, this pointer always increments
by one. The functions lseek and f seek let the user set this pointer
to any desired position. Both routines require three arguments for this,
where lseek is the unbuffered version and f seek the buffered
version. For this reason lseek requires the file handle as the first
argument, while f seek expects a file pointer. A second value follows
the number of bytes by which the pointer must be moved. Positive
values move the pointer toward the end of the file, negative values
toward the beginning of the file. This value must be passed as a long
value. The third argument, an integer, indicates from which position the
movement should start. A 0 sets the data pointer to the beginning of
the file, 2 to the end of the file and 1 to the current position. Some
examples:
The data pointer moves to position 100 (i.e., 100 characters from the
start of the file). It now points to the 101st byte of the file. The follow
ing function places the pointer at position 70, since the call passed the
value 1:
The 1 indicates the calculation of the new pointer position from the
current location. To move the pointer 20 characters toward the begin
ning of the file, the following function is required:
If the processing of a file should start from the end of the file, the
pointer can be set to the last position of the file with:
This shows that in mode 2 (end of the file), only negative numbers or 0
are permitted since the pointer is already at the end of the file. In mode
0, only positive numbers or 0 can be used. These functions only move
216
Abacus 23.5 Direct Access
the file pointer. The data must be read or written with the various func
tions such as read or write.
The lseek function returns the value of the data pointer after the
move, f seek returns either 0 or -1. With -1 an error occurred, other
wise everything proceeded without a problem.
lseek(f_handle, OL, 1) ;
217
23. Communication Amiga C for Beginners
Our previous programs used scanf to read a character from the key
board. The problem with this is that you have to press the <Return>
key after every character. A word processing program would be
intolerable under these conditions. Even a modest application such as
controlling the cursor in all four directions would be difficult
The getchar The getchar function offers help. This function receives the pressed
function key's code immediately. Even here there is a difference between theory
and practice. Almost all other C implementations use this function
according to rules—except for the Amiga. The Amiga requires the
<Return> key for execution.
Usually data is entered through the keyboard into the computer. Mes
sages and the results of calculations usually appear on the screen. These
two devices combined are called the console. If you do not instruct the
computer to get the source data from or send the destination data to a
particular device, it defaults to the standard input/output (keyboard and
screen). The good news is that these devices can be changed by the user.
The Amiga can input data from another device instead of the keyboard.
Standard The standard input device is the keyboard. The standard output device is
devices the monitor screen, or screen for short. In various windows the output
defaults to the CLI window. This window is the standard output for
your previous programs. All CLI limitations also apply to your pro
gram. This causes the error in getchar.
The CLI is line-oriented. Data processes after you enter your input and
press the <Return> key. Anything can be typed in without the com
puter reporting, during input, that this isn't permitted. Press
<Ctrl><G> to make the screen blink. Even though these characters can
be entered, you cannot display them on the screen. If you try this, the
blinking function executes. The CLI is an input console which
processes whole lines and not single keys.
This rule of using only complete lines also applies to programs started
from the CLI. Now that you know why <Return> must be pressed, it's
time to create a user-defined window to solve this problem.
218
Abacus 23.7 A User Window
CON:
RAW:
These strings follow the open command in the CLI. They replace the
usual filenames and drive specifiers. The asterisk sends data directly to
the CLI window; a new window isn't created. Nothing has changed for
the input either. Opening an asterisk device only causes the same
trouble as before.
The CON: device creates a user window. The open call as listed below
creates an unbuffered open file and a pathname of CON:
The CON: device name replaces the drive specifier, and the new
window's coordinates follow. Finally the name Title line appears
in the upper left corner of the title bar. A slash character (/) separates
the window arguments. The other arguments such as 0 (read) and the
dummy value follow the usual syntax of the open routine.
The returned file handle appears in the examples with all read calls.
An 81-character string acts as a buffer. Try this short routine:
/*windowl.c 23.7.1 */
tdefine c *character
#define ESC 27
main ()
{
int dummy = 0, num, handle;
char character [81], line[256];
219
23. Communication Amiga C for Beginners
The raw: option also creates a window. The difference between this
option and CON: is the way the information is displayed. A raw:
window displays information in "unfiltered" form (i.e., control
characters and garbage appear). Change CON: to raw: in the above
example. Compile, link and run this new version and watch what
happens next
Again a new user window appears. You can size this window and move
it around the screen. Select the new window and send data to it (type on
the keyboard). Notice that the window reacts to every keypress. How
ever, the input doesn't appear in the user window. The program seems
to be ignoring the RAW: specification.
220
Abacus 23.7 A User Window
Now the user can write anything into his own window—the print f
function isn't required for output into the CLI window. Now every
thing needed for input/output in the new window is available. Here is
the corrected listing:
/* window3.c 23.7 */
#define ESC 2 7
main ()
{
int dummy = 0, num, handle;
char c, line[256];
{
num = read(handle, &c, 1);
/* write(handle, &c, 1); output only the character*/
sprintf(line, "Character >%c< Code %d\n", c, c);
write(handle, line, strlen(line));
} while (c !=ESC);
close(handle);
221
23. Communication Amiga C for Beginners
23.8 Redirection
Look again at the first RAW program above which used printf for
text output. This example will help you understand redirection.
program_name ,
Instructions that are executed by the operating system and not by the
program can follow the filename. The greater than (>) or less than (<)
characters precede these instructions. The characters inform the
operating system that the standard input/output should be modified.
Here's a practical example:
The program never sees these two arguments. The operating system
reads the standard input from f ilel and sends the output to f ile2.
The operating system also opens and closes the files automatically. The
greater than (>) and less than (<) characters indicate the direction of data,
as an arrow would indicate direction. You can immediately see that the
data goes to the filename f ile2. Let's examine this process using the
window2.c RAW program in the previous section. The printf can
be redirected so that all text goes to a file or a printer (device prt:).
Start the program (called window2 here) with the following line:
The new window appears again but no keypresses seem to affect the
window. That's all right, since the output which would otherwise
appear in the CLI window now goes to the file output .data. After
typing on the keyboard for a while, press the <Esc> key. The window
disappears and the user returns to the CLI. The output.data file can
now be read using the type or ED commands.
Input can also be redirected from the keyboard to a file. This is how a
make file could be created. In these programming examples this
wouldn't make sense since you don't read from the standard input. A
redirection would not make much sense in this case.
222
Abacus 23.8 Redirection
stdin
stdout
stderror
The stdin variable represents "standard input" and the stdout vari
able represents "standard output." What is the third?
All three variables (stdin, stdout and stderr) can be used as file
pointers which are returned through f open.
Caution: These buffered input/output routines should not be confused with the
unbuffered ones. Permitted functions with the file pointers above would
be f printf, fwrite, f read, etc.
getc(stdin)
223
24.
Tricks and Tips
Abacus 24. Tricks and Tips
You'll find that this chapter contains a number of tips and tricks for C
programming on the Amiga. These tips include the creation of C
programs that are accessible from the Workbench, preprocessor
directives and macros.
You may have already tried to start your own C program from the
Workbench. Perhaps you wondered why, despite a full disk, nothing
appeared in that drawer's window. The reason for this is that every
visible program has an additional file used for storing the program's in
formation and icon data. Every program which appears in a Workbench
window has a file with the extension of .info.
Our C programs also need .info files before they can be accessed from
the Workbench. Select a suitable icon on the Workbench (the clock or
Notepad, for example). Any other icon can be selected for this program.
Now enter the CLI. Copy only the source .info file to an .info file
for your file. Remember to use the .info extension for both files in
this command. The example below copies the Notepad.inf o file to
a new .info file for the file test-workb:
Quit the CLI. Click the disk icon containing the target file and .info
file to display the icon. If the icon is covering another icon, move it to
a free location in the window. Click once on the icon. Press a <Shift>
key and click on a disk icon. Select Snapshot from the Special
menu to save the new position.
The following program will tell you how it was accessed, from the
Workbench or from the CLI.
227
24. Tricks and Tips Amiga C for Beginners
/*access.c 24.1 */
#include "stdio.h"
main(argc, argv)
int argc;
char *argv[];
{ int dummy = 0, handle;
char line[256];
else
else
Start the program window2, from the previous chapter, which opens a
window. The Workbench creates an additional, useless window. One
window is used, the other remains empty. There must be an option of
sensing a program start from the Workbench or from the CLI.
In the first case you get a window automatically and the standard input/
output is automatically directed to this window. The basic functions
such as scanf and printf can be used, and you can still enjoy the
use of your own window. In the second case, the user must handle his
own window and input/output.
228
Abacus 24.2 Other Preprocessor Directives
#undef MACRO
Undefining This is the opposite of #def ine. This undefines (cancels) the macro
definition. Assume that two #define directives had been used as
follows:
#define EOS 0
#undef EOS
the defined EOS is still present, but now with the first assignment (0).
#ifdef MACRO
#elseif MACRO
#endif MACRO
If the macro is unknown at this point, all lines are skipped up to the
following directives. Ifan#elseif appears the subsequent source
code is compiled up to the #endif.
if 0
else
229
24. Tricks and Tips Amiga C for Beginners
The commands themselves have nothing to do with the final code. The
reversal of the process makes the following line possible:
#ifndef MACRO
Here the macro cannot be defined, so the part following can be com
piled. Certain parts of a file can be included or left out through the
setting of a define, without changing the file to a great extent.
Where are the directives used?
230
Abacus 243 Finding and Removing Errors
Missing semicolon
If the semicolon is not missing in the line indicated, check one or two
lines above the line stated by the compiler and check the level of paren
theses.
This error often requires a search of the whole area preceding the error. If
you omitted a brace somewhere, the following part is added to the
function described up to this point. This in turn leads to mysterious
error messages, for example the missing semicolon in the next function
definition.
• Wrong answers
==and =
&Sc and&
I I and I
Watch for the legal maximum values of the various data types in calcu
lations. They may differ from one compiler to another:
231
24. Tricks and Tips Amiga C for Beginners
i = (x * y * z - z) / y - x;
• System crash
232
25.
System
Programming
Abacus 25. System Programming
Intuition This chapter takes you into the world of Intuition. Intuition is the
section of the operating system that is concerned with windows,
screens, icons, gadgets, menus and the mouse. Intuition's capabilities
are so vast that we can explore only a small portion of this material.
You'll find additional references suggested if you wish to explore
further. We chose to limit ourselves to introductory material on
Intuition, especially the creation of windows and screens.
235
25. System Programming Amiga C for Beginners
struct NewWindow
{
SHORT LeftEdge, TopEdge;
SHORT Width, Height;
UBYTE DetailPen, BlockPen;
ULONG IDCMPFlags;
ULONG Flags;
struct Gadget *FirstGadget;
struct Image *CheckMark;
UBYTE *Title;
struct Screen *Screen;
struct BitMap *BitMap;
SHORT MinWidth, MinHeight;
SHORT MaxWidth, MaxHeight;
USHORT Type;
}
The The structure definition can be found in the header file intuition/
NewWindow intuition.h. Now let's filter out the items that we are really going
structure to use. The name is already remarkable: NewWindow. The same file
usually contains a structure named Window. You need the
NewWindow structure to define a new user window.
The first four entries represent the upper left corner and the window's
dimensions in height and width. These are the same values as those
used in the CLl's Open command:
open("CON:20/40/200/50/windowtitle"f 0, 0);
To use the same values for the Intuition window, the values are
assigned to the structure components. The following definition precedes
the window description:
236
Abacus 25.2 A Window under Intuition
The capabilities a CLI Open command can't provide are color settings
for the window.
The values in DetailPen specify the window title and the height of
the title bar. The number describes the color register index. If 4 possible
colors are available, they are numbered from 0 to 3. The colors cannot
be changed because they're determined by the settings in Preferences.
The background always occupies register 0. The BlockPen register
draws the color for the window's border.
The next entry (iDCMPFlags) will be skipped since it isn't used. The
element Flags in the NewWindow structure determine certain items
in the window, which are set with defines. Every define deter
mines whether or not an Intuition function is required (e.g., WINDOW-
SI z ING). Look at the defines used in the sample program.
Smart Refresh This causes the Amiga to control and store everything concerning
window changes and contents. If another window is dragged over the
user window, a part of the window may be temporarily obscured. The
computer automatically stores this area in a buffer and, if needed, will
restore it again.
Activate This automatically activates the window once its opened. This saves the
user the trouble of clicking the window to activate it.
windowdepth The window can be moved in front of or behind other windows with the
front and back gadgets (the gadgets in the upper right corner). The oper
ating system keeps watch over these gadgets for any activity.
237
25. System Programming Amiga C for Beginners
After this preliminary work, the window can finally be opened. The
Openwindow function opens the window and returns a pointer. This
pointer points to a window structure but shouldn't be confused with
NewWindow. It is more comprehensive than NewWindow and can be
examined in intuition.h.
1&NewWindow
If everything was processed properly, the new window will have the
specifications which were entered in NewWindow.
The Closewindow function is all you need to close the window again
(e.g., when the program is finished). It has the window pointer as its
only parameter. The window disappears again.
Finally the Intuition library closes to leave everything the way it was
found. If you close Intuition before closing the last window, the Guru
Meditation appears.
238
Abacus 25.2 A Window under Intuition
/* window_intuition.c 25.2.3 */
/* From Amiga C for Beginners */
/* by Abacus */
tinclude <exec/types.h>
#include <intuition/intuition.h>
#define INTUITION_REV 0
main()
{
struct NewWindow NewWindow;
struct Window *Window;
long i;
if(IntuitionBase = NULL)
exit (FALSE) ;
NewWindow.LeftEdge « 20;
NewWindow.TopEdge =20;
NewWindow. Width = 200;
NewWindow.Height = 80;
NewWindow.DetailPen = 0;
NewWindow.BlockPen = 2;
NewWindow.IDCMPFlags = NULL;
NewWindow.Flags = SMARTJREFRESH | ACTIVATE |
WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH |
NOCAREREFRESH;
NewWindow. FirstGadget = NULL;
NewWindow. CheckMark = NULL;
NewWindow.Title = (UBYTE *) "The User window";
NewWindow. Screen = NULL;
NewWindow. BitMap = NULL;
NewWindow. MinWidth =80;
NewWindow.MinHeight - 25;
NewWindow.MaxWidth = 640;
NewWindow.MaxHeight = 200; /* PAL - change to 256 */
NewWindow.Type - WBENCHSCREEN;
239
25. System Programming Amiga C for Beginners
CloseWindow(Window);
CloseLibrary(IntuitionBase);
exit (TRUE) ;
During the opening of the library, the routine wants a version number
which is required for proper processing. If the system has the same or
later version, everything proceeds smoothly. Since this program has no
special needs, a 0 is selected.
240
Abacus 25.2 A Window under Intuition
significantly. Unless the user has a RAM disk on which all include
files are stored, it is not advisable to do this because nothing changes in
the object code anyway.
After the general framework of the window program has been con
structed, some experimentation is helpful. Change a few values in the
NewWindow structure to see the effect on the window. Leave the
unknown structure entries and the type element untouched.
241
25. System Programming Amiga C for Beginners
25.3 Screens
The user can specify these values for each program in order to construct
a screen to personal taste. The number of colors depends on the number
of available bit-planes. A bit-plane represents a part of memory which
is used for storing graphics. More memory permits more bit-planes and
therefore more colors. The Workbench uses two bit-planes for four
colors. A table illustrates the connection between colors and bit-planes.
Not only can the number of colors be selected, but also the resolution
of the screen. You can reach a maximum of 32 colors and a resolution
of 640*400 pixels (640*512 pixels in PAL systems.) As in the win
dow, two color registers can be assigned, which are responsible for the
borders and the background. Since these values which are stored in the
NewScreen structure strongly remind you of the NewWindow struc
ture, let's look at the structure definition.
struct NewScreen
242
Abacus 253 Screens
The first entries in this structure have the same names as those in
NewWindow. They also have exactly the same meanings. Depth
indicates the number of bit-planes (1-5), which were already discussed.
DetailPen and BlockPen are the color indices. They depend on the
number of available bit-planes.
The listing for the subject of screens has some more enhancements
which will be explained now.
/* screen_intuition.c 25.3.1 */
/* From Amiga C for Beginners */
/* by Abacus */
243
25. System Programming Amiga C for Beginners
tinclude <exec/types.h>
#include <intuition/intuition.h>
#define INTUITION_REV 0
main ()
{
struct Screen *Screen;
struct Window *Window;
244
Abacus 25.3 Screens
Wait (1 « Window->UserPort->mp_SigBit) ;
Clicking the close gadget is the only way out. As in the window
program, all flags are set, which permit the user to change the size and
position of the window. The window pointer points to the desired
elements Lef tEdge, TopEdge, width and Height.
245
25. System Programming Amiga C for Beginners
25.4.1 Text
Window->RPort
25.4.2 Move
The string passed by text appears at the current cursor position. The
Move function sets this position using this syntax:
Before each call of the Text function, Move should position the
cursor. A small routine for this task follows:
text(w_j?tr, sf xr y)
struct Window *w_ptr;
char *s;
int xf y;
{
Move(w_ptr->RPort, x, y);
Text(wjptr->RPort, s, strlen(s));
246
Abacus 25.4 Text/Graphic Window Display
To keep the function generic, the pointer to the window in which the
text should appear is passed. Because of this you can service several
windows with the same function. A call appears as follows:
The text appears at position (20/40), if the window will allow it (the if
is important). You can write as much text as you wish in the window.
Intuition ensures that no window or screen is overwritten. If the text
can't be displayed completely in the window, the writing stops at the
window's right border. The user can be assured that nothing is
accidentally drawn in other windows.
25.4.3 Draw
The Draw function draws lines. The parameters of the routine are:
Draw(Window->RPort, x, y);
For drawing, the mouse coordinates are normally needed. They are found
in mouseX and mouseY which are two elements of the window
structure. This includes everything needed to write into a window.
In the following program argv and argc reappear. These other values
can be used from the CLI rather than the preset values. The call has the
following format:
for example:
247
25. System Programming Amiga C for Beginners
/* draw.c 25.4.3 */
/* From Amiga C for Beginners */
/* by Abacus */
#include <exec/types.h>
#include <intuition/intuition.h>
"topaz, font",
TOPAZ_SIXTY,
FS_NORMAL,
FPF ROMFONT,
UBYTE screentitle[81];
248
Abacus 25.4 Text/Graphic Window Display
if (argc != 4)
{
printf("Error in arguments\n");
printf("X-Res Y-Res Bitplanes\n");
else
NewScreen.Width = atoi(argv[1]);
NewScreen.Height = atoi(argv[2]);
NewScreen.Depth = atoi(argv[3]);
if(NewScreen.Depth > 4 || NewScreen.Depth < 1)
NewScreen.Depth =2;
color = 1 « NewScreen.Depth;
NewScreen.DetailPen = color - 1;
NewScreen.BlockPen = color - 2;
249
25. System Programming Amiga C for Beginners
if (argc — 4)
{
NewWindow. Width = Screen->Width/2;
NewWindow.Height = Screen->Height/3;
NewWindow. MinWidth « Screen->Width/3;
NewWindow.MinHeight = Screen->Height/5;
NewWindow. MaxWidth = Screen->Width;
NewWindow.MaxHeight = Screen->Height;
text(Window,"Hello there!",20,20);
CloseWindow (Window) ;
/* Close everything in sequence*/
CloseScreen(Screen);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
exit (TRUE) ;
text(w_ptr, s, x, y)
struct Window *w_ptr;
char *s;
int x, y;
{
Move (w__ptr->RPort, x, y) ;
Text(w_ptr->RPort, s, strlen(s));
250
Abacus 25.4 Text/Graphic Window Display
Notice the new structure TextAttr with the variable Font. Every
NewScreen structure has, among other things, a component named
Font. Here the character set to be used can be stored (address of the
structure). Of course this is again a pointer to another structure,
TextAttr.
The structure for the definition of a character set is very simple. First
there is the name of the font, then the height of the character and the
manner of presentation. Finally a flag marks the location of the charac
ter set. We used the character set built into ROM. This font is used in
the 60 character screen setting. It's somewhat larger than the 80
character version. Eighty characters can be displayed if you use
topaz_eighty instead of topaz_sixty.
As soon as the window is opened, the text appears. The mouse can be
used to draw something. As long as the mouse pointer doesn't move
beyond the upper or left border of the window, a line will be drawn. The
mouse position is always indicated in the title line. This is not
absolute, but relative to the upper left corner of the window. For this
reason a negative value is possible when the mouse is pushed beyond
the left or upper border. The program uses this as an end criterion.
251
25. System Programming Amiga C for Beginners
NewScreen.ViewModes = LACE;
With 32 colors, a function which permits changing the color of the pen
would be useful. This input changes the current color in the color regis
ter
SetAPen(Window->RPort, color);
To see this routine in action, a new program must be written. Add the
following lines to the drawing program. First, at the beginning of the
main function, add the definition of a variable named colour:
At the end of the while loop add two additional lines. Here is the
complete loop:
252
Abacus 25.4 Text/Graphic Window Display
to
Since many colors and high resolution require a large amount of mem
ory, here are some examples of memory usage by windows and screens.
ReadPixel(Window->KPort, x, y);
WritePixel (Window->RPort, x, y);
253
25. System Programming Amiga C for Beginners
ReadPixel ReadPixel tests whether the indicated position of apixel was set and
returns the color value of the pixel. If no pixel was visible, because the
pixel has the same color as the background, ReadPixel returns a 0 to
the register number. If the pixel is outside the window whose port is
passed, the result is -1.
WritePixel WritePixel sets a single pixel at the position indicated. The color
used depends on the-current color as in all other routines and is deter
mined by SetAPen.
The following is a program which changes the title line of the window
used in a sine format
/* pixel.c 25.4.6 */
/* From Amiga C for Beginners */
/* by Abacus */
#include <exec/types.h>
#include <intuition/intuition.h>
#define INTUITION_REV 0
#define GRAPHICS_REV 0
main()
{
struct Window *Window;
register struct RastPort *r;
254
Abacus 25.4 Text/Graphic Window Display
r = Window->RPort;
top = Window->Height / 4;
factor = 2 * 3.1415926 / Window->Width * 1.5;
/* 1.5 Sine Waves */
for(j = 0,
yoffset = top + top * sin(factor * i) + 16;
j < top; j++)
if(colors[j]) /* If Pixel should be set */
SetAPen(r, colors[j]);
WritePixel(r, i, j + yoffset);
Lattice The library for mathematical functions and floating point numbers must
be linked with the standard library. Example:
lc -Lm math2
255
25. System Programming Amiga C for Beginners
Aztec If you work with the Aztec compiler, the library for mathematical func
tions and floating point numbers must be linked with the standard
library c.lib. Example:
cc +L math2.c
In math2.o -lm -lc
How the The program runs under the Workbench screen and uses its colors. Two
program bit-planes (four colors) are the default. If the user constructed a Work
works: bench which deviates from this, the define WB__COLORS must be
adjusted accordingly. The window which was defined in the NewWin-
dow structure contains only front and back gadgets. The size cannot be
changed.
In a large loop which processes the complete width of the window, all
pixels belonging to one X position are gathered in one array. Before the
value which is returned from the ReadPixel is stored, a color trans
formation is made. Every pixel gets the color from the following regis
ter. The area of the display which is transmitted, is the upper quarter of
the window. To prevent mix-ups between the information to be read and
written, a complete column is first saved into the array colors. Then
the new position of the pixels is calculated using the sin (sine) func
tion. The dots are written in the new color with WritePixel at the
new position. The pixels which are the same color as the background
are taken out. This is tested first to increase the speed. The program
will display the top line as a sine wave.
256
Abacus 25.5 DOS
25.5 DOS
result = DeleteFile(filename);
257
25. System Programming Amiga C for Beginners
25.6 SetComment
/* makecom.c 25.6 */
/* From Amiga C for Beginners */
/* by Abacus */
#include <libraries/dos.h>
main(argc, argv)
int argc;
char *argv[];
{
if(argc = 3)
{
if(!SetComment(argv[1], argv[2]))
printf("Error %d\n", IoErr());
}
else
printf("Format: MAKECOM FILE COMMENT\n");
exit(TRUE);
The filename and the comment passes to the program through the
command line. As in all data transfers, the use of spaces in the actual
comment is not permitted. Here is a sample call:
258
Abacus 25.7 Read Directory
Many programs that handle files should have a routine for reading disk
directories. To make this possible in a program, various functions are
required
First there is the Lock function. Lock locks the specified directory for
access. Only after the Lock can other functions operate on the direc
tory. The name of the directory and the access mode are passed to
Lock. Finally an integer value for read is passed with the define
ACCES Spread. The returned key permits the processing of this one
directory, similar to a handle for file accesses or a window pointer under
Intuition. If this key is equal to zero, an error has occurred.
struct FilelnfoBlock {
LONG fib_DiskKey;
LONG fib_DirEntryType;
char fib_FileName[108];
LONG fib_Protection;
LONG fib_EntryType;
LONG fib_Size;
LONG fib_NumBlocks;
struct DateStamp fib_Date;
char fibjComment[116];
259
25. System Programming Amiga C for Beginners
R W £ D
8 4 2 1
R - Read W - Write E - Execute D - Delete
For every protective action one of the bits above must be set. For
example if a file or directory can only be read or erased, the flags W and
E must be set:
RWED
0110 (bits) =4+2=6
This variable must contain the value 6. It is important to set the flag
whose function is forbidden. To make changes please use the protect
command from the CLI. The flags which are passed with this program
are changed in such a manner that the functions can be performed. This
is exactly the opposite of their use in the user program. To protect a
file from erasing, the following line is required:
PROTECT ED RWE
The f ib__Date function contains the date when the file was last
written.
You now have all the information needed to construct the final pro
gram. For the sake of simplicity we use parameter passing with the
command line in this version. This parameter indicates the directory
which should be read.
/* readjdir.c 25.7 */
/* From Amiga C for Beginners */
/* by Abacus */
#include <libraries/dos.h>
260
Abacus 25.7 Read Directory
strcpy(filepath, argv[l]);
else
strcpy(filepath, "sys:");
exit (TRUE) ;
output ()
{
if (!*fi.fib__FileName) /* strlen = 0 */
{
printf ("Empty! \n") ;
/* for example Root-directory of RAM Disk */
return(0); /* That's directory without name */
}
if (fi.fibJDirEntryType > 0)
printf("Directory name");
else
printf("Filename ");
The protect flags are not decoded separately in this program (it wouldn't
be a problem to do that), but are presented as a hexadecimal number (the
"%lx" format instruction). You can enhance this program if you wish.
The flags can be displayed in RWED format using the LIST command
from the CLI. With protect any flag can be set and with LIST the
result can be observed. This information can be compared with the
results from the user program.
261
25. System Programming Amiga C for Beginners
25.8 Conclusion
You now have the general knowledge needed to write simple programs
in C language. As you take time to develop your own programs,
functions and libraries, keep this book nearby for reference. Since it's
difficult to memorize everything about a language, this book will help
you with the complex concepts of C language.
You may be wondering why we didn't spend more time with some
aspects of the Amiga. We admit that we didn't include as much about
the operating system and Intuition as we would have liked. However,
these are difficult concepts for a beginner to understand, and we felt it
best to just give the reader a few general examples controlling these
areas in C. Since C is a transportable language, you may prefer to write
transportable source codes.
Dirk Schaun
262
Appendices
Abacus Appendix A: Functions
A. Functions
Filename: strlen. c
/*****•*•*****•*••**
/* Name: strlen */
/* Parameter: s (String) */
/* Return value: Length (int) */
/* Function: Number of characters in "s" */
/* Other: - */
strlen(s)
char s[];
{
register int i = 0;
while(s[i])
i++;
return(i);
Filename: strcpy. c
/•••a******************
/* Name: strcpy */
/* Parameter: s (String), t (String) */
/* Return value: - */
/* Function: Copies "s" to "t" */
/* Other: - */
/•He*****************************************************/
strcpy (t,s)
register char *t,*s;
{
while(*t++ = *s++)
Filename: streat. c
/••••••••a*********
/* Name:. strcat */
/* Parameter: s (String), t (String) */
/* Return value: - */
/* Function: attach "t" to "s" */
/* Other: - */
/•••••••it*********************************************/
strcat(s,t)
265
Appendix A: Functions Amiga C for Beginners
while(*s)
while(*s++ = *t++);
Filename: letter. c
/ ml*
t
ml* ml* ml*
7t 7% 7*
ml* ml* ml* mlm *1* ml* ml* mlU ml* ml* ml* ml* ml* ml* ml* «W ^U ^U ^U mi* •**• «A» *m^ •£• ^U ^U m^ mfa
*T 7* 7* 7* 7* 7C 7* 7* 7* 7s 7* 7* 7* 7% 7* 7* W *K W^ 7* 7* n ^^^^WW
^U ^L ^U ^L ^L ^L ^U ^L
w«^^««^^
^L ^L ^L X ^U ^L mfa
^*%*%#****»*^ ^»
^L
*^
-1* «JL JU
r* r*
aJU iJU *JU /
-%*%*-•-*»*
/* Name: letter */
/* Parameter: z (char) */
/* Return value: It was a letter (1), else (0) */
/* Function: Determines if it was a letter or not */
/* Other: - */
t 7* 7lf tV 7* 7% 7* *K 7* 7V fC 7* 7* 7* 7* 7* 7T 7* *rC 7* 7C 7% 71T 7V 7* TV 7% 7* iflf 7* 7* TT 7* 7* 7* 7* 7C ^* 7* 7C 7C 7C 7* 7C 7* 7* ^^ w^ W^ 7* 7* 7* *5 « ^ ^
#define FALSE 0
#define TRUE 1
letter(z)
register char z;
if ((z >= 'a' && z <=Jz') || (z >= 'A1 && z <= 'Z'))
return(TRUE);
return(FALSE);
Filename: c_comp. c
/* Name: c_comp */
/* Parameter: cl (char), c2 (char) */
/* Return value: 1 (TRUE).-, 0 (FALSE) */
/* Function: Compares two characters */
/* Other: requires two characters () */
#define FALSE 0
#define TRUE 1
extern int grklflag;
c_comp(cl,c2)
register char cl,c2;
266
Abacus Appendix A: Functions
Filename: strcmp. c
/••it**************************************************/
/* Name: strcmp */
/* Parameter: s (String), t (String) */
/* Return value: identical 0 not identical 1 */
/* Function: Compares "s" and "t" */
/* Other: - */
i Tip TV Tip TV TV TV Tip TV TPC Tip TPC TV TV Tip TPC TV TV TPC * TV TV TBT TV TV TAP TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV ^% ^% ^* ^* ^s ^s ^c w w ^ w ^
strcmp(s,t)
register char *s, *t;
{
register int identical;
while(identical = c_comp(*s, *t++) )
if(!*s++)
return(0);
return(!identical);
Filename: strchar.c
/* Name: strchar */
/* Parameter: s (String), c (char) */
/* Return value: Position (int), or -1 */
/* Function: Determines Pos of the Char "c" in "s"*/
/* Other: - */
/**************************************************** /
strchar(s,c)
register char s[];
register char c;
{
register int i = 0;
while(!c_comp(s[i],c) && s[i])
i++;
if(s[i]) return (i);
return (-1);
Filename: strchbac. c
/••*••**••****•*•***•*••*••*••****•*•***•******•******•/
/* Name: strchback */
/* Parameter: s (String), c (char) */
/* Return value: Index (int) */
/* Function: Searches for Pos of Char "c" in "s" */
/* Other: requires c_comp(), strlenO */
j ^^ "^ ^* "^ ^* ^* " ^* ** *^ *f *^ *■ *f *^* sV <P» •*■ *P» <™ *V TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV TV /
strchback(s,c)
register char s[];
267
Appendix A: Functions Amiga C for Beginners
register char c;
{
register int i = strlen(s);
while((i >= 0) && !c_comp(s[i], c) )
i—;
return(i); /* Error = -1 */
Filename: il at oil a. c
j ^^ ^ ^* ^* ^* ^* " ^^ ** *f ** <RT TP T*P iK rt <K <K «PT *P <PP ?C wC 7K TIP TIP Tip TIT TIP TV TIP TPC Tif ^C ^PP Tip wC "wC *C TIP TPP #t TPp Tip TBT *t #t Tip TlP #C Tl* Tip /
/* Name: ltoa */
/* Parameter: n (long), s (String) */
/* Return value: - */
/* Function: Converts long value to char string */
/* Other: requires reverse() */
/ <^ ^ ^ ^ ^^ ^ ^^ ^ ^ ^ ^ ^^ J^ JL JU JL J^ JL <JL JL JL ^U mlf JL JU JU JU JL JL JU JL JL JU J^ JL JU JL JU JU JU JL OL JL JL JU ^U ^U ^U ^U ^L ^U ^u ^> ^U ^L $
#define TRUE 1
#define EOS '\0'
ltoa(n, s)
register char s[];
register long n;
{
register int i = 0;
register int forechar =0;
if (n < 0)
{
forechar = TRUE;
n = -n;
}
do
{
s[i++] = n % 10 + '01/
} while((n /= 10) > 0);
if (forechar )
s[i++] = '-■;
s[i] = EOS;
reverse(s);
/********************•***************•**********•*******/
/* Name: itoa */
/* Parameter: n (int), s (String) */
/* Return value: - */
/* Function: Converts integer number to char string */
/* Other: requires ltoa() */
itoa(n, s)
register int n;
register char s[];
{
ltoa ((long) (n),s);
268
Abacus Appendix A: Functions
Name: atol
Parameter: s (String)
Return value: n (long)
Function: Converts char string into long value */
Other: */
long atol(s)
register char *s;
/*
/* Name: atoi */
/* Parameter: s (String) */
/* Return value: Integer number */
/* Function: Converts Char string into Integer */
/* Other: - */
atoi(s)
register char *s;
long atol () /
return(atol(s));
269
Appendix B: The History of C Amiga C for Beginners
B . The History of C
C became popular with the introduction of the Amiga and the Atari ST,
whose operating systems were written in C. The Amiga's Intuition user
interface was written almost completely in C. Professional program
mers and software houses prefer using C to develop new programming
projects. C has another advantage: it is portable. This means that C
programs can, theoretically, be transferred to other computers and
compiled there without changes.
The reason for this is that C has a small number of commands available
to all compilers. Parts which are computer specific, such as input and
output, don't belong to the actual C language. These routines are
delivered with the language in libraries adapted to the peculiarities of the
particular computer. The C programmer doesn't have to be concerned
about this. He knows that the get char function gets a character from
the key-board, regardless of whether the program is executing on a C64,
an IBM PC, an Amiga or an Atari ST. This portability means less
programming for the developers—just transfer the program over to
another computer, make the changes needed for the new computer and
recompile it.
How a C Every C compiler has been split into various program portions which,
compiler depending on the manufacturer, are available either in a program module
works or in several smaller programs.
The first part of a C compiler is the preprocessor; this only replaces one
text portion with another according to the user's commands. The result
of this effort is a file containing pure text which can be processed with
the editor. This result passes to the scanner which searches for com
mand words specific to C. It recognizes these words and stores them in
270
Abacus Appendix B: The History of C
Parser After completing this test run, the parser appears. It tests the source
code commands for correct syntax, and differentiates between correct and
incorrect combinations of C commands. The parser knows all the rules
about C syntax. Just as in everyday conversation, stringing words
together isn't enough. The parser ensures that the expression is correct.
As the last part of the actual C compiler, the code generator converts
the text processed by the parser into machine language commands.
Some C compilers first translate the machine language commands into
assembly language so the programmer can streamline the generated
code. This is really unnecessary since the C compilers on the market
already produce very efficient machine language code. After completing
this run, the compiler saves the object file to disk with the extension of
-\ :< .o. •..•.•
The final process is linking the object files with the required libraries to
produce an executable program. The linker is used for this purpose.
271
Appendix C: The Lattice C Compiler Amiga C for Beginners
The C The C compiler is called with lc and the source filename. As a mini-
compiler mum the following is required:
lc hello
With the -L option, the linker can be loaded immediately after the call
of the C compiler. The linker (here BLINK) can also be called indepen
dently. This is a standard call to compile and link a source code named
math2.c into a program named math2.
When the library for mathematical functions and floating point numbers
must be linked with the standard library, the following can be used:
lc -Lm math2
The linker The program BLINK provides a powerful linker for the programmer.
Here are the most important options available in this linker:
After the name BLINK all files which are linked together appear after
the FROM argument (or ROOT, or even nothing). The name of the pro
gram to be executed follows the TO argument. Library files to be
searched are listed after the library argument. Some sample calls:
Using the parameter with all options can be stored in a file just as in a
MAKE file. A linker call is then:
ROOT a,b,c
TO folder/prg
LIBRARY system/lib,obj/special
272
Abacus Appendix D: The Aztec C Compiler
The compiler The compiler with the name CC can be found in directory C:. The call
is very simple:
cc file.c
The source file file.c is compiled and translated into assembly code.
This code can be optimized by a machine language programmer. This
file has the name ctmpAXX.XXX, where X is a number which differs
from one call to the next. It is best to look at the current directory
because this name is needed immediately.
Also Aztec uses symbolic names for devices which are listed as
follows:
CLIB
INCLUDE
CCTEMP
-Ipath:
With -la pathname can be provided in which the Include files
are assumed to be. The search for these files is made only in this
sub-directory. The option is comparable with the assignment
include (see above).
Note: The pathname immediately follows the I without any additional spaces.
For example:
cc -Iram:includes/privat/
273
Appendix D: The Aztec C Compiler Amiga C for Beginners
+C creates longer code, since jumps within the program code arc
equipped with 32-bit commands instead of the 16-bit commands
which could have been used.
cc -DTESTRUN-1 filo.c
#define TESTRUN 1
The assembler After the C compiler comes the assembler which is named AS. It is
also stored in the C: directory. The call is similar to the C compiler:
as file.o
With the option -o a new name can be given to the new file. Example:
as -0 program.o ctmpxyz.12 3
The linker For Aztec the linker provided is called In and can be found in the C:
sub-directory. The files to be linked together are placed one behind the
other. Whether they are libraries or modules doesn't matter in principle,
but libraries should be placed at the end of the list.
274
Abacus Appendix D: The Aztec C Compiler
In file.o c.lib
The standard file c.lib is also like all other libraries in the lib:
directory. Several modules can be linked together
The name assignment for the resulting program is performed with ~O.
The linker can be informed about libraries with -L, but the extension
of .lib is then omitted. Example:
c Program
d Initialized data
The +C stands for chip memory, +F for fast memory. These two
groups of RAM areas are especially important for graphic programming
since certain data must always be stored in the chip-memory. With this
option the following can be requested:
This causes the storage of data in chip-memory and the storage of the
program in the normal fast memory. Without a special statement, all
information would have been stored in the fast memory area.
.key file
275
Appendix E: Reserved C Words Amiga C for Beginners
E. Reserved C Words
Commands which are presented here, but were not described in the
book, either have no function in the current C compilers, or are reserved
for future versions.
default if typedef
do int union
276
Abacus Appendix F: C Operator Precedence
F Operator Precedence
277
Appendix G: Storage Classes Amiga C for Beginners
G. Storage Classes
Storaee class Validitv Duration
auto Block Block
extern Program Program
register Block Block
static (intern) Block Program
static (extern) File Program
H. Type Conversions
Rules:
1. char and short are always converted to int and float into
double.
2. If after this conversion one of the operators should have the type
double, the second operand and the result are also converted to
double.
278
Abacus Appendix I: Modes for fopen
*<ra" no no yes no no no
yes no no no yes no
no no yes yes no no
no no yes no no yes
No conversions are made for binary files, If the file was opened as an
ASCII file, which can be recognized by the "a" at the second place, all
carriage returns (code 13 = \ r) are eliminated and the character with the
ASCII code (26) is converted to EOF (-1) during reading. During writ
ing, the single line feed (\n), is converted to the character combination
\r\n.
Changes for Aztec opens all files in binary. Aztec also offers the "x" and "x+"
Aztec modes which open a file for writing. If the file doesn't yet exist, it is
created. With "x+" the file can be read and written after opening.
279
Index
163 CPU 206
? conditional operator
create 213
281
Index Amiga C for Beginners
282
Abacus Index
Smart_Refiresh 237
Source code 28,,96, 189
sprintf 220
square 106
Standard input/output 218
Statement block 34
static variables 144, 156, 181
stderr 223
stdin 223
stdio.h 91, 148, 163, 223
stdout 223
strcmp 154
strcpy 109, 135, 147, 190
Strings 57, 178
strlen 111
struct 173, 236
Structures 183, 235
switch 123, 125
Syntax errors 13
System crash 37
tell 217
text_arr 182
Tips and tricks 227
Transportability 6
Type conversion 70
typedef 178
283
Companion Diskette
Amiga C for
Beginners
For your convenience, the program listings contained in this book are
available on an Amiga formatted floppy diskette. 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
5370 52nd Street SE
Grand Rapids, MI 49512
A perfect introductory book if you're a new or prospective Amiga owner. Amiga for Beginners introduces
you to Intuition (the Amiga's graphic interface), the mouse, windows, the versatile CLI. This first volume
in our Amiga series explains every practical aspect of the Amiga in plain English. Clear, step-by-step
instructions for common Amiga tasks. Amiga for Beginners is all the info you need to get up and running.
Topics include:
Amiga BASIC: Inside and Out is the definitive step-by-step guide to programming the Amiga in BASIC.
This huge volume should be within every Amiga user's reach. Every Amiga BASIC command is fully
described and detailed. In addition, Amiga BASIC: Inside and Out is loaded with real working programs.
Topics include:
See your local dealer or order TOLL FREE 1-800-451-4319 in US & Canada
Amiga 3D Graphic Programming in BASIC Vol.#3
Amiga 3D Graphic Programming in BASIC- shows you how to use the powerful graphics capabilities
of the Amiga. Details the techniques and algorithm for writing three dimensional graphics programs: ray
tracing in all resolutions, light sources and shading, saving graphics in IFF format and more.
Topics include:
Amiga Machine Language introduces you to 68000 machine language programming presented in clear,
easy to understand terms. If you're a beginner, the introduction eases you into programming right away.
If you're an advanced programmer, you'll discover the hidden powers of your Amiga. Learn how to access
the hardware registers, use the Amiga libraries, create gadgets, work with Intuition and more.
See your local dealer or order TOLL FREE 1-800-451-4319 in US & Canada
Amiga System Programmer's Guide Vol.#6
Amiga System Programmer's Guide is a comprehensive guide to what goes on inside the Amiga in a
single volume. Explains in detail the Amiga chips (68000, CIA, Agnus, Denise, Paula) and how to access
them. All the Amiga's powerful interfaces and features are explained and documented in a clear precise
manner.
Topics include:
EXEC Structure
Multitasking functions
I/O management through devices and I/O request
Interrupts and resource management
RESET and its operation
DOS libraries
Disk management
Detailed information about the CLI and its commands
Much more—over 600 pages worth
Advanced System Programmer's Guide for the Amiga - The second volume to our 'system
programming' book. References all libraries, with basis and primitive sturctures. Devices: parallel, serial,
printer, keyboard, gameport, input, console, clipboard, audio, translator, and timer trackdisk.
See your local dealer or order TOLL FREE 1-800-451-4319 in US & Canada
AmigaDOS: Inside & Out Revised for 2.0 Vol.#8
AmigaDOS: Inside & Out covers the insides of AmigaDOS from the internal design up to practical
applications. AmigaDOS Inside & Out will show you how to manage Amiga's multitasking capabilities
more effectively. There is also a detailed reference section which helps you find information in a flash, both
alphabetically and in command groups. Topics include: Getting the most from the AmigaDOS Shell
(wildcards and command abbreviations) • Script (batch) files - what they are and how to write them.
Amiga Disk Drives: Inside & Out shows everything you need to know about Amiga disk drives. You'll
find information about data security, disk drive speedup routines, disk copy protection, boot blocks,
loading and saving programs, sequential and relative file organization and much more.
Topics include:
See your local dealer or order TOLL FREE 1-800-451-4319 in US & Canada
Amiga C for Beginners Vol.#10
Amiga C for Beginners is an introduction to learning the popular C language. Explains the language ele
ments using examples specifically geared to the Amiga. Describes C library routines, how the compiler
works and more.
Topics include:
Beginner's overview of C
Particulars of C
Writing your first program
The scope of the language (loops, conditions, functions,
structures)
Special features of the C language
Input/Output using C
Tricks and Tips for finding errors
Introduction to direct programming of the operating system
(windows, screens, direct text output, DOS functions)
Using the LATTICE and AZTEC C compilers
Amiga C for Advanced Programmers contains a wealth of information from the C programming pros:
how compilers, assemblers and linkers work, designing and programming userfriendly interfaces utilizing
the Amiga's built-in user interface Intuition, managing large C programming projects, using jump tables
and dynamic arrays, combining assembly language and C codes, using MAKE correctly. Includes the
complete source code for a text editor.
Topics include:
See your local dealer or order TOLL FREE 1-800-451-4319 in US & Canada
AmigaDOS Quick Reference
AmigaDOS Quick Reference is an easy-to-use reference tool for beginners and advanced programmers
alike. You can quickly find commands for your Amiga by using the three handy indexes designed with the
user in mind. All commands are in alphabetical order for easy reference. The most useful information you
need fast can be found including:
See your local dealer or order TOLL FREE 1-800-451-4319 in US & Canada
Books for the AMIGA tofiirt
Amiga Graphics Inside & Out
The Amiga Graphics Inside & Out book will show you simply and in plain Eng
lish the super graphic features and functions of the Amiga in detail. You will
learn the graphic features that can be accessed from AmigaBASIC or C.
The advanced user will learn graphic programming in C with examples of
points, lines, rectangles, polygons, colors and more. Amiga Graphics
Inside & Out contains a complete description of the Amiga graphic
system - View, ViewPort, RastPort, bitmap mapping, screens, and
windows.
Topics include:
Amiga Desktop Video Guide covers all the basics - defining video terms,
selecting genlocks, digitizers, scanners, VCRs, camera and connecting
them to the Amiga.
Just a few of the topics you'll find described in this excellent book:
Save Time and Money!-Optional program disks are available for all our Amiga reference
books (except Amiga for Beginners and AmigasDOS Quick Reference). Programs listed in
Jel the book are on each respective disk and saves countless hours of typing! $14.95
Books for the AMIGA
Vol. 12 More Tricks & Tips for the Amiga 1-55755-051-4 $19.95
Professional DataRetrieve
The Professional Level
Database Management System
BeckerText
Powerful Word Processing
Package for the Amiga
BeckerText Amiga is more than just a word processor.
BeckerText Amiga gives you all of the easy-to-use
features found in our TextPro Amiga, plus it lets you
do a whole lot more. You can merge sophisticated IFF-
graphics anywhere in your document You can hyphenate,
create indexes and generate a table of contents for your
documents, automatically. And what you see on the
BeckerText screen is what you get when you print the
document—real WYSIWYG formatting on your Amiga.
But BeckerText gives you still more: it lets you
perform calculations of numerical data within your
documents, using flexible templates to add, subtract,
multiply and divide up to five columns of numbers on a
page. BeckerText can also display and print multiple
columns of text, up to five columns per page, for
professional-looking newsletters, presentations, reports,
etc. Its expandable built-in spell checker eliminates those
distracting typographical errors.
BeckerText works with most popular dot-matrix and
letter-quality printers, and even the latest laser printers for
typeset-quality output. Includes comprehensive tutorial
and manual. Features
BeckerText gives you the power and flexibility that you
Select options from pulldown menus or handy shortcut
need to produce the professional-quality documents that
keys
you demand Fast, true WYSIWYG formatting
When you need more from your word processor than just Bold, italic, underline, superscript and subscript
word processing, you need BeckerText Amiga. characters
Automatic wordwrap and page numbering
Discover the power of BeckerText. Sophisticated tab and indent options, with centering and
margin justification
Move, Copy, Delete, Search and Replace
Suggested retail price: $150.00
Automatic hyphenation, with automatic table of
contents and index generation
Write up to 999 characters per line with horizontal
scrolling feature
Check spelling as you write or interactively proof
document; add to dictionary
Performs calculations within your documents-
calculate in columns with flexible templates
Customize 30 function keys to store often-used text
and macro commands
Merge IFF graphics into documents
Includes BTSnap program for converting text blocks to
IFF graphics
C-source mode for quick and easy C language program
editing
Print up to 5 columns on a single page
Adapts to virtually any dot-matrix, letter-quality or laser
printer
Comprehensive tutorial and manual
Not copy protected
Selected Abacus Products for the Amiga computers
AssemPro
Machine Language Development
System for the Amiga
DataRetrieve
A Powerful Database Manager
for the Amiga
Imagine a powerful database for your Amiga: one that's
"^Retrieve
fast, has a huge data capacity, yet is easy to work with.
Now think DataRetrieve Amiga. It works the same
way as your Amiga—graphic and intuitive, with no
obscure commands. You quickly set up your data files
using convenient on-screen templates called masks. Select
commands from the pulldown menus or time-saving
shortcut keys. Customize the masks with different text
fonts, styles, colors, sizes and graphics. If you have any
questions, Help screens are available at the touch of a
button. And DataRetrieve's 128-page manual is clear
and comprehensive.
DataRetrieve is easy to use—but it also has
professional features for your most demanding database
applications. Password security for your data.
Sophisticated indexing with variable precision. Full
Search and Select functions. File sizes, data sets and data
fields limited only by your memory and disk storage
space. Customize up to 20 function keys to store macro
commands and often-used text. For optimum access speed,
DataRetrieve takes advantage of the Amiga's multi
tasking. Features
You can exchange data with TextPro Amiga,
Select commands and options from the pulldown menus
BeckerText Amiga and other packages to easily
or shortcut keys
produce form letters, mailing labels, index cards, Enter data into convenient screenmasks
bulletins, etc. DataRetrieve prints data reports to most Enhance screen masks with different text styles, fonts,
dot-matrix & letter-quality printers. colors, graphics, etc.
Work with 8 databases concurrently
DataRetrieve is the perfect database for your Amiga.
Define different field types: text, date, time, numeric &
Get this proven system today with the assurance of the
selection
Abacus 30-day MoneyBack Guarantee. Customize 20 function keys to store macro commands
$79.95 and text
Suggested retail price:
Specify up to 80 index fields for superfast access to
your data
Perform simple or complex data searches
Create subsets of a larger database for even faster
operation
Exchange data with other packages: form letters,
mailing lists etc.
Produce custom printer forms: index cards, labels,
Rolodex*cards, etc. Adapts to most dot-matrix & letter-
quality printers
Protect your data with passwords
Get Help from online screens
Not copy protected
A collection of
essential, powerful,
and easy-to-use tools
for your Amiga.
Also Included
at no
additional cost
($14.95 value)
Here's a new software package Some of our best tools included are:
that every Amiga owner can use.
• DeepCopy- one of the fastest
Abacus1 AmigaDOS Toolbox FULL disk copiers; copies many
has the tools you need to make different formats.
your Amiga computing easier
• Speeder- a data speedup utility
and more productive. Whether
(more than 300%) -not a disk cache.
you are a beginner or an advanced
Amiga user you'll find the • BTSnap- a screen grabber deluxe.
AmigaDOS Toolbox to be just
• Diskmon- a full-featured disk
what you've been looking for.
editing tool.
To order call Toll Free 1-800-451-4319 • Fonts- eleven new originals you
Abacus!
can use in your Amiga text.
...and many additional tools that
Dept. L5, 5370 52nd Street S.E. every Amiga owner can use.
Grand Rapids, Ml 49512 Bought individually, equivalent
Phone:(616)698-0330 software could cost up to $200.
Amiga and AmigaDOS are registered trademarks of Commodore-Amiga Inc.
Presenting...
Includes
WOpage
guide to
Computer
Viruses!
The Virus Protection Toolbox Some of our best tools included are:
describes how computer viruses
• Boot Check-
work; what problems viruses
to prevent startup viruses.
cause; how viruses invade the
Libraries, Handler and Devices • Recover-
of the operating system; to restore the system information
preventive maintenance; how to to disk.
cure infected programs and disks.
• Change Control Checker-
Works with Workbench 1.2 and 1.31 to record modifications to
important files.
Abacus!
Ultimo
mm • Check New-
to identify new program and data files.
5370 52nd Street S.E.
Grand Rapids, Ml 49512 Order now or call for your Free
Available at your local dealer or pamphlet "What you should know
about Computer Viruses"
Order Toll Free 1-800-451-4319 (while supplies last)
Amiga is a registered trademark of Commodore-Amiga Inc.