Skip to main content

Command Palette

Search for a command to run...

Function Prototypes and Variable Scope – How C Organizes Code

Published
4 min read
D

Heya! 👋 I love helping people, and one of the best ways I do this is by sharing my knowledge and experiences. My journey reflects the power of growth and transformation, and I’m here to document and share it with you.

I started as a pharmacist, practicing at a tertiary hospital in the Northern Region of Ghana. There, I saw firsthand the challenges in healthcare delivery and became fascinated by how technology could offer solutions. This sparked my interest in digital health, a field I believe holds the key to revolutionizing healthcare.

Determined to contribute, I taught myself programming, mastering tools like HTML, CSS, JavaScript, React, PHP, and more. But I craved deeper knowledge and practical experience. That’s when I joined the ALX Software Engineering program, which became a turning point. Spending over 70 hours a week learning, coding, and collaborating, I transitioned fully into tech.

Today, I am a Software Engineer and Digital Health Solutions Architect, building and contributing to innovative digital health solutions. I combine my healthcare expertise with technical skills to create impactful tools that solve real-world problems in health delivery.

Imposter syndrome has been part of my journey, but I’ve learned to embrace it as a sign of growth. Livestreaming my learning process, receiving feedback, and building in public have been crucial in overcoming self-doubt. Each experience has strengthened my belief in showing up, staying consistent, and growing through challenges.

Through this platform, I document my lessons, challenges, and successes to inspire and guide others—whether you’re transitioning careers, exploring digital health, or diving into software development.

I believe in accountability and the value of shared growth. Your feedback keeps me grounded and motivated to continue this journey. Let’s connect, learn, and grow together! 🚀

In the previous lesson, you learned how to:

  • Define functions

  • Call functions

  • Use parameters

  • Return values

Now we go one level deeper.

Today we will understand:

  • Why function prototypes exist

  • How the compiler reads your code

  • The difference between declaration and definition

  • Local vs global variables

This lesson helps you understand how C really works behind the scenes.

1. How the Compiler Reads Your Code

The C compiler reads your file from top to bottom.

It does not “look ahead” to guess what you mean.

If you call a function before the compiler has seen it, it will complain.

Example:

#include <stdio.h>

int main() {
    int result = add(2, 3);
    printf("%d\n", result);
    return 0;
}

int add(int a, int b) {
    return a + b;
}

This may cause an error because when the compiler reaches add(2, 3), it has not yet seen the function definition.

It doesn’t know what add is.

So what do we do?

We use a function prototype.

2. What Is a Function Prototype?

A function prototype is a declaration that tells the compiler:

“This function exists, and this is what it looks like.”

It includes:

  • Return type

  • Function name

  • Parameter types

But no function body.

Example:

int add(int a, int b);

That semicolon at the end is important.

3. Declaration vs Definition

This is very important.

Function Declaration (Prototype)

Blueprint only:

int add(int a, int b);

It tells the compiler:

  • The function name is add

  • It returns an int

  • It takes two int parameters

But it does not contain the actual code.

Function Definition

Actual implementation:

int add(int a, int b) {
    return a + b;
}

This contains the real instructions.

Think of it like this:

Declaration → “This function exists.”
Definition → “This is how it works.”

4. Correct Program Structure

Here is the proper structure:

#include <stdio.h>

int add(int a, int b);  // Prototype

int main() {
    int result = add(2, 3);
    printf("%d\n", result);
    return 0;
}

int add(int a, int b) {  // Definition
    return a + b;
}

Now when the compiler reads the file:

  1. It sees the prototype.

  2. It knows add exists.

  3. It allows main() to call it.

  4. Later it finds the definition.

No error.

5. Variable Scope

Now let’s talk about scope.

Scope determines:

Where a variable can be accessed.

There are two main types:

  • Local variables

  • Global variables

6. Local Variables

Local variables are declared inside a function.

They only exist inside that function.

Example:

#include <stdio.h>

void greet() {
    int x = 10;
    printf("%d\n", x);
}

int main() {
    greet();
    // printf("%d\n", x);  // This would cause an error
    return 0;
}

Why does this cause an error?

Because x only exists inside greet().

Once the function finishes, x is destroyed.

7. Global Variables

Global variables are declared outside all functions.

They can be accessed from any function.

Example:

#include <stdio.h>

int globalVar = 10;

void greet() {
    printf("%d\n", globalVar);
}

int main() {
    greet();
    printf("%d\n", globalVar);
    return 0;
}

Both functions can use globalVar.

8. Should We Use Global Variables?

Yes, but carefully.

Global variables:

  • Make code harder to manage

  • Can be modified anywhere

  • Can cause bugs

Best practice:
Use local variables whenever possible.

9. Common Function and Scope Errors

Students often see errors like:

  • “Implicit declaration of function”

  • “Undefined reference”

  • “Conflicting types”

  • Using a variable outside its scope

  • Missing return statement

When you see errors:

  1. Read the first error carefully.

  2. Look at the line number.

  3. Fix one error at a time.

10. Putting It All Together

Example combining everything:

#include <stdio.h>

int multiply(int a, int b);  // Prototype

int main() {
    int result = multiply(4, 5);
    printf("Result: %d\n", result);
    return 0;
}

int multiply(int a, int b) {
    int product = a * b;  // Local variable
    return product;
}

What we see here:

  • Prototype at the top

  • main() calls function

  • Local variable inside function

  • Proper return type

  • Clean structure

Final Thoughts

Today you learned:

  • The compiler reads top to bottom

  • Declaration is not the same as definition

  • Prototypes prevent errors

  • Scope controls where variables can be used

  • Local variables are safer than global variables

Now you understand how C organizes programs.

You are no longer just writing code.

You are structuring programs properly.

More from this blog

D

Dr. Ehoneah Obed

75 posts

Software engineer writing about systems: in code, in learning, in life. I reverse-engineer complex problems into frameworks. Pharmacist → SWE → Founder.