Functions — Declaration, Scope & Storage

abstraction-এর একক

~30 min Intermediate 14 practice problems Live code

1. Functions — The Unit of Abstraction

A function is a named, parameterised block of code that returns a value. Every large program is a tree of functions.

Function হলো একটি নামকরা, parameterised কোড ব্লক যা একটি মান (value) return করে। প্রতিটি বড় প্রোগ্রাম আসলে ছোট ছোট function-এর একটি গাছ (tree) — যেখানে main root।

2. Declaration, Definition, Call

add_demo.c
#include <stdio.h>

// Declaration (prototype) — tells compiler the signature.
int add(int a, int b);

int main(void) {
    printf("add(3, 4) = %d\n", add(3, 4));  // call
    return 0;
}

// Definition — actual implementation.
int add(int a, int b) { return a + b; }
Prototype থাকার কারণে আপনি একটি function-কে এর definition লেখার আগেই call করতে পারেন। Header file-এ সাধারণত শুধু prototype রাখা হয়, implementation থাকে .c ফাইলে।

3. Pass by Value — Always

C সবসময় pass by value করে। Argument-এর একটি copy তৈরি হয়। Pointer পাঠিয়ে caller-এর variable modify করা যায়, কিন্তু সেই pointer-ও pass by value-তেই যায়।

swap.c
#include <stdio.h>

void bad_swap(int a, int b) { int t = a; a = b; b = t; }
void swap(int *a, int *b)     { int t = *a; *a = *b; *b = t; }

