Tuesday, June 2, 2009

2 - Basic C programming

===============================================================================
2 - Basic C programming.
===============================================================================
Now when you know how a pointer works, what an int is, and you can use
sprintf and printf, it's time to move on to the next step.
The things I will take up first here is the if and else statement in C,
the for loop and the scanf function.
And then the argument vectors and argument count (argv and argc), and
also strcpm, strcpy and atoi.
So here we go with the if statement.


-------------------------------------------------------------------------------
The if statement works like this:
if ( condition ) { action } else { other-action }
Let me demonstrate this in a code, make a file called ifstate.c and in it do:
//----------------------------------------------------------
#include
int main ( void )
{
int i;

i = ( 1 );
if ( i == 1 ) {
printf ( "i is 1\n" );
}
else
{
printf ( "i isnt 1\n" );
}
return 0;
}
//----------------------------------------------------------
Here we have it:
if ( condition ) { action } else { other-action }
The condition is i == 1, so if i is 1 (which it is from "i = ( 1 );"), then
it will perform the action which is to print "i is 1" to the screen,
else it will perform the other-action which is to print "i isnt 1" to
the screen.
If you in this code change the "i = ( 1 );" to "i = ( 2 );", then it
will print the other-action instead of the action.
This will look like this executed:
alien:~$ gcc -o ifstate ifstate.c
alien:~$ ./ifstate
i is 1
alien:~$
-------------------------------------------------------------------------------
So why do we do == in the if and not only = ?
C uses the boolean operators, which is as follows:
-------------------------------------------------------------------------------
== equal to.
!= not equal to.
|= or equal to.
> greather then.
>= greather then or equal to.
< less then.
<= less then or equal to.
&& and.
|| or.
-------------------------------------------------------------------------------
Here is another example with the if statement.
//----------------------------------------------------------
#include
int main ( void )
{
int i, x;
i = ( 10 + 10 );
x = ( i );
if ( x < 50 ) {
printf ( "x is %i\n", x );
}
else
{
printf ( "x is %i\n", i );
}
return 0;
}
//----------------------------------------------------------
So what does this do ?
First we declare integers, i and x, and then we make i = 10 + 10 which
needless to say is 20, and then we make x = i, so that x is now 20.
Then we say, if x is less then 50 (which it is), then it prints out
x is 20 (since x is i which is 20), else it will print out
x is .
Not so very hard is it ?
-------------------------------------------------------------------------------
Now it's time to take a look at the for loop.
The first thing I need to say here is that i++ will increas i with 1,
let me illustrate this in a tiny code:
//----------------------------------------------------------
#include
int main ( void )
{
int i;
i = ( 2 );
printf ("i is now %i\n", i);
i++;
printf ("i is now %i\n", i);
i++;
printf ("i is now %i\n", i);
return 0;
}
//----------------------------------------------------------
This will output the following:
i is now 2
i is now 3
i is now 4
This is very handy, I should also say that i--; will decrease i by 1.
But now on to an example with a for loop, make a file and call it forloop.c
and in it do the following:
//----------------------------------------------------------
#include
int main ( void )
{
int i;

for ( i = 0 ; i < 10 ; i++ ) {
printf ( "i is now: %i\n", i );
}
return 0;
}
//----------------------------------------------------------
Let's see how this looks when it's executed.
alien:~$ gcc -o forloop forloop.c
alien:~$ ./forloop
i is now: 0
i is now: 1
i is now: 2
i is now: 3
i is now: 4
i is now: 5
i is now: 6
i is now: 7
i is now: 8
i is now: 9
alien:~$
-------------------------------------------------------------------------------
So now what does the code mean ?
First for works like this:
for ( ; condition ; ) { action }
So let's cut right to the new part:
....
for ( i = 0 ; i < 10 ; i++ ) {
printf ( "i is now: %i\n", i );
}
....
First let's take a look at what's inside the paranteses.
Three feilds separated by ; (semi colon)
"i = 0 ; i < 10 ; i++".
"i = 0", that's easy to know what it means. it set's i to be 0.
The next of the 3 feilds is "i < 10", this means that as long as
i is less then 10, it will perform the action.
And then the "i++" that will increase "i" for every time it loops.
So basically it will read what's inside paranteses over and over again
until it the condition is reached, each time performing the action.
In this code the condition will be met when i is no longer less then 10.
-------------------------------------------------------------------------------
Now here is another short example of a for loop, this time without the
surrounding code.
....
for (;;) {
printf ("This will go on forver\n");
}
....
I dont even need to explain this very much.
If you dont set any conditions at all, it will just keep on looping
for all eternety.
This can be very useful at times, like when coding daemons (servers)
that are suppose to do something over and over again all of the time.
-------------------------------------------------------------------------------
Now let's take a look at the scanf function.
scanf() is a function that will take something from stdin
(standard input - the keyboard), and use it in the code.
Let's illustrate it in an example.
Make a file called say scanftest.c and in it do this:
//----------------------------------------------------------
#include
int main ( void )
{
char str[50];
printf ( "Type something: " );
scanf ( "%s", &str );
printf ( "You typed %s \n", str );
return 0;
}
//----------------------------------------------------------
Ok, so what does the new stuff here really do ?
First we create a pointer that we call str that can hold 50 characters.
The we print to screen (stdout - standard output) "Type something: ",
and after that we use scanf().
scanf ( "%s", &str );
This means that it scans %s (characters), and writes's them to str.
So why is there an amplersand (&) before the str ?
This is called to refference a pointer, you do that when you're writing
something to the actual location of where the pointer points to.
I will come back to that more later, for now just remember that this
is one of the places where you need to have an & before the pointer.
And then we print it out.
So, executed it could look like this:
alien:~$ gcc -o scanftest scanftest.c
alien:~$ ./scanftest
Type something: test
You typed test
alien:~$
-------------------------------------------------------------------------------
And that's all you need to know about the scanf function for now.
-------------------------------------------------------------------------------
Now let's take a look at argc and argv.
argc means argument counter and is an int, it will hold the number of arguments
passed on to the program. ( 3 arguments to a program is this ./program -o foo )
know that the program name it self is an argument in the 'mind' of argc.
arg means argument vector is is a char, and it will hold the actual
arguments passed to the program from the execution line.
So, in order to make this work, I said earlyer that the void in
"int main (void)" was there because we didnt pass anything on to the function,
but now we will, so here is an example, let's call the file program1.c:
//----------------------------------------------------------
#include
int main ( int argc, char **argv )
{
if ( argc != 2 ) {
fprintf ( stderr, "Wrong number of arguments.\n" );
return -1;
}
printf ( "The argument was %s \n", argv[1] );
return 0;
}
//----------------------------------------------------------
Here are a few new things.
First:
int main ( int argc, char **argv )
This means that it will import argc as an int, argc was just explained.
and then we have argv as a char.
So why is there 2 *'s infront of argv ?
Well here a * infront of it means the same as a [] after it, some people
write it as "char *argv[]" personally I think that looks weird.
But perhaps the second way is more 'correct'.
Anyway, this means that argv[0], is argument 0, and hence the program name.
And argv[1], the first argument after the program name... and argv[2]
beeing the argument after that etc.
Then we have:
if ( argc != 2 ) {
This simply means, "if the argument counter not is two, then do .....".
And what does it do ?
This is also new.
fprintf ( stderr, "Wrong number of arguments.\n" );
fprintf means file print file, and the file that we are printing the message
to is stderr (/dev/stderr).
stderr is an abbreviation for standard error, with normal printf you print
by default to stdout which means standard output, and with scanf you read
from stdin, which is standard input... see the note below.
And why are you writing it out as stderr ?
One of the reasons is that if someone writes a shell script where your program
is called, they may expect errors and dont want them visible, and so they can
redirect the errors to /dev/null (the black hole of UNIX), but still see the
stdout if any appears.
And the next two lines after that:
return -1;
}
-1 means that it will return unsuccessful and quit.
Again one of the reasons for doing this is if somone does a shell script
that needs to know if the program was executed successfully or not.
And then close the if statement with the bracket.
And the next line .... you should be able to figure that one out:
printf ( "The argument was %s \n", argv[1] );
The normal printf you know, and the %s you know too by now.
But instead of a 'normal' pointer we use argv[1], argv is a pointer to
all the arguments, and the number inside the brackets says which of the
arguments it should be.
And then return with success and close the main function.
So basically, if it has the wrong number of arguments it will die and
tell you so, but in other cases it will ignore the action of the if statement
because the condition isn't met... and go right on to the printf line.
So, executed it could look like this:
alien:~$ gcc -o program1 program1.c
alien:~$ ./program1
Wrong number of arguments.
alien:~$
Or:
alien:~$ gcc -o program1 program1.c
alien:~$ ./program1 foo
The argument was foo
alien:~$
Or:
alien:~$ gcc -o program1 program1.c
alien:~$ ./program1 bar
The argument was bar
alien:~$
etc.
-------------------------------------------------------------------------------
I/O (Input / Output)
stdout - standard output (1)
stderr - standard error (2)
stdin - standard input
-------------------------------------------------------------------------------
Now let's take a short look at the strcmp function.
strcmp means string compare, and will compare two character strings,
(just two pointers works just as well, but here we will compare a pointer
with a pre made string).
So let's begin, open a file and call it strcmpex.c, and in it do:
//----------------------------------------------------------
#include
int main ( int argc, char **argv )
{
if ( argc != 2 ) {
fprintf ( stderr, "Wrong number of arguments.\n" );
return -1;
}
if ( strcmp ( argv[1], "root" ) == 0 ) {
printf ( "argv[1] was root\n" );
}
else
{
printf ( "argv[1] was NOT root\n" );
}
return 0;
}
//----------------------------------------------------------
Now the only really new thing in here was this line:
if ( strcmp ( argv[1], "root" ) == 0 ) {
This will compare if argv[1] (the first argument after the program name),
and the word/string "root" returns success (that will only happen if they
are the same), and if so do the action.
If we instead would have said:
if ( strcmp ( argv[1], "root" ) != 0 ) {
That would have meant, if argv[1] and "root" does not match....
This should be understandeble, but just in case it isn't, there will be
be another explanation with an example shortly.
This time I will not show how this program looks executed, you gonna have
to test it your self, unless you already can deduct how it will look.
-------------------------------------------------------------------------------
So now let's take a short look at the atoi (ascii to integer).
atoi is really simple, and works like this:
....
int i;
char str[3];
sprintf ( str "5" );
i = ( atoi ( str ) );
....
And as you see, now the char that contains "5" as a character, is now
converted to an integer.
This will come to good use in a while.
Basicly, you could say that "atoi(str)" is used the same way as if
the char would have been a single int in the first place.
There is also atof (ascii to float) and atol (ascii to long) etc. but I'll
explain those later.
-------------------------------------------------------------------------------
Now let's make a little test program, just to see how a program that actually
has a purpose and makes use of what you know this far looks like.
So as a test example let's do a little very simple calculator.
So open a file, let's call it calc.c and in it type the following:
//----------------------------------------------------------
#include
int main ( int argc, char **argv )
{
int i;
if ( argc != 4 ) {
fprintf ( stderr, "Usage: %s <+|-|/|'*'> \n", argv[0]);
return -1;
}
if ( strcmp ( argv[2], "+" ) == 0 ) {
i = ( atoi ( argv[1] ) + atoi ( argv[3] ) );
}
if ( strcmp ( argv[2], "-" ) == 0 ) {
i = ( atoi ( argv[1] ) - atoi ( argv[3] ) );
}
if ( strcmp ( argv[2], "/" ) == 0 ) {
i = ( atoi ( argv[1] ) / atoi ( argv[3] ) );
}
if ( strcmp ( argv[2], "*" ) == 0 ) {
i = ( atoi ( argv[1] ) * atoi ( argv[3] ) );
}
printf ( "The answer is: %i \n", i );
return 0;
}
//----------------------------------------------------------
Now let's see what we have done here:
Everything should be understandeble and clear, but just in case
you dont follow this to 100% I'll explain it again in detail.
First we include the standard input output header file.
#include
Then we make a main function that may import the numbers of arguments as
an integer (int argc - argument counter), and the arguments them self
as characters / ascii, (char **argv - argument vector).
int main ( int argc, char **argv )
The we open the funciton with a bracket.
{
Then we declare i as an integer.
int i;
Then we ask if the argument counter is not 4.
if ( argc != 4 ) {
And if it's not 4 arguments (the program name is one of them),
then we print the following to stderr (the standard error output).
fprintf ( stderr, "Usage: %s <+|-|/|'*'> \n", argv[0]);
And after that we exit the program with status - unsuccessful.
return -1;
And then we close the "if" function.
}
And if the "if" function didnt exit us which it only happens if the argc
is others then 4, then the program goes on to the following.
Here we check if argv[2] is a "+".
if ( strcmp ( argv[2], "+" ) == 0 ) {
And if it is a plus, then it will count argv[1] + argv[3] (the argv's gets
converted to intgers with the atoi).
i = ( atoi ( argv[1] ) + atoi ( argv[3] ) );
And then we close that if function.
}
Next we check if argv[2] is a "-".
if ( strcmp ( argv[2], "-" ) == 0 ) {
And if it is a minus, then it will count argv[1] - argv[3].
i = ( atoi ( argv[1] ) - atoi ( argv[3] ) );
And then we close that if function.
}
Next we check if argv[2] is a "/".
if ( strcmp ( argv[2], "/" ) == 0 ) {
And if it is a slash (devided with), then it will count argv[1] / argv[3].
i = ( atoi ( argv[1] ) / atoi ( argv[3] ) );
And then we close that if function.
}
And last we check if argv[2] is a "*".
if ( strcmp ( argv[2], "*" ) == 0 ) {
And if it is a asterisk (times), then it will count argv[1] * argv[3].
i = ( atoi ( argv[1] ) * atoi ( argv[3] ) );
And then we close that if function.
}
After having the actual counting done, we print it out.
printf ( "The answer is: %i \n", i );
And then we exit with success.
return 0;
And finally we close the main funtion.
}
-------------------------------------------------------------------------------
The compiling:
alien:~$ gcc -o calc calc.c
This executed may look like this:
alien:~$ ./calc 12 + 23
The answer is: 35
alien:~$
Or:
alien:~$ ./calc 15 - 9
The answer is: 6
alien:~$
Or:
alien:~$ ./calc 44 / 3
The answer is: 14
alien:~$
Or:
alien:~$ ./calc 9 '*' 8
The answer is: 72
alien:~$
Note that the asterisk have to be within ` quotes, else it will expand as
a wildcard, and so wont work.
-------------------------------------------------------------------------------
Finally in this section, let's have a look at the strcpy() function.
strcpy() works a little like sprintf, to say:
strcpy( ptr, argv[0] );
Is the same as to say:
sprintf ( ptr, "%s", argv[0] );
So strcpy(), will copy the second character pointer to the first one.
Let's make a short example:
//----------------------------------------------------------
#include
int main ( int argc, char **argv )
{
char ptr[256];

strcpy ( ptr, argv[0] );
printf ( "The program name of this program is: %s \n" , ptr );
return 0;
}
//----------------------------------------------------------
Now try this, and you'll understand it if you dont undersand it already.
-------------------------------------------------------------------------------
That was about all on the very first basics on C programming, at this point
you should play some and make silly little program that dont have any
real purpose, unless you have some great ideas.

No comments:

Post a Comment