A Beginner’s Guide to Object Oriented Programming (2)

Long time no see. I hope you still remember my recent posting on object-oriented programming. Here is part two, which I hope you are interested in. Today, we are going to have a look at inheritance. If you do not feel familiar enough with classes and objects, please refer to my posting “A Beginner’s Guide to Object Oriented Programming (1)”.

What’s inheritance got to do with programming?

In real life scenarios, an object of a specific class may be able to play different roles. Here is an example:

I am a person, and I have all the attributes and methods that are inherent to any person on this planet. I have certain height and weight. I can sleep(), eat(), and speak(). However, I always play a particular role which depends on the situation I’m in. I’m a teacher, husband, paramedic, scuba diver, runner, motorist, air passenger, …

Now, here comes an awesome fact: Each role that I play can be considered a specialized person. I play many roles, but yet I’m still only one single person. (Luckily … because if this wasn’t the case I’d be suffering from some serious mental disorder.) 😉

There is a term computer science which describes this situation: polymorphism (from Greek polymorphia, which means multiple forms).

Note, that whatever role I’m currently playing I still have all the methods and attributes of a person. For example, my teacher alter ego also has a certain height, weight, and all the capabilities (methods) that any other person may have. But what characteristics and abilities are specific to a teacher? You’ll probably agree that a teacher is able to teach, and that a teacher has to teach a certain number of classes per week.

In order to understand, how the situation above is being modelled in object-oriented programming we need to remember this: A class is a blueprint that can be used to build (instantiate) objects. What we are going to do now is to take this blueprint, put it on a xerox machine, and manually scribble in some features to get a new (extended) blueprint. The new blueprint now allows us to build objects that have both the inherited features and the new features. Of course, we can again make a copy of the new blueprint and add even more features.

The following UML class diagram shows a Teacher class that inherits attributes and methods from a class Person.

bitjunkie

In computer science terminology, we say that class Teacher has been derived from class Person. Teacher is the superclass of Person, and Person is a subclass of Teacher. Be aware that I just wrote “the superclass” and “a subclass”. Any class should have only one direct superclass, but it may have more than one subclasses. Java and C#, among other programming languages, enforce single inheritance. (C++ does allow multiple inheritance, but if you feel like you need to use it in your code, this is usually the sign of bad OOP design.)

Person may have a superclass, such as Creature. Likewise, we can derive further classes from Teacher. Consider a school’s principal, for example. He is still a teacher, but he has additional skills, abilities, methods, whatever you want to call it. (Yay! At least in OOP class hierarchy, the principal is down below his school’s teachers.) 😉

Benefits of inheritance

One of the benefits of inheritance is pretty obvious: Reusability, which means that you don’t have to write the same (erroneous) code multiple times. Given the fact that a person, a principal, a teacher, and a plumber eat in exactly the same way, it is enough to implement this method only once.

The second benefit I’d like to mention is very similar to what’s going on in the real world. We know how to eat() and we know about the consequences of eating (some people hate ’em). 😉 However, most of us don’t have a clue about what is going on inside the eat() method. We don’t know the “guts”, so to speak. In our daily life, we appreciate objects that we can just use, without worrying about what’s going on inside. This is called Information hiding.

The third major benefit is Extensibility. As I have mentioned above you can easily enhance your model by adding more subclasses, without impacting the functionality of any of the other existing classes.

There are further benefits that you may discover as you gain experience in object oriented programming. Polymorphism, for example, allows you to write methods that accept objects of different types. The following code in Java shows the definition of method which can be invoked by passing a person, a teacher, a principal, or anything else within the class hierarchy below Person.

public static void giveThisPersonSomethingToEat( Person p ) {
  p.eat();
}

I hope this tiny and incomplete lesson has helped you to understand the very basics of inheritance. If you have further questions, feel free to ask me in my lectures.

— Andre M. Maier

Posted in Programming Essentials, Uncategorized | Tagged , , | Leave a comment

Subroutines, Functions, Methods

Most, if not all, programming languages allow you to create subroutines, functions, or methods, all of which follow the same principle. You can think of them as black-boxes that contain source code to perform a specific task. For example, you could create a function make_coffee() which contains source code that makes coffee. Whenever you feel in need of a steaming hot cup of coffee in your program, you just need to invoke the function.

Now, imagine you were a tiny little person locked up inside this black-box and your job was to make that coffee. Imagine you standing at a Starbucks counter, some customer walks up and says: make_coffee(). What would your immediate reaction be? Would you inquire for more specific details on that order, such as “Tall? Grande? Venti?”, “For here or to go?” and so on?

