The programs are getting more and more complex, but they should not yet
be difficult. There are some new concepts introduces (void pointers,
type modifiers, new format specifiers, and two new functions), but don't
worry, it'll all be explained.
void *kbq = kbd_queue();
This is a new kind of variable type, the void pointer. A pointer is
a place keeper for somewhere in memory. More speficically, a void
pointer is a pointer to an address. In our case, our void pointer will
be the address of the system keyboard queue. We will use the address of
system keyboard queue to read the keyboard later. We will learn more
about pointers in later lessons.
unsigned short key;
unsigned long count = 0;
We have some new variable declarations, but they are fairly simple. A
short is a short integer, which is 2-bytes in TIGCC. unsigned means
there are no negative numbers. Since a byte is 8 bits, and we have 2,
we get 2^(8*2)=65,536 possibilities. A signed short would have the range
-32,768 to 32,767, and the unsigned short has the range 0 to 65,535.
All int variables in TIGCC are by default short unless you change it
in the compiler options, which is rarely necessary, but it is best to
be specific where possible to avoid complications.
As we have seen, shorts (or short ints) are 2-bytes. longs (or long
ints) are 4 bytes. Longs have 2^(8*4)=4,294,967,296 possibilities. A
signed long integer has a range of -2,147,483,648 to 2,147,483,647. An
unsigned long has a range of 0 to 4,294,967,295.
It is usually fine to just use an int variable. The only times when you
need to specify size of signed-ness is when you have a specific range of
values you have to capture. The system key codes fall right into the
range of a 16-bit unsigned integer, so an unsigned short makes sense
here.
In a previous version of this example, the long variable was useful
because it often went beyond 65,535 very quickly. In this revised
example, it probably won't, but it's still nice to see the opposite of
a short.
One more thing to note here is that long and short are not
variable types. They are actually type modifiers. Type modifiers
are ways to give attributes to certain variable types. In our case,
short, long, unsigned, and signed all modify the int variable type.
Although you can write out "long int" or "short int", most people don't
for brevity's sake.
// clear the screen
clrscr();
// print the string telling the user to press a key
printf("Please press a key.\n");
This code should be obvious by now. We clear the screen and print a
string.
// while no key was retrieved from the keyboard queue
while (OSdequeue(&key, kbq)) {
// increment the variable number by one
printf("Queue Check: %lu.\n", count);
++count;
}
Here is the heart of our program, the OSdequeue function. If you take a
look at the TIGCC docs, you will notice that OSdqeueu will return true
if the queue is empty. So, while the OSdequeue function returns empty,
it means there is no key in the keyboard queue for us to extract.
The body of the loop is simple. But notice the & (ampersand) before
the key variable in the OSdqueue function call. This is called the
'address-of' operator. It takes a variable, determines its address in
memory, and we get a pointer. We will learn more about pointers later,
but for now, it is enough to know that the OSdequeue function will use
the pointer to the key variable we gave it to put our key press there
if the queue isn't empty.
// tell them what key they pressed
printf("The keycode was %hu\n", key);
// wait for input before exiting
ngetchx();
This is pretty standard stuff. The only remarks I want to make are in
regard to the format specifiers used by printf here and in the while
loop body. Since we did use an integer variable, we need to use the
right kind of specifier for printf to be able to replace the value.
%u is the specifier for unsigned integer, like %d was for integer. The
h and l in front of the u mean sHort and Long, respectively. We can't
use %s, because it's already used for string replacement. If you look
in the TIGCC docs for the printf function, the complete syntax for
format specifiers is there which can help you out.