Beginner · Decisions, loops and functions · topic 7 of 42 · 30 min
Functions: declare, define, call and return
Explanation
Why functions?
As programs grow, writing everything inside main becomes a mess. A function packs one job, such as "work out GST", under a name. You write it once, test it once and call it from many places. If the GST rule changes, you fix one function.
Writing a function
#include <iostream>
double withGst(double price, double rate) {
return price + price * rate / 100;
}
int main() {
double bill = withGst(1000, 18);
std::cout << bill << '\n'; // 1180
std::cout << withGst(250, 5) << '\n'; // 262.5
}- Return type: the type of the value the function gives back (double here). void means it gives back nothing.
- Parameters: the named inputs, each with its type, in the brackets.
- Arguments: the actual values passed when calling, like 1000 and 18.
- return: ends the function and hands the value back.
Pass by value
By default C++ copies each argument into the parameter. This is pass by value: changing the parameter inside the function does not change the caller's variable. In the next module you will learn references, which let a function change the caller's variable or avoid copying big objects.
void addBonus(int marks) {
marks += 5; // changes only the local copy
}
int main() {
int m = 80;
addBonus(m);
std::cout << m; // still 80
}Declaration versus definition
The compiler reads a file from top to bottom. If main calls a function that is written below main, the compiler has not seen it yet and reports an error. A declaration, also called a prototype, is just the first line followed by a semicolon. It promises "this function exists; its body comes later".
#include <iostream>
int square(int n); // declaration (prototype)
int main() {
std::cout << square(9) << '\n'; // 81
}
int square(int n) { // definition
return n * n;
}Splitting code into files
// gst.h (header: declarations only)
#pragma once
double withGst(double price, double rate);
// gst.cpp (source: definitions)
#include "gst.h"
double withGst(double price, double rate) {
return price + price * rate / 100;
}
// main.cpp
#include <iostream>
#include "gst.h"
int main() { std::cout << withGst(100, 18) << '\n'; }Use angle brackets <iostream> for standard and system headers, and double quotes "gst.h" for your own files. If you forget to add gst.cpp to the compile command, the linker reports "undefined reference to withGst".
Common mistakes
- Forgetting return in a non-void function. The compiler warns ("control reaches end of non-void function"); using the result is undefined behaviour.
- Calling a function before it is declared: "was not declared in this scope". Add a prototype or move the function above main.
- Expecting a pass-by-value parameter change to affect the caller.
- Putting function definitions (bodies) in a header that many .cpp files include. That causes "multiple definition" linker errors unless the function is marked inline.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Functions: declare, define, call and return · 1/6
Functions let you name a job, write it once and call it many times.
Prefer a video by a teacher? Find free videos on “c++ functions parameters return prototype header files tutorial” on YouTube ↗
In real life: IRCTC-style fare calculation
A ticket booking system has many rules: base fare by distance, extra for AC classes, a reservation charge and GST on AC classes. Each rule lives in a small function, and the booking code just calls them. When the railway changes one charge, the team edits one function and its tests.
#include <iostream>
double baseFare(int km) { return km * 0.6; }
double acExtra(bool isAc, double fare) { return isAc ? fare * 0.8 : 0.0; }
double gst(bool isAc, double fare) { return isAc ? fare * 0.05 : 0.0; }
int main() {
int km = 1000;
bool ac = true;
double fare = baseFare(km) + acExtra(ac, baseFare(km));
fare += gst(ac, fare);
std::cout << "Fare: Rs " << fare << '\n'; // 1134
}Practice (0/4 done)
Which is a correct declaration of a function isEven that takes an int and returns true or false?
What does this print? void twice(int x) { x = x * 2; } int main() { int a = 5; twice(a); std::cout << a; }
main.cpp calls area(), which is defined in shapes.cpp. You run g++ main.cpp -o app and get "undefined reference to area". Why?
Write three functions and use them from main: bool isLeapYear(int year), int daysInMonth(int month, int year), and void printCalendarInfo(int month, int year) which prints the number of days. Put the declarations at the top and the definitions below main.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Overloading, default arguments and recursionDecisions, loops and functions · same module
- Operators and decisions: if, else and switchDecisions, loops and functions · same module
- FunctionsC Programming (from zero to systems) · Functions and arrays
- Functions: declarations, expressions and returnJavaScript Programming (language in depth) · Functions and closures
- Splitting a program into filesC Programming (from zero to systems) · The preprocessor, multi-file programs and make
- Functions, statements and expressionsRust Programming · Types, control flow and functions
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What does void as a return type mean?
Answer: The function returns nothing
void functions do their job without giving a value back.
What is a function prototype?
Answer: A declaration: the function's first line ending with a semicolon
It tells the compiler the function's name, return type and parameter types before its body appears.
Which include style is used for your own header file?
Answer: #include "myfile.h"
Quotes search your project folder first; angle brackets are for standard and system headers.
What does #pragma once at the top of a header do?
Answer: Stops the header from being included more than once in the same .cpp file
It is an include guard: repeated #includes of that header are skipped.
int f(int n) { if (n > 0) return 1; } What happens when n is -1?
Answer: Undefined behaviour: control reaches the end of a non-void function
Every path of a non-void function must return a value. Compilers warn about this; using the result is undefined behaviour.
A non-void function ends without return on one branch, and the caller uses the result. This is…Related
function f() { return 1; console.log("hi"); } What happens when f() runs?Related
Answer: Returns 1 and never prints
return ends the function; the next line is never reached.
What does extern int count; in a header mean?Related
Answer: count is defined in some .c file; this just declares it
A declaration without storage.
What does a function without -> return?Related
Answer: The unit type ()
Without a return type, the function returns ().
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Decisions, loops and functions” before its exam: Overloading, default arguments and recursion.
- Module 2 exam: Decisions, loops and functions · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
- Then the next module, References, pointers, arrays and strings. 42 topics left in the course before the final exam.