It is easy to see that a simple command such as make_coffee() is not sufficient for you to start brewing coffee (… apart from the fact that your client must have learned manners by speed-reading 🙂 ).

In computer programming, a function usually cannot “go back asking questions” after it has been invoked. So here we need a clever customer who passes all necessary information within the invocation of the function: make_coffee( “for here”, “venti”, “americano” )

The pieces of information you pass to a function at the very moment of its invocation are called parameters. A function may have zero, one, or many parameters of any data type. I have been using three parameters of String (or char* for C-Programmers) in this example.

function1Let us now take a look at how functions can return a result. As stated above, the function make_coffee(…) will eventually deliver a hot cup of coffee. Any invocation of make_coffee(…) is going to directly represent the function’s return value at runtime. Thus, a function can return only one single result value upon each invocation. If you want a function to return more than one value, e.g. multiple cups of coffee, at a time, you’ll have to make the return type a container that may contain than one item.

The way how functions are defined and invoked basically looks similar in most programming languages. The following example shows how we define a function in C.

function1This function is capable of adding two integer values (a and b). It returns the result value directly.

We can now use (invoke) this function within other functions, whenever we need to add two values.

int result = add( 5, 3 );

Note that the function invocation add( 5, 3 ) directly represents the corresponding return value. This allows us to assign it to an arbitrary variable for further use, e.g. output.

You may also invoke functions within larger formulae. Always keep in mind that the invocation of a function represents its return result.

double z = (1/3.0) - (x*( add( 5, 8 ) + add( 1, 2 )*2 ));

If you want to impress your friends, you can even invoke functions where you pass parameters to functions. This example calculates 3 + 5 + 2 + 7.

int result = add( add( add( 3, 5 ), 2 ), 7 );

Be aware, however, that code like this may significantly decrease both readability and maintainability of your source code.

Have fun!

— Andre M. Maier

Posted in Programming Essentials, Uncategorized | Tagged , , , , , , ,

Swapping Variables

Many algorithms, including the world-famous Euclidean, require to swap the values of two variables. So you probably know the following principle.

int x = 8;
int y = 123;
int tmp = x;
x = y;
y = tmp;

However, do you know how to swap the values of two variables without using a temporary variable? If you do, feel free to skip the rest of this article. If you don’t, you’re either not one of my students, or you haven’t been paying attention due to other, more thrilling activities (shame on you!).

Well, there are basically two ways how to swap variables without using temporary memory.

1. PSM (Primary School Math) 😉

x = x + y;
y = x - y;
x = x - y;

or

x = x * y;
y = x / y;
x = x / y;

Homework: Find out why this works!

2. XOR (Exclusive-OR)

An old professor of mine used to say: “There is nothing that you can’t do with XOR”, and he proved to be right.

One characteristic of the XOR function is its ability to undo/redo itself. If you do an XOR operation twice you will get back to the initial situation. If you’re not familiar with this, you may want to read The X-Factor (OR The Power of XOR), 2. OTP (One-Time Pad) Encryption first.

So what we’re gonna do in the first line is to “stir” y into x. Variable x now “contains” both x and y. To retrieve the initial value of x, which is to be written to y, we just have to do the same operation again (see second line). y now contains the initial value of x, whereas x still “contains” both values. In the third line, we retrieve the initial value of y from x by performing the same operation yet again (remember that in this line y contains the initial value of x).

x = x ^ y;
y = x ^ y;
x = x ^ y;

Homework: Try to understand the explanation above. 😉

A warning …

… to all those who are planning to use these cool and nerdy swap methods in practical life!

Please, please. Only use the very first method, involving a temporary variable, in your every day programming projects. There are multiple reasons why you shouldn’t use the “cool” methods:

  • Today’s processors have fast accessible caches (beside other technologies) that make it very unlikely for these methods to have higher runtime efficiency.
  • Saving 4-8 byte of runtime memory isn’t worth any disadvantages.
  • You can give someone a heck of a hard time debugging your program, especially if x and y do not contain the actual values but pointers instead. (Think twice: This someone could be you!)

You cannot believe that what you have learned is totally useless? Well, every discipline of science will come up with useless facts once in a while. And it is exactly this what some people (aka nerds) may find so sexy about science. 🙂

Enjoy!

— Andre M. Maier

Posted in Bit-Twiddling, Information Theory, Uncategorized | Tagged , , , ,

