Most programming languages let you slice up a messy, long-running program into neat, named chunks. These chunks are called functions. They allow you to reuse code instead of rewriting the same logic over and over. A function takes inputs, known as parameters, and spits out a result. In C, you can pass as many parameters as you need. The compiler doesn’t care about the order of functions in your source file, as long as it knows the name of the function before it tries to execute it.
We touched on this briefly with the rand function. It is the simplest possible function. It takes nothing and gives back an integer.
The line int rand() tells the compiler that rand is a function. It accepts no parameters and returns an integer. This specific version has no local variables. If it did, they would sit right below the opening brace {. C allows you to declare variables anywhere after a {. They exist until the matching } is hit. Then they vanish. While they are alive, local variables live on the system stack.
Note the lack of a semicolon after rand(). If you accidentally put one in, you will get a huge cascade of error messages from the compiler that make no sense. Even with no parameters, you must use the parentheses. Without them, you aren’t declaring a function. You are just declaring an integer.
The Return Statement and Multiple Exit Points
The return statement is critical for any function that provides a result. It sets the value to be returned and exits the function immediately. You can place multiple return statements in a single function to create multiple exit points.
If you forget the return statement in a function that should return a value, the function exits when it hits the closing brace. It returns a random, garbage value. Most modern compilers will warn you if you fail to return a specific value. C supports returning any type: int, float, char, struct, and more.
There are several correct ways to call the rand function. The most common is assignment:
Here, the variable x gets the value returned by rand. You must include the parentheses in the call, even if there are no parameters. Without them, x receives the memory address of the rand function. That is rarely what you intended.
You can also call it inside a condition:
Or simply ignore the result:
In the last case, the function runs but the returned value is discarded. You might not want to do this with rand, but many functions use the return value as an error code. If you know an error is impossible, discarding the code is fine.
Handling Void Returns
Sometimes you don’t want to return anything. You use a void return type for this.
This function outputs text but returns no value. You call it like this:
Again, include the parentheses. If you omit them, the function is not called. It will compile correctly on many systems, but it won’t do anything.
Parameters and Old-Style C Code
C functions can accept parameters of any type. Here is a function that calculates the factorial of a number:
The parameter i is passed in as an integer. To pass multiple parameters, separate them with commas.
C has evolved. You will occasionally see older code written in the “old style.” It looks like this:
You need to be able to read this old notation. It executes exactly the same way. It is just different syntax. You should use the “new style,” known as ANSI C, where types are declared in the parameter list. Only use the old style if you know you are shipping code to someone with a non-ANSI compiler.
Why This Matters for Everyday Users
You might not write C functions daily. But understanding how they work changes how you think about software. Every time you click a button in a web app, a function is likely processing that click, checking parameters, and returning a status. If you’ve ever seen a “runtime error” or a “stack overflow,” you’ve encountered the limits of these mechanisms.
The distinction between passing a value and passing a reference (the memory address) is a common source of bugs. In high-level languages, this is often hidden. In C, it is explicit. Knowing that rand without parentheses returns an address, not a number, saves hours of debugging.
The old-style vs. new-style debate is largely settled for new projects. ANSI C is the standard. But legacy codebases still exist. Knowing how to read int add(i,j) int i; int j; prevents you from getting stuck on code that looks wrong but works perfectly. It is a matter of literacy.
Does the stack really matter to you? If your program crashes unexpectedly, the stack trace is your only clue. Local variables disappearing when they hit the closing brace is not a bug. It is a feature. It keeps memory usage predictable.
There is no perfect way to write code. There is only the way that compiles and the way that doesn’t. Keep the parentheses. Watch your returns. And don’t assume the compiler will save you from your own syntax errors. It won’t.






































