Functions, parameters and prototypes (4)
The structure of a C program requires to put the lines of code into functions. Every C program, which is designated to be compiled into an executable file should have a "main" function :
int main(void) {
return 0;
}
We already have seen how the "main" function works in this article
This is how we create a function :
void <identifier>(<?parameters>) { ... }
<return type> <identifier>(<?parameters>) {
...
return <value>;
}
And this is how we call a function :
<identifier>(<?parameters>);
Return value
When a function returns a value, the call instruction stands for this value. Not clear ? Look at this example :
int returns_5(void) {
return 5;
}
int main(void) {
return returns_5();
}
Now, "main" is returning the value of 5
So, we can assign a variable to the returned value :
#include <assert.h>
...
int main(void) {
int number = returns_5();
assert(number == 5);
return 0;
}
What's
assert
???
It's a function coming from the standard library. It requires a boolean expression and checks it. When the expression is true, it does nothing, but when it's false the program panics.
If you see assert
in this course, the result is always good. It avoids some more explication, you directly get the idea.
Parameters
When the function doesn't have parameters, we simply put the void
keyword, by convention.
But you can declare a function that needs parameters, and then play with a parameter like if it was a simple variable, because it is.
Then, when you will call that function, you have to specify the parameters :
int foo(int a, float b) {
assert(a == 10);
assert(b == 69.96);
return 0;
}
int main(void) {
foo(10, 69.96);
return 0;
}
Every parameter requires a data type, same as when you declare a variable data type. When you call the function, you have to respect the correct needed data type.
Command line arguments
We have always seen main
without parameters. But the function can have some. It's called "command line parameters", it's the parameters you give when you call the executable.
int main(int argc, char** argv) {
for (int i = 0; i < argc; ++i) {
printf("%i : %s\n", i, argv[i]);
}
return 0;
}
gcc main.c -o program
./program "hey" 6 zzz 97
0 : ./program
1 : hey
2 : 6
3 : zzz
4 : 97
The first parameter is always the first part of your call in the command line, here it's "./program". We often just ignore it when we play with the arguments
Naming rules for identifiers
The rules for variable identifiers are the same for function identifiers, check this article
Prototypes
The C compiler has to know every existing function in the file. If you try to call a function defined below the line where you call it, you have to create a prototype.
int foo(int x) { // new function known !
return x;
}
int main(void) {
foo(5); // call to the known function "int foo(int x)"
return 0;
}
This example works. As you can see, the compiler knows the function before calling it because it was defined above the call.
But, this one doesn't work :
int main(void) {
foo(5); // call to the unknown function "??? foo(??? x)"
return 0;
}
int foo(int x) { // new function known !
return x;
}
Well, to avoid this problem we simply create a prototype for the function.
int foo(int x); // new function known !
int main(void) {
foo(5); // call to the known function "int foo(int x)"
return 0;
}
int foo(int x) {
return x;
}
A prototype is a function definition without any code lines defined inside it. You have to respect the same definition when you create a function prototype :
void foo(long x, int y); // new function known !
int foo(void) { // what ? "foo" should be "void foo(long x, int y)"
return 0;
}
Think about making the prototype at the file's beginning for every function you create.
Exercises
- Create a function returning its first argument
- Print the second element from the command line arguments
Fix the following code :
#include <stdio.h> int returns(int x); int main(void) { say_hello(); return 0; } void say_hello(void) { printf("Hello !\n"); } float returns(float x) { return x; }
Solutions
Create a function returning its first argument
int returns_first_arg(int to_return) { return to_return; }
You can choose any type for
to_return
, but the return type of the function should have the same type.Print the second element from the command line arguments
#include <stdio.h> int main(int argc, char** argv) { printf("%s\n", argv[1]); return 0; }
Fixing code
#include <stdio.h> void say_helo(void); float returns(float x); int main(void) { say_hello(); return 0; } void say_hello(void) { printf("Hello !\n"); } float returns(float x) { return x; }