int main(void) {
    int x = 1, y = 2;
    bad_swap(x, y);
    printf("after bad_swap  : x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("after real swap : x=%d, y=%d\n", x, y);
    return 0;
}

4. Scope — Where Names Live

  • Block scope — { ... }-এর ভেতরে ঘোষিত, বাইরে অদৃশ্য।
  • Function scope — goto label-এর জন্য।
  • File (translation unit) scope — global declaration।
  • Function prototype scope — prototype-এ parameter নাম।

5. Storage Classes

KeywordLifetimeLinkageTypical use
autoblocknonelocal variable default (rarely typed)
static (local)programnonepersistent local state
static (global)programinternalfile-private global
externprogramexternalrefer to a global defined elsewhere
registerblocknonehint (obsolete)
static_counter.c
#include <stdio.h>

int counter(void) {
    static int count = 0;    // survives between calls
    return ++count;
}

int main(void) {
    for (int i = 0; i < 5; i++)
        printf("%d\n", counter());
    return 0;
}
static int local variable প্রতিবার ফাংশন call-এ নতুন হয় না — আগের মানই থাকে। তাই counter, memoization-এর মতো কাজে উপযোগী।

6. Designing Good Functions

  • একটি function-এ শুধু একটি কাজ।
  • ছোট রাখুন — আদর্শ ৩০ লাইনের নিচে।
  • নাম স্পষ্ট ও বর্ণনামূলক: compute_average, func1 নয়।
  • Error থাকলে শুরুতেই return করুন।
  • যে pointer modify করবেন না, সেটিকে const করুন।

7. Practice Problems

  1. Write int max3(int a, int b, int c).
    তিনটি int-এর maximum return করে এমন ফাংশন লিখুন।
    ✨ Show Answer
    max3.c
    #include <stdio.h>
    int max3(int a, int b, int c) {
        int m = a;
        if (b > m) m = b;
        if (c > m) m = c;
        return m;
    }
    int main(void) { printf("%d\n", max3(7, 42, 13)); return 0; }
  2. Write double distance(double x1, double y1, double x2, double y2).
    দুটি বিন্দুর মধ্যে Euclidean দূরত্ব বের করুন।
    ✨ Show Answer
    distance.c
    #include <stdio.h>
    #include <math.h>
    double distance(double x1, double y1, double x2, double y2) {
        double dx = x2 - x1, dy = y2 - y1;
        return sqrt(dx*dx + dy*dy);
    }
    int main(void) { printf("%.4f\n", distance(0,0,3,4)); return 0; }
  3. Write int is_prime(int n).
    একটি সংখ্যা prime কি না নির্ধারণ করুন।
    ✨ Show Answer
    is_prime.c — stdin: 97
    #include <stdio.h>
    int is_prime(int n) {
        if (n < 2) return 0;
        for (int i = 2; i*i <= n; i++) if (n % i == 0) return 0;
        return 1;
    }
    int main(void) {
        int n; scanf("%d", &n);
        printf("%d is %sprime\n", n, is_prime(n) ? "" : "not ");
        return 0;
    }
  4. Write and test void swap(int *, int *).
    pointer দিয়ে swap লিখে test করুন।
    ✨ Show Answer

    উপরের Section 3-এর swap.c-ই পুরো উত্তর।

  5. Implement size_t my_strlen(const char *s) without the standard library.
    Library ছাড়াই my_strlen লিখুন।
    ✨ Show Answer
    my_strlen.c
    #include <stdio.h>
    #include <stddef.h>
    size_t my_strlen(const char *s) {
        const char *p = s;
        while (*p) p++;
        return p - s;
    }
    int main(void) { printf("%zu\n", my_strlen("ABCL TECH")); return 0; }
  6. Static-counter function — returns 1, 2, 3, … on each call.
    Static counter function — প্রতিবার call-এ 1, 2, 3, … return করবে।
    ✨ Show Answer

    উপরের Section 5-এর static_counter.c-ই সম্পূর্ণ উত্তর।

  7. Explain why register is effectively dead today.
    আজকের দিনে register keyword কেন অর্থহীন হয়ে গেছে?
    ✨ Show Answer

    আধুনিক optimizing compiler নিজেই সবচেয়ে ভালোভাবে নির্ধারণ করতে পারে কোন variable CPU register-এ রাখা হবে। তাই register hint আর কোনো উন্নতি আনে না। উপরন্তু, register variable-এর address নেওয়া (&) যায় না, যা বাধা তৈরি করে। C++-এ এটি deprecated।

  8. Two files share a global via extern — write a minimal example.
    দুটি ফাইল extern দিয়ে একটি global share করবে — minimum উদাহরণ দিন।
    ✨ Show Answer
    // file1.c
    int counter = 0;            // definition
    
    // file2.c
    extern int counter;         // declaration referring to file1's definition
    void bump(void) { counter++; }
    
    // Compile: gcc file1.c file2.c -o app
  9. Find the bug: a function returns the address of a local int.
    ভুল খুঁজুন: একটি ফাংশন একটি local int-এর address return করছে।
    ✨ Show Answer

    Local variable function return করলেই ধ্বংস হয়ে যায়। তার address-কে পরে dereference করা undefined behavior — memory ওখানে আর নেই বা overwrite হয়ে গেছে। সমাধান: malloc-এ allocate করুন বা static বানান বা caller-এর buffer-এ লিখুন।

  10. Write recursive and iterative factorial. Compare runtimes for large n.
    Factorial-এর recursive ও iterative version লিখুন এবং বড় n-এ performance তুলনা করুন।
    ✨ Show Answer
    fact_two.c
    #include <stdio.h>
    long long fact_rec(int n) { return n <= 1 ? 1 : n * fact_rec(n - 1); }
    long long fact_it(int n)  { long long f = 1; for (int i = 2; i <= n; i++) f *= i; return f; }
    int main(void) {
        printf("rec 20! = %lld\n", fact_rec(20));
        printf("it  20! = %lld\n", fact_it(20));
        return 0;
    }

    Iterative version stack frame overhead বাঁচায়, তাই সাধারণত সামান্য দ্রুত। n = 20-এর পর result long long-এও ওভারফ্লো করে।

  11. Write a function that takes an array and its length and returns the sum.
    একটি array এবং length নিয়ে sum return করে এমন ফাংশন লিখুন।
    ✨ Show Answer
    array_sum.c
    #include <stdio.h>
    long sum(const int *a, int n) {
        long s = 0;
        for (int i = 0; i < n; i++) s += a[i];
        return s;
    }
    int main(void) {
        int a[] = {5, 8, 13, 21, 34};
        printf("sum = %ld\n", sum(a, 5));
        return 0;
    }
  12. Write void reverse_string(char *s) that reverses in place.
    String in-place reverse করার ফাংশন লিখুন।
    ✨ Show Answer
    reverse_string.c
    #include <stdio.h>
    #include <string.h>
    void reverse_string(char *s) {
        size_t n = strlen(s);
        for (size_t i = 0, j = n ? n - 1 : 0; i < j; i++, j--) {
            char t = s[i]; s[i] = s[j]; s[j] = t;
        }
    }
    int main(void) {
        char s[] = "Bangladesh";
        reverse_string(s);
        printf("%s\n", s);
        return 0;
    }
  13. Write a function with static cache that remembers the last computed Fibonacci number.
    Static cache-যুক্ত একটি Fibonacci ফাংশন লিখুন যা শেষবারের হিসাব মনে রাখে।
    ✨ Show Answer
    fib_cache.c
    #include <stdio.h>
    long fib_cached(int n) {
        static int  last_n   = -1;
        static long last_val = 0;
        if (n == last_n) return last_val;   // cache hit
        long a = 0, b = 1;
        for (int i = 0; i < n; i++) { long t = a + b; a = b; b = t; }
        last_n = n; last_val = a;
        return a;
    }
    int main(void) {
        printf("%ld\n", fib_cached(30));
        printf("%ld\n", fib_cached(30));   // second call returns from cache
        return 0;
    }
  14. Why does C not allow function overloading?
    C কেন function overloading অনুমোদন করে না?
    ✨ Show Answer

    C-র name mangling (signature অনুযায়ী unique symbol বানানো) নেই — linker শুধু নাম দেখে function খুঁজে নেয়। দুটি ফাংশনের নাম একই হলে linker একাধিক definition-এর জন্য error দেয়। C++ এই সমস্যা সমাধান করে, তাই সেখানে overloading আছে।

Glossary (শব্দকোষ)

TermMeaningবাংলায়
FunctionA named, reusable block of code that may take inputs and return a value.নামকরা, পুনঃব্যবহারযোগ্য code block।
ParameterThe variable that receives an input in a function definition.Function definition-এ input ধারণকারী variable।
ArgumentThe actual value passed when calling a function.Call-এর সময় পাঠানো প্রকৃত মান।
Return TypeThe type of value a function returns.Function যে type-এর মান ফেরত দেয়।
PrototypeA function declaration without body — tells compiler the signature.Body ছাড়া function declaration।
DefinitionThe actual implementation of a function.Function-এর প্রকৃত implementation।
Pass by ValueThe function gets a copy of the argument.Function পায় argument-এর copy।
ScopeThe region of code where a name is visible.একটি নাম কোথায় দৃশ্যমান।
Local VariableDefined inside a function — visible only there.Function-এর ভিতরে সংজ্ঞায়িত variable।
Global VariableDefined outside any function — visible everywhere in the file.Function-এর বাইরে সংজ্ঞায়িত variable।
staticStorage class — file-private or persistent local variable.File-private বা persistent local variable।
externRefers to a variable/function defined in another file.অন্য ফাইলে সংজ্ঞায়িত variable/function-এর reference।
Storage ClassDetermines lifetime and visibility (auto, static, extern, register).Variable-এর জীবনকাল ও visibility নির্ধারণ করে।
Stack FrameMemory area for one active function call.চালু থাকা function call-এর জন্য বরাদ্দ মেমরি।

Summary — Module 11

Functions decompose problems. Declare, define, call. All arguments pass by value. Use static for file-private or persistent state. Short, single-purpose functions beat long ones.

Next Module → Recursion — কোডে induction।