Gigi Labs

Please follow Gigi Labs for the latest articles.
Showing posts with label type casting. Show all posts
Showing posts with label type casting. Show all posts

Saturday, November 9, 2013

C: Calculating the Average of Several Numbers

Hello everyone! :)

In my article "C: Hello World on Linux", we saw how to write a very simple C program, and how to compile and run it on Linux. In this article, we'll learn how to work with numbers in C, and also how to accept input and print output. I like to use Linux when writing or teaching C/C++, but you can just as well follow along if you're on Windows (e.g. by using Microsoft Visual C++). If you're going to use Linux, you can use your distribution's text editor, or else something like vi (check out my articles, "Linux: vi Essentials" and "Linux: Navigating Text with vi", if you feel you need a refresher on vi).

So, we'll begin with the following basic template:

#include <stdio.h>

int main(int argc, char ** argv)
{
    return 0;
}

Including the stdio.h header file gives us access to the input/output (I/O) functions that we'll need. The first of these is printf(), which we've already seen in my original article, "C: Hello World on Linux".

In our program, we're first going to ask the user how many numbers he's going to enter. Let's say he enters 5. In that case, we'll ask him for five numbers, and then add them up, and then compute the average.

Before the return statement, add the following:

    printf("How many numbers do you want to average?\n");

The \n translates to a newline.

We then declare a variable called count, of type int (integer), so that we can store how many numbers the user needs to enter:

    int count = 0;

Just a note... in C/C++ it is important to always initialise your variables with a value. If you don't, they will contain random garbage data, and using them before they're assigned might lead to unpredictable results.

Now, we can then use the scanf() function to accept input, as follows:

    scanf("%d", &count);

This looks pretty scary, doesn't it? The first parameter is a format string; it indicates what kind of data you're trying to accept. In this case, %d means we are expecting an integer. The second parameter indicates the variable where we'll store the input. By preceding the count variable with the & symbol, we're telling scanf() that the input should go to the location in memory where count resides. This might sound a bit weird until we talk about pointers and references (because it is), but just remember to include that & when accepting input, and you'll be fine.

Next, we need a few new variables:

    int i = 0;
    int number = 0;
    int total = 0;

We'll accept each number into the number variable, after which we'll add it to total. The i variable will be used to track how many numbers have been accepted, so that we know when to stop.

Next, we can write a for loop to repeatedly accept numbers as input, until we have reached the number of numbers we were expecting:

    for (i = 0; i < count; i++)
    {

    }

The code inside the curly brackets (which we will write shortly) will execute as many times as the count variable is set to. If count is 5, then it will execute 5 times. If you look at the first line of the for loop, we're starting with i set to zero, and we're telling it to continue executing as long as i is less than count. Each time the loop's code executes, i is increased by 1 (that's the i++ bit), until the i < count condition becomes true and the loop ends.

Sidenote: if you're coming from some other language, you might be wondering why I didn't declare i in the for loop. That's because some versions of C don't allow it (although it's fine in C++), so you may end up with an error like this:

error: ‘for’ loop initial declarations are only allowed in C99 mode

Let's add some code inside the for loop to accept numbers as input:

        printf("Enter number %d of %d: ", i, count);
        scanf("%d", &number);
        total = total + number;

In the first line, we can see the use of the %d (integer) placeholder within printf(). When you run the program, the placeholders are replaced with the other parameters, i.e. the first %d is replaced with the value of i, and the second one is replaced with the value of count.

In the second line, we're accepting a number as input, and storing it in the number variable (remember the &). Finally, in the third line, we add number to total. There's actually a more concise and efficient way of adding a value to a variable, which is the following:

        total += number;

After the end of the for loop, we can now calculate the average by dividing total by the number of items (count):

    float average = total / count;
    printf("Average: %f\n", average);

The float data type allows us to store numbers that are not integers (whole numbers), and which might have some decimal value. When using floats with printf(), we need to use the %f placeholder, instead of the %d that is used for integers.

Here's the code we have so far, with syntax highlighting courtesy of vim:


From the Linux terminal, the following command will compile your code to an executable called average:

gcc average.c -o average

...and the following command executes it:

./average

Let's test the program to see that it works correctly:


Hmmm, wait just a minute. 1 + 2 + 4 gives us 7, and divided by 3, that doesn't give us exactly 2 (it's actually 2.333333.....). The problem is in the following line of code:

    float average = total / count;

We're dividing an integer by another integer, and that gives us back an integer - losing any digits after the decimal point. To get this to work correctly, we can convert count to a float as follows:

    float average = total / (float) count;

This is called type casting: you put a data type in brackets before a variable to indicate that it should be interpreted as the specified data type. When we recompile and run the program, we can see that it now behaves as we originally expected:


Nice! :)

This article showed how to write a simple program - one that calculates the average of a set of numbers - in C. This simple program revealed several features of the C language, including input/output (via printf() and scanf()), placeholders for format strings (%d and %f), int and float variables, for loops, and type casting.

I hope you found this interesting. Stick around for more articles! :)

Saturday, May 11, 2013

The ASCII Table (C#)

Hi! :)

In previous articles, we have seen how to create a simple game based within the console window (Part 1Part 2). In this article we're going to find out what ASCII is about, and how we can draw some basic shapes  using the characters available in the console. Don't mind the length of this article... there's a really long chunk of code that you can just copy and paste. Read on! :)

So far we have displayed strings in the console window many times. However, a computer does not know anything about text; it can only work with numbers. So when you do something like this:

             Console.WriteLine("Hello world!");

...each character maps to a particular number (e.g. the 'H' is 72, the 'e' is 101, and so on). ASCII is a standard defining a set of basic characters such as these. Check out an ASCII Table to see how the characters are organised.