A Beginner’s Guide to Object Oriented Programming (1)

What’s so fancy about Object Oriented Programming?

Computers have been invented to help real-world people solving real-world problems, even though it seems today that computers actually contribute problems to the real world. Since a plain computer doesn’t know anything about the world beyond its steel case, it takes a programmer to describe a model of the real world to the computer. The programmer’s job is to overcome the semantic gap by translating human language into a programming language.

Suppose you want to calculate the average speed of a car that travels 100 miles in 2 hours. In this case, the model of the real world only consists of a simple mathematical equation. The model will get more complex, once you begin to consider fuel consumption, headwind, tire abrasion, earth rotation, temperature, theory of relativity, and whatever crazy stuff is going on in this universe.

The world that we live in is extremely complex and reality does not consist of mathematical equations or algorithms. Instead, there are objects changing their properties by interacting with each other. There are factories in which engineers use blueprints and machines to build new objects. Engineers can copy blueprints, do some modifications to them, and build objects that are similar to the original ones. Large objects can be composed of smaller objects … I think you get the idea. As early as around 1960 some computer scientists invented a programming paradigm that uses real-world thinking to describe the model: Object Oriented Programming (OOP)

Some basic vocabulary

If you want to learn how to write object-oriented programs you first need to get familiar with some terminology.

A class is the blueprint that describes what properties an object may have and what it is able to do. The properties of an object are called attributes or fields.  “What an object is able to do” is defined in methods. Methods can also be imagined as some kind of “levers” that allow other objects to interact with this object.

The act of “building” a new object from a class is called instantiation. An object is also called an instance of a class, although it is correct to use the word object for objects. 😉

Let’s have a look at a practical example: We are going to design a class which describes the model of a door that can be opened and closed.

Firstly, we need to name the class we are going to program which is easy, because it is simply the noun of what we are going to program: Door

Secondly, we need to define how other objects, Hans for example, can interact with the door. Hans shall be able to open and to close the door. The verbs in the sentence will give you an idea of what the methods are: open() and close(). Note that there are always parentheses attached to a method name.

Finally, we’ll have a look at the attributes of the class. If you think of properties that our door may have, you’ll probably come up with a huge list. The door has a weight, a height, a width, a color, a material, a specific temperature, the state (open or closed) and so on. Always keep in mind, however, that there is no model without limitations. Hence we will focus on those properties that are essential for the model to function. You can often identify them by asking yourself: “Which of the properties may be influenced by methods of the class?” In this example we need just one attribute, isOpen, which can be true (if the door is open) or false (if the door is closed).

A common mistake is to introduce redundant attributes: isOpened and isClosed, in this example. Obviously, a door cannot be open and be closed at the same time. Whenever one of the attributes is modified in a method, the redundant information would have to be updated as well. In larger projects this can result in hardly maintainable source code, a high risk of bugs, and last but not least, waste of runtime resources.

How to describe a class

UML (Unified Modeling Language) provides a variety of diagrams that allow to describe any detail of entire software projects. Classes are described by UML class diagrams. The following class diagram shows our model of a door.

A class diagram consists of three rows. The class name (always bold and centered) is in the first row. The second row contains the attributes, and the third row contains all methods. Both boolean and void are data types. It basically means that isOpen may only have two states, either true or false. void after the methods means that nothing is returned from the method. Don’t worry about this, and don’t worry about the + and the – signs, either. I’m going to explain this in one my next postings on OOP.

So now have fun creating object-oriented models of your car, of your pet, or of your boyfriend or girlfriend. 🙂

See you around,

— Andre M. Maier

Posted in Programming Essentials, Uncategorized | Tagged , ,

Mandelbrot Set

This posting is about one of my first BASIC programs that I wrote on my Amstrad CPC464 in 1985. I must confess that I hadn’t actually ‘written’ the program. It was a so-called type-in. Although I was far from understanding the underlying math the program was worth typing the skin off my fingers to get it working.

The program was able to calculate the following fractal picture. A fractal is a self-similar pattern that, as you zoom in deeper and deeper, will reveal the same shapes and structures over and over again.

Mandelbrot Set

Fractals often appear in nature. A really delicious form fractal you probably know is “Romanesco” broccoli.

Today, I know that the related mathematical principle is nothing to worry about. It is quite easy, provided you do know what complex numbers are. I have used this programming project with high-school kids (twelfth grade) and they all managed to understand the principle. What nobody really understands, however, is why there are such things like fractals and what role they play in our universe …

