Skip to content

C Crash Course, Part 1: Methods, Parameters and Return Values

This is part one of a C programming mini crash-course.

So you’ve learned some C programming and at some point encountered methods, parameters and return values. But why do we need those?

As you probably know, the entry point of all the software we write is main:

#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello world\n");
return 0;
}

But as soon as we write any software that really does anything (except print “hello world”), main quickly evolves to contain lots of lines of code and becomes hard to read and understand.

As an example, let’s assume we want to write software for a system that can control the temperature in a room. We need to read the temperature sensor and turn on a heater if it is too cold in the room (too cold is defined as less than 30 degrees for now).

My main program becomes:

int main(int argc, char** argv)
{
// loop forever
{
// read temperature
// if temperature is too low, raise temperature
}
}

Note that I have only written the comments. This is the way I always write code: comments first, to plan what the code will do.

The next step is to implement the software. I could implement it all in main(), but I’ve just argued why that is not a good idea. We need methods.

int main(int argc, char** argv)
{
// loop forever
while (true)
{
// read temperature
readTemperature();
// if temperature is too low, turn on heater
if (temperature < 30)
{
turnOnHeater();
}
}
return 0;
}

Now I have introduced the two methods readTemperature() and turnOnHeater(). The code won’t compile, because the methods don’t exist yet. Let’s implement them:

#include <stdint.h>
void readTemperature()
{
// do something to read the temperature
// from a sensor
}
void turnOnHeater()
{
// do something to turn on a heater
}
int main(int argc, char** argv)
{
uint8_t temperature = 0;
// loop forever
while (true)
{
// read temperature
readTemperature();
// if temperature is too low, turn on heater
if (temperature < 30)
{
turnOnHeater();
}
}
return 0;
}

Note that the main() method is still very easy to read. Actually, because good names were chosen for the methods, most of the comments in main() are no longer needed — they can be removed and the code still makes sense.

The code compiles now, but we have a problem: the temperature variable is never updated. We need return values.

#include <stdint.h>
int8_t readTemperature()
{
// do something to read the temperature
// from a sensor
return 25; // just a hardcoded value for now
}
void turnOnHeater()
{
// do something to turn on a heater
}
int main(int argc, char** argv)
{
uint8_t temperature = 0;
while (true) // loop forever
{
temperature = readTemperature();
if (temperature < 30)
{
turnOnHeater();
}
}
return 0;
}

Now the readTemperature() method is no longer marked void. void has been replaced with int8_t, which means the method will return an 8-bit signed integer. This means that when the method is invoked, the calling code can use that return value — as seen in main(), where the temperature variable gets assigned the return value from readTemperature().

The code to read from a sensor isn’t implemented yet, so readTemperature() just returns a hardcoded value of 25.

In the current implementation, the heater will heat at maximum whenever it’s turned on. That’s probably not a good idea, so let’s give it 3 settings, where 1 is low, 2 is medium, and 3 is max. Which setting to use will be determined by the difference between the actual temperature and the desired temperature.

Desired temperature – actual temperature Heater setting
>0 1
>5 2
>10 3

We need some way to tell the heater which setting to use. We need parameters.

#include <stdint.h>
int8_t readTemperature()
{
// do something to read the temperature
// from a sensor
return 25; // just a hardcoded value for now
}
void turnOnHeater(int8_t setting)
{
// do something to turn on a heater
}
int main(int argc, char** argv)
{
uint8_t temperature = 0;
while (true) // loop forever
{
temperature = readTemperature();
if ((30 - temperature) > 10)
{
turnOnHeater(3);
}
else if ((30 - temperature) > 5)
{
turnOnHeater(2);
}
else if ((30 - temperature) > 0)
{
turnOnHeater(1);
}
}
return 0;
}

Note that the turnOnHeater() method has changed. Its complete signature is now:

void turnOnHeater(int8_t setting)

This means that code which invokes the method is required to provide an 8-bit integer as a parameter to the method. Inside the method, this parameter is called setting.

Right now we don’t actually have a heater, so let’s just print the setting to the console — that can be done with printf. Right now the readTemperature() method always returns the same temperature. We can make the program a bit more interesting if we let the method return a random value in a given range.

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int8_t readTemperature()
{
// create a random temperature
uint32_t randValue = rand(); // generate random value
uint8_t limitedValue = randValue % 15; // limit to 0-15
// the fake temperature will be between 18 and 32
uint8_t fakeTemperature = 18 + limitedValue;
return fakeTemperature;
}
void turnOnHeater(int8_t setting)
{
// do something to turn on a heater
printf("Heater on: %d\r\n", setting);
}
int main(int argc, char** argv)
{
uint8_t temperature = 0;
while (true) // loop forever
{
temperature = readTemperature();
if ((30 - temperature) > 10)
{
turnOnHeater(3);
}
else if ((30 - temperature) > 5)
{
turnOnHeater(2);
}
else if ((30 - temperature) > 0)
{
turnOnHeater(1);
}
}
return 0;
}

The printf() method formats a string and prints it to the console. printf has many formatting options; the documentation for them can be found here.

  1. Make turnOnHeater() print something different on the console, depending on the heater setting.
  2. Right now, the heater will never be turned off. Extend the program so the heater is turned off when the temperature is 30 degrees or above.
  3. The desired temperature is hardcoded to 30 degrees. In a real application, the desired temperature would probably be input from a sensor or entered on a user interface. Add a getDesiredTemperature() method to the program and use the return value from that method when the heater setting is calculated in main(). You can let the method return a hardcoded value for now.