The standard ASCII is a set of 128 characters, the first 32 and last 1 of which are control characters such as the Carriage Return (13) and Line Feed (10), which together make a newline. The remaining characters are the text characters that we are used to.

There is also an extended set of another 128 ASCII characters. These consist of some non-English characters as well as some line and block characters that can be used to draw something like the screenshot towards the beginning of my article "C#: ASCII Art Game (Part 1)".

We can write all the 256 ASCII characters to the console window using a simple loop. Start a new SharpDevelop project, and use the following code:

            int i = 0;
            while (i < 256)
            {
                Console.Write(Convert.ToChar(i));
                i++;
            }

All we do is run this loop from 0 to 255 and write the corresponding ASCII character. We use the Convert class that is familiar from my article "C# Basics: Fun with Integers", but this time we convert from an integer to a character.

This is easy, but there's a better way to do this. Replace the above code with this:

            for (int i = 0; i < 255; i++)
            {
                Console.Write((char) i);
            }

This for loop does the same as above, but is much more compact. Initialising i, incrementing it, and the loop condition are all contained within the brackets of the for statement. The braces contain the statements to carry out with each iteration. If you have just one statement, as in this case, you may omit the curly brackets.

Also, you'll notice that I changed how we convert between integer and character. This method is called type casting - you just put the desired type (char in this case) beside the variable to be converted. The end result is still the same as with using Convert.ToChar().

When you run this code (F5), you'll hear a beep and see this:


Some things will seem weird here. There are what appear to be smiley faces, an uncalled-for newline, a whole bunch of question marks, and lots of strange characters after that, not to mention the beep.

The smiley faces, newline and beep are all due to the control characters at the beginning of the ASCII set. The beep is due to the bell character (7); the newline is due to the line feed character (10). The smiley faces and other crap at the beginning are just the character representations of those control characters. Additionally, what you're not seeing is that the carriage return (13) is moving the cursor position to the beginning of the line, so characters 11 and 12 are being overwritten. Let's rectify this:

            for (int i = 0; i < 255; i++)
            {
                if (i == 13)
                    Console.Write(' ');
                else
                    Console.Write((char) i);
            }

As for the extended character codes not matching the ASCII Table, that's due to some encoding mumbo-jumbo that I'm not going to get into, but the solution is pretty simple: just add the following line before the for loop:

            Console.OutputEncoding = System.Text.Encoding.GetEncoding(1252);

The result is now different:


That's better! Now, we can use those extended ASCII characters to draw something. This is called ASCII art. Here's some full code:

            Console.OutputEncoding = System.Text.Encoding.GetEncoding(1252);
        
            for (int i = 0; i < 255; i++)
            {
                if (i == 13)
                    Console.Write(' ');
                else
                    Console.Write((char) i);
            }

            // top-left corner
        
            Console.SetCursorPosition(3010);
            Console.Write((char201);
        
            // top-right corner
        
            Console.SetCursorPosition(5310);
            Console.Write((char187);
        
            // mid-left T-junction
        
            Console.SetCursorPosition(3013);
            Console.Write((char204);
        
            // mid-right T-junction
        
            Console.SetCursorPosition(5313);
            Console.Write((char185);
        
            // bottom-left corner
        
            Console.SetCursorPosition(3015);
            Console.Write((char200);
        
            // bottom-right corner
        
            Console.SetCursorPosition(5315);
            Console.Write((char188);
        
            // horizontal edges
        
            for (int i = 31; i < 53; i++)
            {
                Console.SetCursorPosition(i, 10);
                Console.Write((char205);
                Console.SetCursorPosition(i, 13);
                Console.Write((char205);
                Console.SetCursorPosition(i, 15);
                Console.Write((char205);
            }
        
            // vertical edges
        
            Console.SetCursorPosition(3011);
            Console.Write((char186);
            Console.SetCursorPosition(3012);
            Console.Write((char186);
            Console.SetCursorPosition(3014);
            Console.Write((char186);
            Console.SetCursorPosition(5311);
            Console.Write((char186);
            Console.SetCursorPosition(5312);
            Console.Write((char186);
            Console.SetCursorPosition(5314);
            Console.Write((char186);
        
            // text
        
            Console.SetCursorPosition(3211);
            Console.Write("     Welcome to");
            Console.SetCursorPosition(3212);
            Console.Write(" Programmer's Ranch");
            Console.SetCursorPosition(3214);
            Console.Write("by Daniel D'Agostino");
        
            Console.SetCursorPosition(024);

            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);

...and the output:


Right... although we have achieved our goal, you'll notice two things here that feel a little uncomfortable. First, the code is rather long. For this kind of thing, the drawing data is best kept in files. Secondly, there is quite a bit of repetition: lots of Console.SetCursorPosition() calls followed by Console.Write() calls. This may be alleviated by using methods, but more on that in another article.

Great! In this article we learned about what the ASCII table has to offer us. It doesn't sound like much, but if you're creative, you can use it to make some really cool games. Also, ASCII is probably the most basic character encoding there is; if you do advanced programming using text later on, knowing ASCII is a useful foundation.

I have more good things coming up in the next few articles, so don't go away! :)

Optional exercises:

  1. Replace the 'X' representing the player in our ASCII art game (Part 1Part 2) with a smiley face from the ASCII character set.
  2. Draw a top-down view of a house in the console window using ASCII art. Use '-' for doors and '+' for windows.
  3. If you feel like going overboard, draw something complex (such as an elaborate logo design or an overworld map) using ASCII art and send me a screenshot. I'll post the best ones here.