Nearby lessons

75 of 124

C - Function Parameters

Parameters are the variables in a function's header that receive incoming values. Learn how to declare them, pass arrays and pointers as parameters, use const to protect inputs, and write a function that takes nothing.

Every Parameter Needs Its Own Type

Unlike variable declarations, you cannot share a type across parameters:

Example01
CCode Cell
1#include <stdio.h>
2 
3/* int badSum(int a, b) INVALID - b has no type */
4 
5int sum3(int a, int b, int c) /* each type stated */
6{
7 return a + b + c;
8}
9 
10void describe(char name[], int age, float height) /* mixed types */
11{
12 printf("%s is %d years old and %.2f m tall\n", name, age, height);
13}
14 
15int main()
16{
17 printf("sum3 = %d\n", sum3(1, 2, 3));
18 describe("Rahul", 25, 1.75f);
19 return 0;
20}
Output
sum3 = 6
Rahul is 25 years old and 1.75 m tall

Parameters Are Local Variables

A parameter behaves exactly like a local variable that was initialised from the argument. You can even reassign it — the caller is unaffected:

Example02
CCode Cell
1#include <stdio.h>
2 
3int countdown(int n)
4{
5 int total = 0;
6 
7 while (n > 0) /* modifying the parameter is fine */
8 {
9 total += n;
10 n--;
11 }
12 return total;
13}
14 
15int main()
16{
17 int x = 5;
18 
19 printf("countdown(%d) = %d\n", x, countdown(x));
20 printf("x is still %d\n", x); /* unchanged */
21 return 0;
22}
Output
countdown(5) = 15
x is still 5

Array Parameters Decay to Pointers

An array parameter is really a pointer. That is why sizeof inside the function gives the pointer size, and why the size must be passed separately:

Example03
CCode Cell
1#include <stdio.h>
2 
3/* These three headers are identical to the compiler */
4int sumArray(int a[], int size)
5{
6 int i, total = 0;
7 
8 printf("sizeof(a) inside = %zu (a pointer!)\n", sizeof(a));
9 
10 for (i = 0; i < size; i++) total += a[i];
11 return total;
12}
13 
14int main()
15{
16 int nums[5] = {10, 20, 30, 40, 50};
17 
18 printf("sizeof(nums) in main = %zu\n", sizeof(nums));
19 printf("Sum = %d\n", sumArray(nums, 5));
20 return 0;
21}
Output
sizeof(nums) in main = 20
sizeof(a) inside = 8 (a pointer!)
Sum = 150

Arrays Are Effectively Passed by Reference

Because the function receives the address, changes to the elements are visible to the caller:

Example04
CCode Cell
1#include <stdio.h>
2 
3void doubleAll(int a[], int size)
4{
5 int i;
6 for (i = 0; i < size; i++)
7 a[i] *= 2; /* modifies the caller's array */
8}
9 
10int main()
11{
12 int nums[5] = {1, 2, 3, 4, 5};
13 int i;
14 
15 doubleAll(nums, 5);
16 
17 printf("After doubleAll: ");
18 for (i = 0; i < 5; i++) printf("%d ", nums[i]);
19 printf("\n");
20 return 0;
21}
Output
After doubleAll: 2 4 6 8 10 

const Parameters — A Promise Not to Modify

Marking a pointer parameter const documents your intent and lets the compiler enforce it:

Example05
CCode Cell
1#include <stdio.h>
2 
3int findMax(const int a[], int size) /* promises: read only */
4{
5 int i, max = a[0];
6 
7 /* a[0] = 99; ERROR: assignment of read-only location */
8 
9 for (i = 1; i < size; i++)
10 if (a[i] > max) max = a[i];
11 return max;
12}
13 
14int main()
15{
16 int nums[5] = {23, 67, 12, 89, 45};
17 
18 printf("Max = %d\n", findMax(nums, 5));
19 return 0;
20}
Output
Max = 89

Pointer Parameters — Modifying the Caller

To let a function change a caller's scalar variable, pass its address and take a pointer parameter:

Example06
CCode Cell
1#include <stdio.h>
2 
3void swap(int *x, int *y) /* pointer parameters */
4{
5 int temp = *x;
6 *x = *y;
7 *y = temp;
8}
9 
10int main()
11{
12 int a = 10, b = 20;
13 
14 printf("Before: a=%d b=%d\n", a, b);
15 swap(&a, &b); /* pass addresses */
16 printf("After : a=%d b=%d\n", a, b);
17 return 0;
18}
Output
Before: a=10 b=20
After : a=20 b=10

Returning Several Values

A function returns one value — but with pointer parameters it can hand back as many as you need:

Example07
CCode Cell
1#include <stdio.h>
2 
3void statistics(const int a[], int size, int *min, int *max, float *avg)
4{
5 int i, total = 0;
6 
7 *min = *max = a[0];
8 for (i = 0; i < size; i++)
9 {
10 if (a[i] < *min) *min = a[i];
11 if (a[i] > *max) *max = a[i];
12 total += a[i];
13 }
14 *avg = (float) total / size;
15}
16 
17int main()
18{
19 int nums[6] = {45, 12, 78, 33, 90, 25};
20 int lo, hi;
21 float mean;
22 
23 statistics(nums, 6, &lo, &hi, &mean);
24 
25 printf("Min = %d, Max = %d, Avg = %.2f\n", lo, hi, mean);
26 return 0;
27}
Output
Min = 12, Max = 90, Avg = 47.17

Struct Parameters

A struct is copied whole by default. For anything large, pass a const pointer instead to avoid the copy:

Example08
CCode Cell
1#include <stdio.h>
2 
3struct Point { int x, y; };
4 
5void printByValue(struct Point p) /* copies the struct */
6{
7 printf("By value : (%d, %d)\n", p.x, p.y);
8}
9 
10void printByPointer(const struct Point *p) /* no copy */
11{
12 printf("By pointer: (%d, %d)\n", p->x, p->y);
13}
14 
15int main()
16{
17 struct Point pt = {3, 7};
18 
19 printByValue(pt);
20 printByPointer(&pt);
21 return 0;
22}
Output
By value  : (3, 7)
By pointer: (3, 7)

2D Array Parameters

Every dimension except the first must be specified so the compiler can compute row offsets:

Example09
CCode Cell
1#include <stdio.h>
2 
3void printMatrix(int m[][3], int rows) /* [3] is required */
4{
5 int i, j;
6 for (i = 0; i < rows; i++)
7 {
8 for (j = 0; j < 3; j++) printf("%4d", m[i][j]);
9 printf("\n");
10 }
11}
12 
13int main()
14{
15 int m[2][3] = {{1, 2, 3}, {4, 5, 6}};
16 printMatrix(m, 2);
17 return 0;
18}
Output
   1   2   3
   4   5   6

Common Mistakes

MistakeProblem
f(int a, b)b has no type — compile error
sizeof(a) on an array parameterGives the pointer size, not the array size
Forgetting the size parameterThe function cannot know where the array ends
Passing a value where a pointer is expectedThe address is treated as a value
Omitting the second dimension of a 2D parameterCompile error
Passing a huge struct by valueSlow — copies every byte
Trainer's Note: void f(int a[10]) looks like it enforces ten elements. It does not — the 10 is ignored and the parameter is still just int *. Nothing stops a caller passing a 3-element array. The size must travel as a separate argument.
📝 Key Takeaways
  • Each parameter needs its own type: (int a, int b), not (int a, b).
  • Parameters are local variables initialised from the arguments.
  • An array parameter decays to a pointer — pass the size separately.
  • const on a parameter promises the function will not modify it.
  • Use (void) when a function takes no parameters.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4