Showing posts with label tcc. Show all posts
Showing posts with label tcc. Show all posts

Monday, September 26, 2011

Coding Lessons: C and included header files (lesson 8)

In the last lesson I introduced the idea of putting either complicated or repetitive lines of code into a function of their own in order to reduce the amount of typing that you may need to do.

Now, I'm going to introduce a radical new concept, what if as well as using a function multiple times in that program, you also want to use that same function in multiple programs, are you going to copy and paste your function hundreds of times into your new code?

In the same way as you don't re-write all the code to actually do the getting of characters onto the screen, (you just use the printf function, you don't write out all the code each time) you also don't want to have to re-write (or copy paste) the code for your repetitive functions.

You might be wondering, since I've just said that printf is a function, where is this function? where is it declared? where is it called?

Well, you'll notice that the first line of every program that we've written so far has #include, (that means include this file), then the name of a file, the fact that the file name is in little triangular brackets means that it's in the tcc includes folder.)

well, those functions, Printf, scanf (and a whole load more) are declared in that stdio.h file.

you see that exporting those functions to a header file is useful, what's contained in the header file is just code, (exactly like we write), but it's used again and again, (in every program we've written so far).

so lets have a look at including our own header files.

so we start the code in the usual fashion

(include the standard header files from the includes directory of the Tcc compiler)
#include <stdio.h>

now we'll include our own header file, but this time from the same source directory.

#include "bmi.h"

see how it's included in quote marks, and not brackets. that means from this path, rather than from your library.

of course, copying header files might not be your idea of a great time so you could put your header into the main includes folder in the tcc directory, or you might want to start a header library of your own and include like this:
#include "../../mylibrary/bmi.h"


After this we write the main part of the program exactly as before.
int main()
{
    int weight, height;
    float bmi;
    printf("BMI Calculator\r\n");
    printf("Enter your weight in Kilos:");
    scanf("%d", &weight);
    printf("Please enter your height in centimeters:");
    scanf("%d", &height);
    bmi = bodymassindex(height, weight);
    printf("your BMI is: %f\r\n", bmi);
    printf("\r\n\r\nUnderweight = <18 -="-" .5=".5" 24.9="24.9" 29.9="29.9" 30="30" br="br" greater="greater" n="n" nnormal="nnormal" nobesity="BMI" noverweight="25" of="of" or="or" r="r" weight="18.5">
}


inside our source directory we also need to have the header file, (called bmi.h)

this header file is literally, a line to declare a function exists, and the function, exactly the same as the last lesson:
float bodymassindex(h, w);
float bodymassindex(int h, int w)
{
    float result;
    /*bmi = mass(kg) / height^2(m)*/
    result = h * h;
    result = result/10000;
    result = w/result;
    return(result);
}




in completion the source code looks like this:

File 1, source.c
#include <stdio.h>
#include "bmi.h"
int main()
{
    int weight, height;
    float bmi;
    printf("BMI Calculator\r\n");
    printf("Enter your weight in Kilos:");
    scanf("%d", &weight);
    printf("Please enter your height in centimeters:");
    scanf("%d", &height);
    bmi = bodymassindex(height, weight);
    printf("your BMI is: %f\r\n", bmi);
    printf("\r\n\r\nUnderweight = < 18 -="-" .5=".5" 24.9="24.9" 29.9="29.9" 30="30" br="br" greater="greater" n="n" nnormal="nnormal" nobesity="BMI" noverweight="25" of="of" or="or" r="r" weight="18.5">
}

File 2, bmi.h
float bodymassindex(h, w);
float bodymassindex(int h, int w)
{
    float result;
    /*bmi = mass(kg) / height^2(m)*/
    result = h * h;
    result = result/10000;
    result = w/result;
    return(result);
}

Complied and run, this program looks exactly the same as the program fro mthe last two examples.

Friday, September 23, 2011

Coding Lessons: C and functions (lesson 7)

OK so we learned a little about accepting inputs, and made a sort of useful tool into the bargain. -I say sort of useful because there are online versions everywhere, the point wasn't to create a useful tool, the point was to introduce manipulating the variables.


Now lets take a step back and look at some simple functions.

we always have a main function, this is where the "meat" of our program goes.

but lets says that we have a defined function

we'll take something simple, like A+B
now we can write C = A+B.

but what if this were actually a really complicated equation, and we're using it hundreds of times, are we going to write it out each time? copy and paste code?

what if we notice a mistake -then we'll hace to correct all the hundreds of times we've written this out.

I guess it's not easier to write c = add(a, b) but for a more complex function this is useful.
what if it weren't adding, what if it were calculating VAT, a change in rate means that you have to search all your code, but if you had a function for calculating VAT, you'd only need to change that function.

Lets' look again at BMI.


as before we include standard libraries:
#include <stdio.h>but this time there is a change, we don't jump right into our main function, we tell the program that there is another function.

float bodymassindex(h, w);

Everything in the first half of this example is the same as the last lesson, show prompts, gather data.
int main()
{
    int weight, height;
    float bmi;
    printf("BMI Calculator\r\n");
    printf("Enter your weight in Kilos:");
    scanf("%d", &weight);
    printf("Please enter your height in centimeters:");
    scanf("%d", &height);
But in this example the data processing has been moved out to a function, we pass that function the numbers,
    bmi = bodymassindex(height, weight); it returns a result, which we then carry on using as normal.
    printf("your BMI is: %f\r\n", bmi);
    printf("\r\n\r\nUnderweight = <18 -="-" .5=".5" 24.9="24.9" 29.9="29.9" 30="30" br="br" greater="greater" n="n" nnormal="nnormal" nobesity="BMI" noverweight="25" of="of" or="or" r="r" weight="18.5">}
the function is written underneath the main part of the program, but in reality it works just the same as the program.
in the main program we expect an integer error code to say if execution has completed sucessfully, so the main part of the program is declared as int main()
We're expecting a floating point to be returned, so we declare the function as a float.
float bodymassindex(int h, int w)
also we tell the function what sort of variables it'll be getting, notice that they have to be the same type (in this case integers), but they don't need the same names, so I shortened height to h and weight to w.

then we come to the function, just as in the last example this calculates the BMI number 
{
    float result;
    /*bmi = mass(kg) / height^2(m)*/
    result = h * h;
    result = result/10000;
    result = w/result;
Then the function returns it's result using the return function.
    return(result);
}



Put all together the code looks like this: (and gives the same output as the last lesson).


#include <stdio.h>
float bodymassindex(h, w);
int main()
{
    int weight, height;
    float bmi;
    printf("BMI Calculator\r\n");
    printf("Enter your weight in Kilos:");
    scanf("%d", &weight);
    printf("Please enter your height in centimeters:");
    scanf("%d", &height);
    bmi = bodymassindex(height, weight);
    printf("your BMI is: %f\r\n", bmi);
    printf("\r\n\r\nUnderweight = <18 -="-" .5=".5" 24.9="24.9" 29.9="29.9" 30="30" greater="greater" n="n" nnormal="nnormal" nobesity="BMI" noverweight="25" of="of" or="or" r="r" span="span" weight="18.5">
}

float bodymassindex(int h, int w)
{
    float result;
    /*bmi = mass(kg) / height^2(m)*/
    result = h * h;
    result = result/10000;
    result = w/result;
    return(result);
}


The difference is that this code is much more maintainable, you might not see it for a small program like this, (in fact it's arguable more work to put in functions than just write the calculations in the code), but if this were a part of a much larger, millions of lines of code program, using this function technique means that you can correct errors without having to search through all lines of code.

It can also reduce lines of code, say I was doing this calculation 3 million times, the calculation is only 3 lines long, but that means that over all this will take 3 million lines of code in my source.

if I decided that I needed height cubed instead of squared, I'd have to alter 1 million lines.

using a function I only need to call the function 1 million times so instead of three million lines of code, I have one million, plus the 9 lines involved in setting up and actually doing the function.

now if I decide that I want height cubed instead of squared, I change 1 line of code.

Tuesday, September 20, 2011

Coding Lessons: C A simple Program (lesson 6)

So far we've only looked at how to get values into and out of the console.

so lets look at a very simple program, we'll still accept inputs from the command line, and output them to the command line. but, the thing that makes this different is that it's a program that actually does something.

Since the world is becoming obsessive of its weight, lets make a BMI calculator.

BMI is a number, it is derived by knowing your weight in kilos, and dividing that by your height in meters squared.

BMI = M / H^2

We'll be including the stadard io library, and opening our main program as usual

#include <stdio.h>
int main()
{

After this we want to sort out our variables, there is weight and height, (you'd expect these to be whole numbers, so we'll declare them as integers).

  int weight, height;
Then we'll need something that will take the result of the equation above for BMI, there is a very good chance that this will be a number with decimal places, so we'll declare a floating point number
    float bmi;


After this we'll do some nice user prompts, and grab some inputs,
    printf("BMI Calculator\r\n");
    printf("Enter your weight in Kilos:");
    scanf("%d", &weight);
    printf("Please enter your height in centimeters:");
    scanf("%d", &height);


now that we have those inputs we need to transform them,
to do this we'll square the height first, (multiply it by itself)
then we'll need to divide that number by 100 (squared) to get the height in meters, (from the height entered in centimeters.

In order to reduce the amount of variables that I'll be declaring, I'll re-use the floating point variable over and over, pushing the results of equations into it, then using it in the next equation:
    /*bmi = mass(kg) / height^2(m)*/
    bmi = height * height;
    bmi = bmi/10000;
    bmi = weight/bmi;

After this we'll display the BMI figure, and a explanation of what it actually means:
    printf("your BMI is: %f\r\n", bmi);
    printf("\r\n\r\nUnderweight = <18 -="-" .5=".5" 24.9="24.9" 29.9="29.9" 30="30" br="br" greater="greater" n="n" nnormal="nnormal" nobesity="BMI" noverweight="25" of="of" or="or" r="r" style="color: red;" weight="18.5">}


Put it all together and you have:
#include <stdio.h>

int main()
{
    int weight, height;
    float bmi;
    printf("BMI Calculator\r\n");
    printf("Enter your weight in Kilos:");
    scanf("%d", &weight);
    printf("Please enter your height in centimeters:");
    scanf("%d", &height);
    /*bmi = mass(kg) / height^2(m)*/
    bmi = height * height;
    bmi = bmi/10000;
    bmi = weight/bmi;
    printf("your BMI is: %f\r\n", bmi);
    printf("\r\n\r\nUnderweight = <18 -="-" .5=".5" 24.9="24.9" 29.9="29.9" 30="30" br="br" greater="greater" n="n" nnormal="nnormal" nobesity="BMI" noverweight="25" of="of" or="or" r="r" weight="18.5">} 

Compile and run to see the following:

 D:\coding\lesson6>source.exe
BMI Calculator
Enter your weight in Kilos:85
Please enter your height in centimeters:195
your BMI is: 22.353714


Underweight = <18 .5=".5" br="br">Normal weight = 18.5û24.9
Overweight = 25û29.9
Obesity = BMI of 30 or greater

D:\coding\lesson6>

Tuesday, September 06, 2011

Coding Lessons: C and more inputs (Lesson 5)

So in the last lesson we dealt with only integers, in the same way as lesson 2 introduced the idea of variables, and we focused on one type of input (mostly so that I could keep my focus and the lesson wouldn't go on too long).

Now we're going to take a look at all the other types that are available to us.

Other Variables
We did integers pretty much to death in the last lesson, looking at how to declare, then how to read them, how to over flow them.

Remember how I said that the scanf statement looked like the printf statement. and worked in much the same way too?
Well just like the printf statement you can specify the width of the number, you can add modifiers (long, short signed and unsigned) to the type...

For example
%9ld would take an input that was 9 characters in width, and was a long integer.

So lets go over getting variables into a program.
We'll of course start by making a program, (so create a new lesson 5 folder and a new source file etc).

Then start writing the source in the normal way:
#include<stdio.h> int main() {
and declare some variables of different types that we'll be using to store the data entered by users in.
short int whole_number; char character1, character2; float not_whole_number;

Now lets start asking the user of the program to enter data,
Again we'll start by asking the user to enter the first char that we defined:
printf("enter char1:"); scanf("%c", &character1);

Then we'll ask the user to enter that short int:
printf("enter the short int:"); scanf("%hd", &whole_number);
remember we use the modifier h after the % sign to specify that it's a short integer.

Now we'll ask the user to enter the next character, (chracter2):
printf("Enter the char2:"); scanf("%c", &character2);

And finally get them to enter that floating number:
printf("Enter the float:"); scanf("%f", &not_whole_number);

now let's display back to the user the values that they entered:

printf ("the values entered were\r\n"); printf ("char1:%c, shortint:%hd, char2:%c, float:%f",character1, whole_number, character2, not_whole_number);

and finish our main function by closing the curly bracket:
}

The complete code should look like this:
#include<stdio .h>
int main()
{
short int whole_number;  
char character1, character2;  
float not_whole_number;
printf("enter char1:");
scanf("%c", &character1);
printf("enter the short int:");
scanf("%hd", &whole_number);
printf("Enter the char2:");
scanf("%c", &character2);
printf("Enter the float:");  
scanf("%f", &not_whole_number);
printf ("the values entered were\r\n");
printf ("char1:%c, shortint:%hd, char2:%c, float:%f",character1, whole_number, character2, not_whole_number);
}

Now you need to compile your program, and run it to make sure that it works.
D:\coding\lesson5>tcc lesson5.c
 D:\coding\lesson5>lesson5.exe
enter char1:a
enter the short int:1
Enter the char2:
Enter the float:1.2
the values entered were char1:a, shortint:1, char2: , float:1.200000  
D:\coding\lesson5>

Something strange happened there, we were able to enter the first character input, and the integer, but after that we were only able to enter the floating point number, and when displayed the program seemed to put a line break in unexpectedly.

Buffers
What happened there was no mistake, it looks a little weird, but what happened there was that when we entered that that short integer, we entered the number then hit enter.
so what we actually entered was
1\n
Now we told the program to look at the keyboard buffer, and read a short integer from it, so it took the one leaving \n in the keyboard buffer.
then we told the program to look for a char in the keyboard buffer, and it found \n and used that.

So the reason that the program didn't wait for us to enter a value, is because it already found one.
the reason that there is a line break in the output results is because that's what the character is (\n), so as I said, there is no mistake, the program is just doing what it was asked.
So how can we get data into that variable?

well, we can either just fill the keyboard buffer with what we want: (entering all the variables at once) and the scanf statements will just pick out the data that they are interested in.
D:\coding\lesson5>lesson5.exe enter char1:a4b6.7 enter the short int:Enter the char2:Enter the float:the values entered were char1:a, shortint:4, char2:b, float:6.700000

or, we can do it the proper way and flush the input buffer before reading it so that we know that it's empty and only getting what we want.

Flushing buffers

to flush the buffers in a program, (that is erase them all and make them ready to accept new input, we use the function;
flushall();
So all we need to do now is re-visit that code, and flush the buffers before reading inputs.

#include<stdio .h>
 int main()
{
short int whole_number; char character1, character2;
 float not_whole_number;
printf("enter char1:");
flushall();
scanf("%c", &character1); printf("enter the short int:");
flushall();
scanf("%hd", &whole_number); printf("Enter the char2:");
flushall();
scanf("%c", &character2); printf("Enter the float:");
flushall();  
scanf("%f", &not_whole_number);
 printf ("the values entered were\r\n");  
printf ("char1:%c, shortint:%hd, char2:%c, float:%f",character1, whole_number, character2, not_whole_number);
}

Making pretty outputs
Now, I can't help but feel that just putting data out on one line looks a little, well messy, it's nice for computers to read, but I'm not a computer.

So lets have a look at making our data outputting a little neater.

A few lessons ago we introduced the concept of displaying characters with their ASCII number rather than the data.
I put a link to the table found at http://www.asciitable.com/, we looked at how a character could be 97, which was a lower case a, and 98 was a b.

Well, now we're going to start using the characters, 185, 186, 200, 201, 202, 203, 204, 205 and 206... you'll see that these are double line corners, double horizontal lines (like =) double vertical lines, and junctions between these lines.

we'll start by deciding how wide we want our columns to be, I'm choosing 8 character places.

so we'll draw the top of our table:
printf ("the values entered were\r\n");
printf("%c", 201);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
 printf("%c\r\n", 187);

(Note that if you were a real sadist, all this could be done on a single line! but I feel that'd be a bit confusing).

Then we'll write out our column headers:
printf("%c", 186);
printf("Char 1 ");
printf("%c", 186);
printf("Shortint");
printf("%c", 186);  
printf("Char 2 ");
printf("%c\r\n", 186);
notice I've used white space to pad out those titles to 8character lengths, (by white space I mean I pressed the space bar three times after writing float, (float has five characters, but to make it up to 8, I added 3 blank characters.)

Then we'll close the table cells,
printf("%c", 204);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 185);
and now we'll enter the variables:
printf("%c", 186);
printf("%8c", character1);
printf("%c", 186);
printf("%8hd", whole_number);
printf("%c", 186);  
printf("%8c", character2);
printf("%c\r\n", 186);

Remember how we set the columns to be 8 characters wide, well, that's meant that we have to either pad out, or restrict variables.

So we've used %8c, to make the characters take up 8 spaces, we've made the short in take up 8 spaces by writing %8hd.

Then we close our table:
printf("%c", 200);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);  
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 188);

So the complete code for that bit is:

#include<stdio.h>
int main()  
{
short int whole_number; char character1, character2;
printf("enter char1:");  
flushall();  
scanf("%c", &character1);  
printf("enter the short int:");
flushall();
scanf("%hd", &whole_number);  
printf("Enter the char2:");
flushall();  
scanf("%c", &character2);
printf ("the values entered were\r\n");
printf("%c", 201);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 203);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);  
printf("%c\r\n", 187);  
printf("%c", 186);
 printf("Char 1 ");
printf("%c", 186);
printf("Shortint");
printf("%c", 186);  
printf("Char 2 ");  
printf("%c\r\n", 186);
printf("%c", 204);
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 206);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 185);  
printf("%c", 186);  
printf("%8c", character1);  
printf("%c", 186);  
printf("%8hd", whole_number);
printf("%c", 186);  
printf("%8c", character2);
printf("%c\r\n", 186);  
printf("%c", 200);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c", 202);  
printf("%c%c%c%c%c%c%c%c", 205,205,205,205,205,205,205,205);
printf("%c\r\n", 188);
 }


Yes, I have deliberately taken out the float type of variable.

Compile this and run it, and you should see the following:
D:\coding\lesson5>tcc lesson5.c
D:\coding\lesson5>lesson5.exe
enter char1:1 
enter the short int:s
Enter the char2:1
the values entered were 
╔════════╦════════╦════════╗
║Char 1  ║Shortint║Char 2  ║
╠════════╬════════╬════════╣
║       1║      64║       1║
╚════════╩════════╩════════╝  

Thursday, September 01, 2011

Coding Lessons: C and inputs (Lesson 4)

To start with we're only going to deal with fixed formatted inputs.

That is to say that we'll be assigning a variable type, (an integer for example), and we expect a user to be entering an integer.

We are leaving the system open to people inputting strings or floats or characters, and just trusting that they will enter a number.

Of course, if you were writing professional software, or software for anyone but yourself you'd be allowing input of strings, and then checking that this strings were actually numbers, and then converting them into numbers before allowing them to be treated as numbers.

To start, do the same as for any lesson, go into your coding folder and create a new folder called Lesson4, and open your editor.

you will of course be including the header file that we use to get either inputs or outputs from the console
#include <stdio.h>
And you'll be starting your main routine in the program.

int main()
{
As I said, we'll deal with numbers first, so lets declare a couple of integer variables:
int x, y;
I mentioned in an earlier lesson that you could declare two variables on the same line, that you just separated them by a comma. Well, you just did it!

now you need to tell the user of your program that you're waiting for an input, if you don't tell the user, then how are they going to know to do anything?

So print a message to the screen telling them to enter a number for the variable.
printf("enter a number for X:");
And now you need to actually get the variable.

To do this you use a function called scanf, scanf works pretty much the same as printf, but instead of printing to the terminal, you're scanning from the terminal.
The format of the function looks incredibly similar to the printf function, the same place holder for the variable types are used, but, you cannot put text into the statement, and instead of just writing the variable at the end, we have to prefix the variable name with an ampersand, like this.
scanf("%d", &x);
We tell the user to intput a value, and read that value for y from the keyboard in the same way.

Then we can display our variables, just like we did in earlier lessons.
printf("x=%d, y=%d", x, y);

You can now close your main routine and compile and run your program.

D:\coding\lesson4>tcc lesson4.c

D:\coding\lesson4>lesson4.exe
enter a number for X:99
Enter a number for Y:1
x=99, y=1
D:\coding\lesson4>

Of course, just getting and displaying inputs is a little bit boring, so lets look at some simple functions that we can do with numbers.

We can add them together.

If we'd declared another variable (Z?) then we could write;
z = x+y;
Then the variable z, would have the sum of variables x and y in it.

but we learned in our last lesson that we don't necessarily have to have a variable to display data.
we can just do the maths inside the printf statement.
printf("\r\n%d + %d = %d", x, y, x+y);

I'd recommend some caution here though, anything more complicated than simple maths functions are going to get a little bit difficult to work through, what I mean is that if they are in the end of a printf statement it's going to look messy, be difficult to read, and difficult to debug.

Anyway, add that line of code at the end of your program, and re-compile. and run again.
Testing
D:\coding\lesson4>tcc lesson4.c

D:\coding\lesson4>lesson4.exe
enter a number for X:99
Enter a number for Y:1
x=99, y=1
99 + 1 = 100
D:\coding\lesson4>

The numbers are input correctly, and the sum is calculated correctly.

Lets see if we can trip this program up, and expose some limitations.
D:\coding\lesson4>lesson4.exe
enter a number for X:-8
Enter a number for Y:4
x=-8, y=4
-8 + 4 = -4
D:\coding\lesson4>
It deals perfectly well with negative numbers, remember, integers are signed by default. so lets try something else.
D:\coding\lesson4>lesson4.exe
enter a number for X:1
Enter a number for Y:a
x=1, y=1245064
1 + 1245064 = 1245065
D:\coding\lesson4>
a, is not a number. the program doesn't crash, but the results are meaningless. Imagine if you were writing a program for a financial company, a simple mistake of hitting the wrong key could be disastrous!

Overflow error
Lets be a little less obvious about how to break this program now.
D:\coding\lesson4>lesson4.exe
enter a number for X:1
Enter a number for Y:2147483647
x=1, y=2147483647
1 + 2147483647 = -2147483648
D:\coding\lesson4>
How did that happen?!

If you remember in the first lesson on variables we talked about all the variable types, signed and unsigned, and we talked about how numbers were expressed in binary.
how a signed 4 bit number could count from -8 to +7
0111 = 7
1000 - -8

Well this happens with all signed numbers,
In this case the number has 32 bits, and all that happened was the variable was:
0111 1111 1111 1111 1111 1111 1111 1111
We added 1 to that, so it became.
1000 0000 0000 0000 0000 0000 0000 0000

If that were an unsigned number 2,147,483,647 would have become 2,147,483,648.
but because it is signed, (and has that signed bit) instead it became -2,147,483,648.

We've forced the computer to deal with a number larger than a 32bit integer, with consequences that we could expect, but could not deal with inside the program, because they were too big for the program to deal with!
Consider this:
D:\coding\lesson4>lesson4.exe
enter a number for X:214748364970
Enter a number for Y:214748364970
x=170, y=170
170 + 170 = 340
D:\coding\lesson4>

The numbers are nothing like what we entered, what we've started playing with is forcing the program to deal with numbers that it's just not equipped to. This is an overflow error.
(because the bits have overflowed out of the space that this variable can deal with), sometimes this just doesn't matter, (this program that we've made doesn't complain).
Other times it does matter

The complete code is here:
#include
int main()
{
int x, y;
printf("enter a number for X:");
scanf("%d", &x);
printf("Enter a number for Y:");
scanf("%d", &y);
printf("x=%d, y=%d", x, y);
printf("\r\n%d + %d = %d", x, y, x+y);
}

Tuesday, August 30, 2011

Coding Lessons: C and more variables (lesson 3)

So far we've covered that there is a way to print stuff to the screen.
And that you can set up variables, and that there are different types of variable for different types of data. We declared a variable, gave it a value, and wrote that value to the screen.

But so far we only dealt with 1 data type, (because I didn't want to make the lessons too long).

We know how to declare lots of data types, now lets look at using a few more data types

Start
As before set up your workspace (create a new folder d:\coding\lesson3) and open your editor.

Just as before add any comments that you like, and put that header file in that'll let us deal with outputting data to the screen

#include <stdio.h>

And start your main function

int main()
{

This time I'm not going to declare the variables, of course you can if you want to, but what I'm going to do this time is use the variable place holders in the printf statement, then assign them hard coded values at the end.

Now, lets look at characters, (ones that you'd assign to the char variable type).
printf ("looking at characters: %c %c \n\r", 'a', 98);

there are going to be two characters printed on that line (there are two %c's) looking at the end, you can see that one of those characters is going to be a, and the other is going to be 97?

97 isn't a character!, but it is a place on an ASCII Character map!

If you look up the ASCII character values you'll see that this corresponds to the letter b.

the first 127 characters I'd pretty much agree, there is not a lot of point in printing them, but the extended ASCII, that's where it gets more interesting, these don't appear on the keyboard, but you can use them by just writing the number value.

http://www.asciitable.com/

The other thing that was introduced there was \n (new line) and \r (carriage return), and that's because if we just have two statements;
printf("some text");
printf("some more text");
They will appear on the same line as "some textsome more text"

now let's look at some integers (like we used in the first example).

printf ("integers: %d %ld\n\r", 1234, 650890L);
What we've done there is looked at a %d, (signed integer), and also looked at a much bigger number using a long integer %ld, you'll see that at the end of the large number there is a big L that specifies that it's a long.

So we're really getting into the hang of things now!

So let's look at some special formatting,
Say I'm writing a table, and I need to preserve the formatting, it should be easy right, I can just use spaces to pad out the cells of my output? (but how do I know how many spaces to put?) the variable changes? how do I know I'll need 8 blank spaces, what if I need 9, or 7?

Well, there is a way to tell the printf statement to print out that integer, and pad the space with blank spaces.

printf ("Padding with blanks: %10d \n\r", 123);
that 10 in front of the d in the %d place holder tells the program that that data takes up ten spaces. (so seven blank spaces are put into the front of the number 123)

If I wanted data to be displayed in a set number of characters, i could just as easily pad out the blank space with zeros instead I'd do that like this:

printf ("Padding with zeros: %010d \n\r", 1234);

I said at the start that these lessons would be geared towards programming micro controllers, what if I want to get a number to or from the chip, that number is a representation of 8 bits, I don't write 0111 1111 for off on on on on on on on whichis what I want my 8 output pins to read. I want to represent that in as simpler way as possible in my code, I want to use hex. where I can just write 7f, which is a little easier than working back to the base ten number of 127.

printf ("Using different bases: Decimal %d unsigned hex %x unsigned Octal %o formatted Hex %#x Formatted Octal %#o \n\r", 127, 127, 127, 127, 127);

But now what about floating point numbers, dealing with floats is pretty important, just about everything in this world can be expressed as a floating point number.
if I say to you that my chip measures the temperature of 0x4f it means nothing. but if there is the correct maths on my chip to write 23.5 degrees now that's much better!

printf ("floating point numbers: %10.5f %010.5f %2.2f %E \n\r", 23.517, 23.517, 23.517, 3344.1416);

I'm re-using a couple of the tricks from above. the first one %10.5f basically says, take up ten character spaces, use blank space at the start, have five places after the decimal point.

So 23.517 is displayed as [space][space][space]23.51700

The next example uses the same trick to write zeros instead of blank spaces (%010.5f)
so 23.517 appear as 00023.51700

The next is quite useful, I'm not adding any place holders, or extra information, I'm restricting the accuracy.
%2.2f means 2 places before the decimal place, 2 places afterwards.
so 23.517 gets neatly trimmed to 23.51, I gave the example earlier of a temperature probe, you probably don't need to worry about the thousandth of a degree!

And %E means display in scientific format.
so 3344.1416 becomes 3.3441416 x10(3)

That's floats pretty much covered, so lets move on.

I said earlier about setting the width of text by padding with zeros or blank spaces,
but, there is another way.
printf ("setting the width: %*d \n\r", 5, 14);

If you put a star after the % sign, you can then specify the width before the value.

And last but not least, because I know that you'll want to work with strings of characters so that you can send messages!

printf ("%s \n\r", "A silly message goes here");

%s is the place holder for strings, strings can contain numbers, (as in you can write)
printf("%s \n\r", "123");
But you cannot perform maths functions on strings!


Put it all together
The complete example is here:

#include<stdio.h>

int main()
{
printf ("looking at characters: %c %c \n\r", 'a', 98);

printf ("integers: %d %ld\n\r", 1234, 650890L);

printf ("Padding with blanks: %10d \n\r", 123);

printf ("Padding with zeros: %010d \n\r", 1234);

printf ("Using different bases: Dec %d unsigned hex %x unsigned Octal %o formatted Hex %#x Formatted Octal %#o \n\r", 127, 127, 127, 127, 127);

printf ("floating point numbers: %10.5f %010.5f %2.2f %E \n\r", 23.517, 123.517, 23.517, 3344.1416);

printf ("setting the width: %*d \n\r", 5, 14);

printf ("%s \n\r", "A silly message goes here");

}


so you need to save that in D:\coding\lesson3\
as variables.c

then navigate to that directory and type "tcc variables.c" hit return,

Wednesday, July 13, 2011

Coding Lessons: C and variables (lesson 2)

Ok, so in the last lesson we looked at setting up a program, the header files that you needed to include to be able to accept and output data, comments, outputting data and how to compile the program to an executable.

The trouble is, that program didn't really do much, it doesn't accept any data, doesn't processes anything and the output is pretty much always the same boring message.

So, lets have a look as some variables,

Variables
Variables come in different shapes and sizes, there are integers, chars, floating point numbers and strings.

In general these can be modified with some special words, and those special words either shorten or lengthen the bits assigned to the variable, The amount of data assigned to a variable? who the hell cares about that? Well on a PC, you'd pretty much be right, there is no drive these days to write efficient code like there used to be, drive space, memory space and processor speed are all available in abundance, But, as I said in lesson 1, these lessons are gearing up for switching away from the PC to programming micro controllers where not doings efficiently can quickly lead to your program running well frankly badly, or lead to you running out of memory, that's either memory on the device for your program to be held in, or memory in RAM for data to be stored in as the program is running.

Data Types
So lets go through the different data types.
I said earlier that there were basically 4 data types (ints, chars, floats and strings).

There are several modifiers for these data types (const, signed, unsigned, short and long) and those modifiers pretty much do exactly what they say on the tin.

If you write const before declaring an integer for example, then you are saying that variable is constant, it can't change,

const int lesson=2;

That variable (called lesson) is now constant.

Signed
This is probably going to be difficult to explain without going in depth into how numbers are represented on a computer. So this lesson has to deviate away from C for a moment and into Binary.

Binary
So sit tight, read and re-read, ask questions if needed. Here goes,

In digital electronics there are only two states, 1 or 0, these ones and zeros can be represented as either on or off on a wire, card intact, or hole punched on a punch card, inline or sideways as the domain of the magnetic charge on an HDD platter, charge present or charge not present in an SSD hard drive, it's either something or not something, unlike analogue electronics where there is an infinite range, in binary there is only two states.

I'll use 4 bit binary (because it's going to be easier to write out).

Numbers in 4 bit binary are counted like this

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = 10
1011 = 11
1100 = 12
1101 = 13
1110 = 14
1111 = 15

So with two symbols, and 4 places for those symbols to sit, you can represent 16 numbers, in this example I represented number 1 - 15, 16 would be 10000, and 17 10001 so on and so fourth.
255 = 1111 1111.

(from now on we'll call the places bits), so with a 4 bit number you can count to 15, with a 8 bit number you can count to 255.

You might not be able to see immediately, but the bits have a value assigned to them

8 4 2 1
1 1 1 1 = 8 + 4 + 2 +1 = 15
1010 = 8 + 2 = 10

The left most bit when writing this way is the most significant bit [msb], (assigned the biggest value) the right most bit the one that is assigned a value of only 1 is the least significant bit (lsb)


Well, that's all very good you say, I can count from zero to a number as big as the amount of places I have in my number, but what about representing minus one, we use minus numbers all the time. When looking at the weather, or counting, minus numbers crop up all the time in our daily lives.

To denote a number as a signed number, we need to use a part of that binary representation to denote that it's negative, this is the signed bit.
Sadly, it doesn't just work like a minus sign so that whatever is after the signed bit can be read as that number, but this is not a lesson in binary, if you want to learn how to read binary either wait for an upcoming lesson, or Google search twos compliment.

Anyway, the signed bit is the msb, and the numbers now look like this.
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = -8
1001 = -7
1010 = -6
1011 = -5
1100 = -4
1101 = -3
1110 = -2
1111 = -1

So now my 4 bit space, 4 bit address space that is, can't count up to 15, any more, my 16 states are no longer 0 - 15, they are now -8 to +7

Now, you may want to read and re-read until you properly understand that, perhaps even ask questions in the comments, or even go off and search for a better binary tutorial. you can write the numbers out on paper, practice working out what numbers are. it is possible to program without knowing what the binary states are, but it'll help you when you come to realise the pin outputs of chips later on.

Integers
In maths whole numbers are called integers.
1 is an integer, 1.5 is not.
3000 is an integer, 523 is an integer, 3.147 is not an integer. anything that is not a whole number
is not an integer.

In the example above we looked at signed and unsigned 4 bit integers.

Now if you managed to read that all through and understand it, you may have surprised yourself what you've just learned, in a short space of time!

There are no 4 bit integers in C, (signed or unsigned) so you will have to use slightly bigger numbers (which as I said earlier will take up slightly more memory.

In C the standard space for an integer is 32bit, this means that the number range for an unsigned int is 0 - +4,294967295
the number range for a signed int is -2147483648 - +2147483647.

So that was the signed, variable modifier.

Earlier I talked about the size of space in memory, There are times when it's not appropriate to store 32 bit numbers, if your memory space is 8 bits, for example, and you need to store a 32 bit number, you're taking up 4 times the memory space (as those 32 bits need four 8 bit spaces to be stored in). if you don't have that space, then you'll be in trouble pretty quick.
or what about if you're only recording values of 0 - 255, and you;re logging them, you only need a 8 bit number, if you use 32bit address spaces you'll be using up memory twice as fast, that means that you might end up having to buy more memory in the shape of eeproms. Or that if you're on a computer, your disk space will be used up four times as fast.

So what if you want to use memory really efficiently? Well then you start to use modifiers, such as short, or to get bigger numbers you can use long. Short makes the address space shorter, and Long (in most cases) makes the address space longer.

Below is a table of the amount of bits in a number, and the number range given by that variable type and modifier.
            Data type    Bits                Range
short int 16 -32,768 -> +32,767
unsigned short int 16 0 -> +65,535
unsigned int 32 0 -> +4,294,967,295
int 32 -2,147,483,648 -> +2,147,483,647
long int 32 -2,147,483,648 -> +2,147,483,647

But long ints can also be 64 bit
−9,223,372,036,854,775,808
to 9,223,372,036,854,775,807
It really depends on the architect of the system , on 32 bit systems ints are 32 bit and long ints are 32 bits, long longs are 64 bits, but on 64 bit systems, long ints are 64 bits.
on old Dos systems (16 bit) ints were 16 bit and longs were 32 bits. Basically, check your
platform to find out for sure!

So that's ints (in all their different types) covered, but lets say that you want to represent non integer numbers now. I mean non integer numbers occur in life all the time, if you have a cake and want to share it you get 0.5 of a cake.

Floats
Number that have decimal are called floating point numbers, floating point numbers are always signed, and the standard floating point number is assigned a 32bit address space, if you need a greater address space, then you don't use long floats, you actually use a data type called double (64 bit), after that there is a long double (96 bit).

Chars
the final data type is char, chars are 8bit numbers, so count either 0 - 255 as unsigned chars, or -128 - 127 as signed chars, chars are used for displaying characters. (for example from an ASCII chart of characters,

ok, to wrap up.

To define a variable, use declare the datatype, and ten give the variable a name.
int x;

if you want to modify the variable, you put the modifier in front of this:
short int x;

and if you want, you can assign a value to the variable as it's defined.

short int x=10;

You can also define lots of variables at once.
int x, y, z;

So lets wrap this up with a simple piece of code.

Go back to your coding folder and create lesson 2:

The code
First, you can add whatever comments you like

/* lesson 2, valiables */

Then you want to include the header file that contains all the necessary code to use the output device (monitor)

#include <stdio.h>

Now you need to decide whether you're going to define a global variable, or not a global variable.
at this stage of programming this doesn't matter, however, when you start creating subroutines and functions you're going to notice the difference then.

In this example I'll create a local variables, all this really means is that they are created inside of main routine, and are accessible to only that routine

It's generally bad practice to make variables global.

Now you want to setup your main subroutine in the same way that you did in lesson 1.

int main()
{
and declare your variable
int x;

Now give your variable a value...

x = 50;

Now display your variable.

printf("the variable X is %d", x);

And finish the main routine with a }
That printf statement was interesting, the way in which is works is that you put a little place holder into the text that you're printing (%d for ints), then after you close the speech marks you write down that variable name.

for signed ints you use %d
for unsigned ints you use %u
for floats you use %f
for chars (signed or unsigned) use %c
for strings you use %s, I'll cover strings in more detail in another time...

There is clearly a lot more, a lot, lot more, but I'm going to wrap up this lesson now.

The complete code is
#include <stidio.h>
/*lesson 2*/

int main()
{
int x;
x = 50;
printf("variable x = %d", x);
}

Monday, July 11, 2011

Coding Lessons: simple C programs

Perhaps I'm stretching things a little far now introducing a third set of lessons, it will inevitably mean that all lessons run a little slower, I hope that I'm not stretching myself too thin. I think that at this level at least the lessons are so simple that they can be written up fairly quickly.

I just hope I'm not proved wrong, after all, I'm trying to give lessons on Electronics, Crafting and coding now, as well as going to work, living a life, and making things.

But this is the third lesson type, and covers the third area of interest that this blog is interested in, coding -writing programs.

My feeling is that even if you don't have time to make furniture (write up coming soon) restore furniture (write up coming soon), make home audio equipment (write up coming soon), make tools (write up(s) coming soon), anyway, if you don't have the time, or you don't have the space, or you don't have the money for these things, then by reading this I'm guessing that you have a computer, and you can at least make some virtual things.

I'm not going to be writing a tutorial on how to write games in C++, I may write some tutorials on using shell scripts in both Windows and Linux, but for now I'm writing tutorials on ordinary (ANSI) C.

In the end these lessons in C will be geared towards programming micro-controllers. (Microchip PIC devices).
But you have to walk before you can run.

I've said before on a forum that I frequent, those that say "Help, I need to learn C++ so that I can write a game" are pretty much destined to never learn either C++ or how to make games.
I honestly think that the best approach to learning is to break things up into small manageable chunks and get your head down and study and learn.

Tools
The first thing that you're going to need is a compiler, When I first started using C I learned using Visual Studio 6, that tool is good, and the newer versions of visual studio are in my opinion even better. (Visual Studio is an IDE -Integrated Development Environment, it contains an editor, and a compiler and debugger all in one package, whilst this is all very well, it's overkill for beginer situations.)

However, I won't be using Visual Studio, because it's a cost option, and it's not available on Linux/Unix/Mac, instead I'll be using a free C compiler.

http://bellard.org/tcc/

I'm using Tiny C compiler, which I found by just searching for "free C compiler" -we'll get onto how to use it later.

Next you're going to need something to actually write the code in.
I'm going to be using notepad, but feel free to use jedit, turbopad, emacs, pico, vi, the msdos edit program, you own IDE or your own favourite plain text editor. note I said plain text editor. Something like MS office will not work, because it saves a document with formatting information, you need just a plain text file.

Setting up
I prefer to keep everything nice and organised. You don't have to use the same system as me, indeed I'm on windows, so if you're on Linux or Mac, you'll have to adapt the instructions to suit, I have a C and D drive, you might only have one, or you might have more! again, use your own brain and decide how you want to do things.

First, get the free C compiler that was linked above, and unzip the file to your D drive, this will create a folder called "tcc" inside this tcc folder is the compiler.
you can run the compiler from this folder without any further changes.

from the command prompt:
c:\>d:\tcc\tcc.exe "D:\coding\Lesson1\helloworld.c"

This creates a file called hello world.exe at the C drive.

however, to make things a little easier for yourself, you should really just add d:\tcc to the "path" environmental variable, (I won't cover how to do that here, improve your google fu by finding it our for yourself).

Now you'll be able to just run tcc from any folder without having to enter the path.

I've also created a folder on my D drive called coding.
inside that is a folder called Lesson1

Hello World
Perhaps the simplest of programs is the ubiquitous hello world program, using this will enable you to actually create some source code, compile that to an executable, and actually run a program.

To start with, load your editor (notepad).

This is where you start to need to know something about the way in which C works, and the way in which compilers work.

You might like to put a comment into your program.

Comments are used to put information into the source code for a program, that might be a copyright notice, or instructions for how to use. It might be notes to yourself on how and why you've done things. there are many discussions on what are good an bad comments. but you choose for yourself what you'd like your comments to be.
The compiler will ignore anything marked as a comment. (it won't compile it). this lets you remove stuff from a program by commenting it out whilst you're testing.

in C comment blocks are started with a start then a forward slash */
comment blocks are ended by a forward slash, followed by a star /*

/* my
comments */

So anyway, the next line might be:

/* Hello World
A simple console program, that outputs hello world to the console, then exits.
Version: 1.0
Created: 08/07/2011*/

These comments are fairly useful, they tell you what the program does (without you having to read through the source code), they tell you the version of the program -admittedly not so important in this simple program, but when you've got a program that's taken many weeks to do and you've perhaps got a few different backups saved. or you know that it was working last week and can't see what you changed etc, it's nice to have some version control!
It also tells you the date that you created it. -which can help when you;re documenting your project later.

In C, something with a hash/pound in front of it is an instruction for the compiler.
The top line of the code (after your comment) in your file will be #include < stdio.h >
the #include command tells to compiler that you want to link to another file, you want that code included in your program.

stdio.h is a header file that contains all the code needed to be able to accept inputs from the user, and output to the screen. Using these pre-made headers saves you having to write all the functions for outputting text.

Next you need to set up the main part of your program, the bit where things actually happen.

To do this you write int main()

Some books will tell you to write void main(void), or void main() this declares the return type, in ANSI C void is a valid return type, and your compiler will compile it... but for reasons that will come up in later tutorials, declare the main runtime as an int.

In programming there are routings, and sub routines, and loops and such. you have just started the main routine.

Everything inside the main routing needs to be encased in curly brackets { } to show that it's included inside of this routine. (if that doesn't make sense keep reading, it will at the end.)

So at this point, you've got your header file that contains all the code needed to interact with the display.
You've written some helpful comments that'll remind you what you wanted to do.
You've started your main routine.

Now you want to make it do something, in this case, the Hello world program, all we want the program to do is print hello world to the screen, and then exit.

To make the program print "Hello World" to the screen, you use the command:
printf
then you open some brackets to say what will be printed, (
what you want to say goes inside quote marks "
printf("Hello World")

Then in C all the lines of code that are like this need to be ended with a semi colon ;

printf("Hello World");

Then you need to close that curly bracket to mark the end of the main routine.

The complete program is now:

/* Hello World
A simple console program, that outputs hello world to the console, then exits.
Version: 1.0
Created: 08/07/2011*/

#include <stdio .h>

int main()
{
printf("hello world");
}


OK, so now you need to save that file.

Click on file and click on save.
make the save location your project folder (D:\coding\lesson1).
and call the file "helloworld.c"

To do this, on the save screen, at the bottom change the file type from "Save as type: Text documents (*.txt)"
to "Save as type: All files (*.*)"

The enter the file name as "helloworld.c" (yes, do actually put the quotation marks into the file name box).

On Linux or Macs this steps might be different, indeed different editors on windows might be different, the important thing is that your file has the extension ".c" if it has the extension ".txt", or ".c.txt" then the compiler won't like it.

So now you've got your source file written, and your source file saved.

Now you need to use the command prompt, (in windows click on start, then click run, then type "cmd").

You need to navigate to your project directory,
type:
D:
cd \
cd coding
cd lesson1
If you type dir at this point you should see helloworld.c is contained in this folder.

now you can either type
>d:\tcc\tcc.exe helloworld.c

or, if you added the tcc compiler directory to your system path earlier you can just type
>tcc helloworld.c
(if you're not using this compiler you may need to look at the manual for your own compiler for instructions on how to run it).

You should now see (if you type dir) that a new file called helloworld.exe has been created.

Still at the command prompt, type helloworld.exe, you should see that your program runs, displays the text "Hello World" and the exits, leaving you back at the command prompt.

You can of course change the message from Hello World to anything that you like.

That was a lot of work for displaying two words wasn't it!
but that's because this was a complete beginner lesson and I've tried to explain things as simply as possible! (that and the fact that as I said earlier, sometimes making stuff is hard, and requires learning!).

If there is anything that's confusing, or you feel could be written better, or requires elaboration, leave a note in the comments and I'll see about making some changes.