DnA 2-5: C Programming Series: Installment I
C Programming Series: Issue 1
Released With DNA Volume 1, Issue 2
Written by Pazuzu 04-21-1993
Welcome to Issue #1 of Pazuzu's Guide to C Programming: The Fun, Easy, And Possibly DESTRUCTIVE Way to Learn C!
You may wonder why I'm writing an article on a non-underground topic. In truth, it's really not any of your fucking business and you should just BUTT OUT, MIND YOUR OWN FUCKING BUSINESS, AND ENJOY THE INFO. But, since I'm in a good mood, I'll tell you anyway.
I've been seeing posts all over the place, on nets, local BBS's, everywhere, with people saying "hOw Do YoU pRoGrAm In C?!^%$!$!$!!!?????". So, I decided to write a tutorial series so that even the stupidest fool who can't even use WINDOWS will be able to program in C, without damaging his hard drive (at least not physically anyway.). Actually, you can't be a total idiot, you DO have to get a C compiler, and figure out how to use it, because I'm not telling you how to use the compiler, only how to write programs. If you can't accomplish the simple task of getting a C compiler and figuring out how to use it (I recommend Turbo or Borland C, as some of my examples are TC/BC-specific), then please put your computer in a suitable shipping box and ship it to the PO box listed at the end of this article, then place a loaded gun to your head and pull the trigger.
C programming is not particularly difficult, and I assume only a knowledge of either BASIC or Pascal in this series. C will save you much time when coding, just in typing alone. For example, in Pascal, to define a code block, you have to type "Begin" and "End". This is utterly ridiculous. In C, it is simply "{" and "}". Besides, Pascal was invented as a teaching language anyway, while C was made BY programmers FOR programmers, and we ALL know what BASIC is for, so WHY would you want to use anything but C?
Variables, Declarations, Type Specifiers, Etc
In BASIC, when you need a variable, you just use it. However, in most other languages, you must DECLARE each variable before it is used. You do this by telling the compiler the name of the variable and what type of data it needs to hold. Here are a few examples in C:
int i;
register int j;
char a_string[9];
unsigned char q;
The first line declares an integer variable named "i", which can hold any value between -32,767 and +32,767 - the maximum values allowed in 16 bits.
The second line is a special case - it tells the compiler to write code that will use a REGISTER for the variable, if one is available. You would do this for any variables that are used for loop control, as the CPU can access a register MUCH faster than a memory location, and any loop control variable is going to be accessed many times. If there is no register available, the compiler just makes it a normal variable - you don't need to worry about it.
Line 3 is a very important example. There isn't a string data type in C - you must use arrays of char's. Line 3 defines an 8-character string. Why only 8?, you ask... Well, in C, every string must end in a NULL (ASCII 0), and that NULL takes up a position in memory, so you need to always make the strings one bigger than what you really need. The NULL is handled automagically by all of the library's string functions.
Line 4 defines an 8-bit variable which can hold either an actual ASCII character or an integer value in the range 0 to 255 - the maximum for 8 bits. If you define an unsigned int, you can hold a value between 0 and 65,535. The reason for this is that C assumes you want a signed unless you say unsigned. The highest bit is always used for the sign, so with a signed int, you can have -32,767 to +32,767 (-128 thru +128 for signed char), and with an unsigned, you get 0 thru 65,535 for int, and 0 thru 255 for char. There's a few other type specifiers also, the most important being long. If you apply long to an int, you get 32 bits, which is a pretty huge range, even if it's signed. Unsigned, it's really huge. I don't remember the range off the top of my head, and I don't want to load the compiler and check in the help right now, so you'll just have to figure it out yourself. But trust me, it's big enough to handle any values you could ever possibly want.
Very Basic C Programming
With that out of the way, on to the structure of a C program...
C is a weird language in that it defines NO, that's right - NO input/output commands... "Well then how the fuck do I do input/output???" you ask. You do it through FUNCTION CALLS. The C language has control structures, arithmetic operators, and logical test commands, but no i/o commands - that is the job of the library. Every C compiler comes with a library, and it's basically standardized - for example, printf will almost always be printf, but the compiler writer could have just as easily called it print_the_fucking_stuff if he really wanted to.
A C program is made up of functions and function calls. The *MUST* be one function, called main() which is what gets called when you first execute the program... Here is an example of a very basic C program:
#include <stdio.h>
void main(void) {
clrscr();
printf("\n\nhElLo cReWeL, EViL, aNd WiCKED wOrLd!%$^!$!!^%$!^%$!!\n\n");
}
This illustrates several important things:
Line 1 (the #include line): The #include command isn't a C command, it's a command to the compiler to include (I bet you would have never figured that out!!!) another file into the compilation. In this case, we are including the stANdARD iNPUT/oUTPUT library header file. We need to do this because without it, the compiler won't know what the fuck we're talking about when we use any i/o functions - they're defined in stdio.h ...
Line 2: This declares the main() function. The first void tells the compiler that main() doesn't return any value to the caller (since there isn't one!), while the second void tells the compiler that main() doesn't require any parameters. The { opens the function block.
Line 3: This is a call to the library's clear screen routine.
Line 4: This prints a string. The "\n"'s are NEWLINES, they tell the function to go to the next line. You will also notice that all statement lines and in a ";"...
Line 5 (}): This ends main()'s function block, and also in this case the program.
This illustrates several important points, as well as carries on the traditional of ALWAYS making programming students write a "hello world" program as their first. Of course, I altered the text, because I'm scum, but ohwell.
Here is another sample program:
#include <stdio.h>
void main(void) {
register int i;
char inpstr[81];
for(i=0;i<100;i++) {
clrscr();
printf("\n\nInput a string: ");
gets(inpstr);
printf("\n\nYou typed: %s, number %i\n",inpstr,i);
gets(inpstr);
}
}
Ok, the first few lines should already be familiar for you. I'm going to start with the "for..." line. This illustrates an important thing in C - the for loop. Most other languages have this - in BASIC its FOR I = 1 TO 100. The C version is a bit harder to understand, yet infinitely more powerful. The first part ("i=0;") set the loop counter to 0. The second part ("i<100";) specifies what condition to test when deciding if the loop is done yet. In this case, as long as i is less than 100, the loop will execute. The last part ("i++") specifies the increment command. This command is what gets executed to increment the loop counter. In this case, i gets 1 added to it every time the loop executes. The "++" operator is VERY important: In other languages, you have to code i = i + 1 - in C, the i = i + 1 is valid - however, it will be less efficient when compiled. The reason for the is that the i=i+1 version compiles to an ADD instruction, while i++ would compile to a simple INC instruction. This is far more efficient. This is called "C SHORTHAND", and there are several others as well: i-- (subtract 1), i+=3 (i=i+3), and so on. Of course, the variable doesn't have to be i, could be any other variable.
Another VERY important concept is demonstrated by this for loop as well - the BLOCK STATEMENT. Any place a normal single statement is valid, a block statement enclosed by { and } is also valid. In this example, everything between the { and } will get executed on each iteration of the loop.
clrscr() is the Borland library function to clear the screen - other compilers may vary.
The first printf statement should be quite obvious.
gets() is one of the Borland library functions to input a string from the keyboard. Quite simple.
The next printf line shows off part of the true power of printf. The string between the quotes in any printf statement is really a FORMAT STRING, and in most cases, will just be output as is. However, if you insert any % commands, printf will expect additional arguments to tell it what to print in their place. The %s means put a string at this position, and %i means use an integer. For every % command, you must have a variable, separated by commas outside the closing quote, else you will crash your program. In this case, printf will print "You typed: " then whatever you typed into inpstr, then ", number " and the current value of i. This makes printf very powerful as I'm sure you can see.
The last gets() line just makes you press enter to continue.
I've covered quite a bit here, and you can actually do quite a bit with this small amount of knowledge, if you're creative enough. Next issue, I'll cover pointers, bit fields, structures, and basic file accessing.