Without any doubt fractals are thrilling programming projects. Here I’m going to explain the algorithm for the popular Mandelbrot set as shown in the picture above. You will find it amazing how simple it is.

1. Create a Cartesian coordinate plane. Both the x-axis and the y-axis are ranging from -2 to 2. Now imagine that any point within the coordinate system represents a complex number. The x value represents the real part of the number, whereas the y value represents the imaginary part of the number.

2. Iterate the formula

for each point within the coordinate plane until the absolute value of z is larger than 2. The number of iterations will directly yield the color of the point in question. In case the number of iterations exceeds the number of available colors, just draw a black pixel or whatever background color you want to use.

Here are some hints how to handle the real part and the imaginary part of the numbers separately:

That’s it.

Here is a thoroughly documented Java implementation which I tried to keep as short and as basic as possible (no swing, no separate threads).

import java.applet.Applet;
import java.awt.event.*;
import java.awt.*;

/**
 * Simple Mandelbrot Applet
 *
 * Note: I tried to keep this program as simple as possible. Thus, 
 *       the applet isn't using different threads. If you want to 
 *       increase runtime efficiency, you probably want to have the 
 *       calculation running in a separate thread.
 *
 * @author Andre M. Maier
 * @version 1.0
 */
public class Fract extends Applet implements MouseListener {

   // The Mandelbrot fractal is defined for complex numbers with
   // -2 < real(z) < 2 and 2 < imag(z) < 2. In the picture the 
   // x-axis represents the real part of the number, whereas the 
   // y-axis represents the imaginary part. The following variables 
   // define the mathematical limits of the picture.
   private final double default_real_min = -2;
   private final double default_real_max = 2;
   private final double default_imag_min = -2;
   private final double default_imag_max = 2;

   // In this applet the number iterations will be represented by 
   // the intensity of red color. Each iteration corresponds to one 
   // step of the color's intensity. In True-Color mode there are 
   // 255 steps available for each of the basic colors (red, green, 
   // blue).
   private final int max_iter = 255;

   // The zoomed window will be 1/4th = 25% of the previous picture 
   // size
   private final int zoom_factor = 4;

   // The actual mathematical limits of the pictures' coordinates 
   // depend on the actual zoom level. So we need some variables to 
   // hold these values.
   private double real_min = default_real_min;
   private double real_max = default_real_max;
   private double imag_min = default_imag_min;
   private double imag_max = default_imag_max;

   // Variables to hold the size of the applet
   private Dimension applet_size;
   private int       xmax, ymax;

   // The value of the following variables will be added and 
   // subtracted from the current position of the mouse pointer. 
   // This allows calculation of the zooming clip's dimensions.
   private int clipping_pixels_x,
               clipping_pixels_y;

   // Variables to hold the x and y boundaries of the clip to be 
   // zoomed
   private int zoom_window_start_x,
               zoom_window_start_y,
               zoom_window_stop_x,
               zoom_window_stop_y;

   /**
    * This method returns the number of iterations that we need to 
    * reach
    *
    * real( p )^2  + imag( p )^2  ~= 4, or we exceed the number of 
    * maximum of iterations allowed
    *
    * with the recursive formulas
    *
    * real( new_p ) = real( p )^2  - imag( p )^2  + real( z )
    *
    * and
    *
    * imag( new_p ) = 2 * ( real( p ) * imag( p ) ) + imag( z )
    *
    * and p starting at 0 + 0i.
    *
    * @param complex_real real part of a complex number
    * @param complex_imag imaginary part of a complex number
    * @returns the number of iterations
    */
   private int iterate( double complex_real, 
                        double complex_imag  ) {

      double real = 0,
             imag = 0;
      double new_real,
             new_imag;
      int    iteration_count = 0;

      while (( real * real + imag * imag < 4 ) &&
             ( iteration_count != max_iter )) {

         new_real = real * real - imag * imag + complex_real;
         new_imag = real * imag + real * imag + complex_imag;

         real = new_real;
         imag = new_imag;

         iteration_count++;

      }

      return( iteration_count );

   }

