### Command-Line Arguments (`argc` and `argv`)

In C, command-line arguments are passed to `main()` through two parameters:

```
int main(int argc, char **argv)
```

- `**argc**` **(Argument Count):** The total number of command-line arguments, **including the program name**.
    
- `**argv**` **(Argument Vector):** An array of strings containing the arguments.
    
    - `argv[0]` → Program name or path.    
    - `argv[1]` → First user-provided argument.
    - `argv[2]` → Second user-provided argument.

**Example:**

```
./fib 10
```

|Variable|Value|
|---|---|
|`argc`|`2`|
|`argv[0]`|`"./fib"`|
|`argv[1]`|`"10"`|

To ensure exactly one user-provided argument:

```
if (argc != 2) {
    printf("Invalid number of arguments!\n");
    return EXIT_FAILURE;
}
```

### Function Declaration vs. Function Definition in C

In C, a function can be **declared before `main()`** and **defined after `main()`**. This allows the compiler to recognize a function before encountering its implementation.

#### 1. Function Declaration (Prototype)

A **function declaration** introduces a function to the compiler without providing its implementation.

```c
unsigned long fib(unsigned long n);
```

It specifies:
- **Return type:** `unsigned long`
- **Function name:** `fib`
- **Parameter:** `unsigned long n`
- **Semicolon (`;`):** Indicates that this is only a declaration.

The compiler uses this information to check whether function calls have the correct argument types and return type.

#### 2. Function Definition (Implementation)

A **function definition** provides the actual implementation of the function.

```c
unsigned long fib(unsigned long n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}
```

- Contains the executable code inside `{ }`.
- Defines what the function actually does.
- Also serves as a declaration.

#### 3. Why Separate Declaration and Definition?

C requires a function to be **declared before it is called**.

A declaration allows a function to be called even when its definition appears later in the source file.

**Example:**

```c
#include <stdio.h>

// 1. Function Declaration
unsigned long fib(unsigned long n);

int main(void) {
    // 2. Function Call
    unsigned long result = fib(5);
    printf("%lu\n", result);
    return 0;
}

// 3. Function Definition
unsigned long fib(unsigned long n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}
```

**Source code order:**

1. **Declaration:** Tells the compiler that `fib()` exists and specifies its interface.
2. **Function call:** `main()` calls `fib(5)`.
3. **Definition:** Provides the implementation of `fib()`.

> This represents the order in the source code, not the runtime execution order.

#### 4. Is a Separate Declaration Always Necessary?

**No.** If a function is fully defined before its first use, a separate declaration is unnecessary.

```c
#include <stdio.h>

// Definition comes first
unsigned long fib(unsigned long n) {
    if (n <= 1) return n;
    return fib(n - 1) + fib(n - 2);
}

int main(void) {
    printf("%lu\n", fib(5));
    return 0;
}
```

The compiler already knows `fib()` when it encounters the function call inside `main()`.

#### Declarations in Larger Projects

In larger C projects, declarations and definitions are commonly separated into different files.

| File | Purpose |
|---|---|
| `.h` (Header file) | Contains function declarations (prototypes). |
| `.c` (Source file) | Contains function definitions (implementations). |

This allows multiple source files to use the same function interface without duplicating its implementation.

#### Key Takeaways

- **Declaration:** Describes a function's interface (what it accepts and returns).
- **Definition:** Provides the actual implementation (what it does).
- A function must be declared before it is called.
- A definition also counts as a declaration.
- A separate prototype is unnecessary if the function is already defined before its first use.
- In larger projects, prototypes are typically placed in `.h` files and implementations in `.c` files.

### Converting Strings to Numbers (`strtoul`)

Command-line arguments are always received as **strings**, even when they represent numbers.

The `strtoul()` function, provided by [[Libraries#<stdlib.h> : Standard Library|<stdlib.h>]], converts a string into an `unsigned long` integer.

**Syntax:**

```
strtoul(nptr, endptr, base);
```

|Parameter|Description|
|---|---|
|`nptr`|String to convert|
|`endptr`|Pointer used to identify where conversion stopped; `NULL` if unused|
|`base`|Number system (`10` = decimal, `16` = hexadecimal)|

**Example:**

```
unsigned long val = strtoul(argv[1], NULL, 10);
```

This converts the first user-provided argument from a decimal string into an `unsigned long`.

For `./fib 10`:

- `argv[1]` contains `"10"` (string).
- `strtoul()` converts `"10"` into `10` (number).
- `val` stores the resulting numeric value.

**Important:** `strtoul()` does not automatically guarantee valid input. For robust validation, use `endptr` and `errno` to detect invalid input and conversion errors.