Maker.io main logo

The Basics of C++ on an Arduino, Part 2: Functions and Methods

2020-10-28 | By Maker.io Staff

This Basics of C++ on an Arduino series is covering many different elements necessary for all sorts of projects and ideas on an Arduino. In this entry, we cover Functions and Methods in C++.

Blocks and method calls

In the first entry in this series, users learned how to do simple declarations and statements, like the following:

Copy Code
Serial.print(“Hello!”);

This statement is a method call. It ends, like every other statement, with a semicolon. The name of the method is print and a single parameter gets supplied, which is the string “Hello” in this case.

A block can combine statements that belong together to a single unit. In C++, blocks get encapsulated with a curly bracket, like this:

Copy Code
{
	// This is a block.
	// It groups certain calls to a logical unit
	int year = 2020;
	int birth_year = 1995;
	int age = year - birth_year;

	Serial.print("Age: ");
	Serial.println(age);
  }

Note that these blocks can only go within already existing functions - for example, the loop method. It’s also important to remember that any variable defined inside of a block is only valid within that region.

Furthermore, blocks can only be used once. Whenever you want to repeat a calculation, you’ll have to copy the entire block and paste it wherever it’s needed. That is inconvenient, and it’ll quickly introduce errors in your program. It tends to be much better to write a custom method that calculates the age and returns it, like so:

Copy Code
int age = calculateAge(1995, 2020);

Writing your own methods and functions

You can think of a function as a named block. Besides that, functions also have a return type, and they might have an arbitrary number of parameters that allow you to pass some data to it. The return type can be anything that you could also use as the type of a variable. If you don’t want to return a value, C++ requires you to use void as the type. Here are some examples of methods and functions:

Copy Code
// This function takes two integers as parameters, calculates the age, and returns it.
int calculateAge(int birth_year, int current_year)
{
	int year = 2020;
	int birth_year = 1995;
	int age = year - birth_year;

	return age;
}

// This method doesn’t have any parameters and it doesn’t return a value
// Note that it’ll accept any parameters.
void doSomething()
{
	// ...
}

// This method doesn’t have any parameters and it doesn’t return a value
// Use the void keyword to indicate that no parameters are allowed.
void doSomethingWithoutParameters(void)
{
	// ...
}

// You can also write the opening curly bracket in the same line as the method’s head
void doSomeMath(float x, float y, double angle) {
 
}

In the context of methods, the method declaration, which contains the return type, name, and parameters, is called the head of the method. The content inside of the function form is its body.

For now, remember that unlike simple blocks, methods may not be contained inside other functions in C++. However, there are exceptions to that rule, but that’s an advanced topic that can be explored in a later blog.

Method prototypes

Typically, you can’t use a method before it gets declared in C++. The following is usually not allowed:

Copy Code
void printSomeMath()
{
  Serial.println(doSomeMath(2.0f, 9.7f, 93.572000));
}

double doSomeMath(float x, float y, double angle)
{
  return (x * y) + (x * angle) + (y * angle) - (x / y);
}

As you can see, the printSomeMath() method references the doSomeMath() function before it’s defined. You could swap the functions to solve this issue. However, it’s also possible to define method prototypes to let the compiler know about your self-defined functions. A method prototype consists of its header and omits the body. Because it’s a statement, it also has to end with a semicolon:

Copy Code
// Method prototypes
void printSomeMath();
double doSomeMath(float x, float y, double angle);

// The implemented methods
void printSomeMath()
{
  Serial.println(doSomeMath(2.0f, 9.7f, 93.572000));
}

double doSomeMath(float x, float y, double angle)
{
  return (x * y) + (x * angle) + (y * angle) - (x / y);
}

It’s possible to add all prototypes to the beginning of a cpp file. However, it’s also possible to define an hpp or h file that contains them. (We’ll cover this in part five of this series -- for now, you can omit the prototypes because the code will work just fine without them in the Arduino IDE.)

Recommended Reading

Summary

It's possible to define custom functions in your code. This helps to keep your code organized and easier to understand, maintain, and use. You can then call the method whenever you need a certain behavior. Every method must at least have a name and a return type. Furthermore, it can have an arbitrary number of optional parameters that allow you to pass data to it. If you define parameters, you must always supply all of them in the correct order when you call the function.

制造商零件编号 A000066
ARDUINO UNO R3 ATMEGA328P BOARD
Arduino
¥224.66
Details
制造商零件编号 A000005
ARDUINO NANO ATMEGA328 EVAL BRD
Arduino
¥202.68
Details
制造商零件编号 A000067
ARDUINO MEGA2560 ATMEGA2560
Arduino
¥393.97
Details
制造商零件编号 ABX00033
ARDUINO NANO EVERY WITH HEADERS
Arduino
¥119.66
Details
制造商零件编号 ABX00012
ARDUINO MKR ZERO W/ HDR ATSAMD21
Arduino
¥246.64
Details
制造商零件编号 A000073
ARDUINO UNO SMD R3 ATMEGA328
Arduino
¥214.08
Details
制造商零件编号 A000057
ARDUINO LEONARDO W/ HDRS ATMEGA3
Arduino
¥202.68
Details
Add all DigiKey Parts to Cart
TechForum

Have questions or comments? Continue the conversation on TechForum, DigiKey's online community and technical resource.

Visit TechForum