  /**
   * This method is mandatory for any applet that uses graphical 
   * output. It actually draws the picture.
   *
   * First, the pixel dimensions of the applets need to be mapped 
   * into the mathematical boundaries (real and imaginary) of the 
   * fractal's number space.
   *
   * Then we calculate the number of iterations for each pixel. 
   * After that the pixel is drawn in the color that represents 
   * this number. In case the maximum number of iterations has been
   * reached for a specific pixel, we will draw it in black color.
   */
   public void paint( Graphics g ) {

      double real, imag;
      double step_real, step_imag;
      int    x, y;
      int    iterations;
      int    color;

      // we will start at x = 0, y = 0 (left upper corner), which 
      // is the minimum of real( z ) and the maximum of imag( z )
      imag = imag_max;

      // mapping the pixel steps into mathematical steps for z
      step_real = ( real_max - real_min ) / xmax;
      step_imag = ( imag_max - imag_min ) / ymax;

      // now loop through the entire picture
      for( y = 0; y < ymax; y++ ) {

         real = real_min;

         for( x = 0; x < xmax; x++ ) {

            // calculate number of iterations for the current pixel
            iterations = iterate( real, imag );

            if ( iterations > max_iter ) {

               // draw pixel in black color, if allowed
               // number of iterations has been reached
               color = 0;

            }
            else {

               // let the color value (0 to 255) represent the 
               // number of iterations for this pixel
               color = iterations;

            }

            // set color and draw pixel
            g.setColor( new Color( color, 0, 0 ));
            g.drawLine( x, y, x, y );

            // increasing the (mathematical) real part by one step
            real += step_real;

         }

         // increasing the (mathematical) imaginary part by one step
         imag -= step_imag;

      }
   }

   /**
    * The init() method of an applet is executed when the applet 
    * gets initialized (started by the browser). Hence, we will run 
    * some initiaization code in here ...
    */
   public void init() {

      // setting initial background to white
      this.setBackground( new Color( 255, 255, 255 ));

      // adding the event listener to this applet
      addMouseListener( this );

      // retrieving the applet's size and setting the pixel limits 
      // of the fractal image
      applet_size = this.getSize();
      ymax = applet_size.height;
      xmax = applet_size.width;

      // calculating the clipping size
      // Note: (int) performs a type cast
      clipping_pixels_x = (int) ( xmax / zoom_factor );
      clipping_pixels_y = (int) ( ymax / zoom_factor );

   }

   /**
    * This method gets executed whenever somebody presses the mouse
    * button within the applet.
    */
   public void mousePressed( MouseEvent e ) {

      // So let's determine our position and define our zooming 
      // window
      zoom_window_start_x = e.getX() - clipping_pixels_x;
      zoom_window_start_y = e.getY() - clipping_pixels_y;

      zoom_window_stop_x  = e.getX() + clipping_pixels_x;
      zoom_window_stop_y  = e.getY() + clipping_pixels_y;

   }

   /**
    * Sooner or later the person who pressed the mouse button will
    * release it. We will now use the dimensions of the zooming 
    * window to calculate the new boundaries of the complex number 
    * space z.
    */
   public void mouseReleased( MouseEvent e ) {

      double real1, imag1;
      double real2, imag2;

      // mapping xy pixels for each corner of the zoom window into 
      // the real part and the imaginary part of z
      real1 = real_min + zoom_window_start_x 
                       * ( real_max - real_min ) / xmax;
      imag1 = imag_max - zoom_window_start_y 
                       * ( imag_max - imag_min ) / ymax;

      real2 = real_min + zoom_window_stop_x 
                       * ( real_max - real_min ) / xmax;
      imag2 = imag_max - zoom_window_stop_y 
                       * ( imag_max - imag_min ) / ymax;

      // The following if/else constructs are the remains from a 
      // version where the user could define the dimensions of the 
      // clipping window by dragging the mouse while the button is 
      // pressed.
      //
      // The purpose of this code was to eliminate the direction in 
      // which the zoom window has been opened.
      if ( real1 < real2 ) {
        real_min = real1;
        real_max = real2;
      }
      else {
        real_min = real2;
        real_max = real1;
      }

      if ( imag1 < imag2 ) {
        imag_min = imag1;
        imag_max = imag2;
      }
      else {
        imag_min = imag2;
        imag_max = imag1;
      }

      // In any case, redraw the picture using the new z space that 
      // we have just calculated
      repaint();

   }

   /**
    * This method gets executed whenever the mouse pointer enters 
    * the applet. We will give zooming instructions by writing some
    * text into the status line of the browser running the applet.
    */
   public void mouseEntered( MouseEvent e ) {

      getAppletContext().showStatus( "Click inside the picture!" );

   }

   /**
    * This method gets executed, when the mouse pointer leaves the 
    * applet.
    */
   public void mouseExited( MouseEvent e ) {

      // Let's clean up the status line ...
      getAppletContext().showStatus( "                         " );

   }

   /**
    * Actually we don't need this method, because all the zooming 
    * is already being handled by mousePressed() and 
    * mouseReleased(). As this method needs to be overwritten in 
    * the mouse event handler, we just leave it empty.
    */
   public void mouseClicked( MouseEvent e ) {

   }

}

Now have fun programming. 🙂

— Andre M. Maier

Posted in Math, Programming Assignments, Uncategorized

1.61803398…

In order to declutter my website at school I decided to move all explanatory content over to this blog. I decided to start with an interesting number I have been using in some of my programming assignments. This magic number is the numeric result of a simple problem found by Euclid about 300 BC.

Imagine a line which is described by two line segments a and b.

Euclid’s assignment is to position the point in a way that a/b is equal to (a+b)/a. In plain English. What is the ratio when a over b is the same at total length over a.

Any high school student should be able to solve the problem, because it just involves solving a quadratic equation. (In case you didn’t like math back in high school, here’s how it works 😉

Since negative lengths (probably) do not exist in real life, we may focus on the positive solution which is … tadaa … 1.61803398

So why is this number so damn awesome? Well, the are plenty of reasons.

One reason is that there are a lot of different algorithms that lead exactly to this number. For instance, consider the following sequence of numbers:

1, 1, 2, 3, 5, 8, 13, 21, 34, …

This series is called the “Fibonacci Series”. You might have noticed that each new number is determined by adding the two previous numbers.

So what happens if you choose a random number out of this series and divide it by its predecessor? Let us choose “34”: 34 devided by 21 equals 1.61905 — a number that comes very close to the above solution. If we choose higher numbers from the series we get closer and closer to what is called the “Golden Ratio“.

Ok, I must admit that there are many more other mathematical constants that can  be determined by different seemingly independent algorithms, but here are the really interesting facts about the Golden Ratio:

  • You will find rectangular shaped things (e.g. TV screens, swimming pools) more appealing, if their width/height ratio is about 1.618.
  • The Golden Ratio defines the dimensions of the human profile and even those of our teeth.
  • Many artists (most of them unconsciously) rely on the Golden Ratio to make their pictures look appealing.
  • The shell of certain snails reveal the Golden Ratio (most famous among them is the nautilus pompilius)
  • You will find the Golden Ratio in the growth pattern of certain ferns
  • … and more

Well, so if you meet an ugly person don’t call him or her ugly. Say “Your face seems to have missed the Golden Ratio by a mile.” instead.

Cheers,

— Andre M. Maier

Posted in Math, Programming Assignments, Uncategorized | Tagged , ,

Yet another “trick” that isn’t really a trick …

In my attempt to answer a question during my lecture this afternoon I typed in a quick-and-dirty program that was supposed to illustrate what I was saying. In the program I had to pass a variable number of struct pointers to a function, which I thought was a piece of cake. However, the straight-forward technique I’d been using made my poor students staring at the screen in disbelief. Although they would have had the technical background, they said they did not understand what I was doing.

What had struck them was something like this. (Note: I have changed the data type to int, and I have also simplified the code in function f to merely display the values passed, which hopefully will direct your attention to what is essential.)

#include <stdio.h>

void f( int* args ) {
  while( *args ) {
    printf( "%d ", *args );
    args++;
  }
  printf( "\n" );
}

int main( int argc, char* argv[] ) {
  f( (int[]){ 1, 5, 8, -2, 3, 6, 0 } );
  f( (int[]){ 3, -6, 2, 20, 0 } );
}

Function f is invoked by function main() twice. In both calls of f, a sequence of integer numbers (array literal) is type-casted to an array of int. Function f will now receive a pointer to a sequence (array) of int values. Hence, the argument of f must be an int pointer. Dereferencing this pointer will give us the first value. The number of values (or length of the array) is determined by the terminating zero.

This “trick” (which isn’t really a trick) is based on a principle that you have already used when passing a text strings to functions in C. Strings in C are arrays of characters, and any array is represented by a pointer that holds the address of its first element. So it doesn’t matter which data type you want to pass. Feel free to pass ints, doubles, or even struct pointers. Easy, isn’t it?

If you still do not feel comfortable with pointers, read this (Intermediate) or this (Introduction).

Have fun!

— Andre M. Maier

Posted in Pointers, Programming Essentials, Uncategorized