Nearby lessons

76 of 124

C - Function Arguments

Arguments are the actual values you pass when calling a function, as opposed to the parameters that receive them. Learn the difference, the type-conversion rules, argument evaluation order, and how main receives command-line arguments.

Arguments vs Parameters

The two words describe the same data at different moments:

ParameterArgument
Appears inThe function definitionThe function call
Also calledFormal parameterActual parameter
Is aVariable nameValue or expression
Exampleint add(int a, int b)add(5, x + 2)
In simple words: the parameter is the empty box in the function's header; the argument is what you drop into that box when you call it.
Example01
CCode Cell
1#include <stdio.h>
2 
3int multiply(int a, int b) /* a and b are PARAMETERS */
4{
5 return a * b;
6}
7 
8int main()
9{
10 int x = 4;
11 
12 printf("%d\n", multiply(3, 5)); /* 3 and 5 are ARGUMENTS */
13 printf("%d\n", multiply(x, x + 1)); /* expressions work too */
14 return 0;
15}
Output
15
20

Count and Order Must Match

The compiler checks the count and the types. It cannot check that you got the order right when the types are the same:

Example02
CCode Cell
1#include <stdio.h>
2 
3float divide(float numerator, float denominator)
4{
5 return denominator != 0 ? numerator / denominator : 0;
6}
7 
8int main()
9{
10 /* divide(10.0f); ERROR: too few arguments */
11 /* divide(10, 2, 3); ERROR: too many arguments */
12 
13 printf("divide(10, 2) = %.2f\n", divide(10, 2)); /* correct */
14 printf("divide(2, 10) = %.2f\n", divide(2, 10)); /* legal, wrong */
15 return 0;
16}
Output
divide(10, 2) = 5.00
divide(2, 10) = 0.20

Automatic Type Conversion

An argument is converted to the parameter's type. Widening is safe; narrowing silently loses data:

Example03
CCode Cell
1#include <stdio.h>
2 
3void takesInt(int n) { printf("int got %d\n", n); }
4void takesFloat(float f) { printf("float got %.4f\n", f); }
5void takesChar(char c) { printf("char got '%c' (%d)\n", c, c); }
6 
7int main()
8{
9 takesInt(3.99); /* 3.99 -> 3, fraction lost */
10 takesFloat(5); /* 5 -> 5.0000, safe */
11 takesChar(65); /* 65 -> 'A' */
12 takesInt('A'); /* 'A' -> 65 */
13 return 0;
14}
Output
int    got 3
float  got 5.0000
char   got 'A' (65)
int    got 65

Evaluation Order Is Unspecified

C does not define which argument is evaluated first. Code whose result depends on that order is broken, even if it appears to work:

Example04
CCode Cell
1#include <stdio.h>
2 
3int track(int n)
4{
5 printf(" evaluating %d\n", n);
6 return n;
7}
8 
9int add(int a, int b) { return a + b; }
10 
11int main()
12{
13 int i = 5;
14 
15 printf("Calling add(track(1), track(2)):\n");
16 printf("Result: %d\n", add(track(1), track(2)));
17 
18 /* AVOID: printf("%d %d", i++, i++); order is unspecified */
19 printf("i = %d\n", i);
20 return 0;
21}
Output
Calling add(track(1), track(2)):
  evaluating 2
  evaluating 1
Result: 3
i = 5

Passing Arrays and Strings

You pass an array by giving its name, which is already an address. The size must go along as a separate argument:

Example05
CCode Cell
1#include <stdio.h>
2#include <string.h>
3 
4int sumArray(const int a[], int size)
5{
6 int i, total = 0;
7 for (i = 0; i < size; i++) total += a[i];
8 return total;
9}
10 
11void showLength(const char *s)
12{
13 printf("\"%s\" has %zu characters\n", s, strlen(s));
14}
15 
16int main()
17{
18 int nums[4] = {10, 20, 30, 40};
19 
20 printf("Sum = %d\n", sumArray(nums, 4)); /* name + size */
21 showLength("Hello"); /* literal works */
22 return 0;
23}
Output
Sum = 100
"Hello" has 5 characters

Passing Addresses

When the function must modify your variable, the argument is &variable:

Example06
CCode Cell
1#include <stdio.h>
2 
3void increment(int *n) { (*n)++; }
4 
5int main()
6{
7 int count = 10;
8 
9 increment(&count); /* & makes the argument an address */
10 increment(&count);
11 printf("count = %d\n", count);
12 return 0;
13}
Output
count = 12

Command-Line Arguments

main can take two parameters: the argument count and an array of argument strings. argv[0] is always the program name:

Example07
CCode Cell
1#include <stdio.h>
2 
3int main(int argc, char *argv[])
4{
5 int i;
6 
7 printf("Argument count: %d\n", argc);
8 for (i = 0; i < argc; i++)
9 printf("argv[%d] = %s\n", i, argv[i]);
10 return 0;
11}
12 
13/* Run as: ./program hello 42 */
Output
Argument count: 3
argv[0] = ./program
argv[1] = hello
argv[2] = 42

Converting Command-Line Arguments

Everything in argv arrives as text. Use atoi or strtol to get numbers:

Example08
CCode Cell
1#include <stdio.h>
2#include <stdlib.h>
3 
4int main(int argc, char *argv[])
5{
6 int a, b;
7 
8 if (argc != 3)
9 {
10 printf("Usage: %s <num1> <num2>\n", argv[0]);
11 return 1; /* non-zero = error */
12 }
13 
14 a = atoi(argv[1]); /* text to int */
15 b = atoi(argv[2]);
16 
17 printf("%d + %d = %d\n", a, b, a + b);
18 return 0;
19}
20 
21/* Run as: ./program 15 27 */
Output
15 + 27 = 42

Variable Argument Lists

printf accepts any number of arguments. You can write such functions too, using <stdarg.h>:

Example09
CCode Cell
1#include <stdio.h>
2#include <stdarg.h>
3 
4int sumAll(int count, ...) /* ... means "more arguments follow" */
5{
6 va_list args;
7 int i, total = 0;
8 
9 va_start(args, count);
10 for (i = 0; i < count; i++)
11 total += va_arg(args, int);
12 va_end(args);
13 
14 return total;
15}
16 
17int main()
18{
19 printf("sumAll(3, 10, 20, 30) = %d\n", sumAll(3, 10, 20, 30));
20 printf("sumAll(5, 1, 2, 3, 4, 5) = %d\n", sumAll(5, 1, 2, 3, 4, 5));
21 return 0;
22}
Output
sumAll(3, 10, 20, 30)     = 60
sumAll(5, 1, 2, 3, 4, 5)  = 15

Common Mistakes

  • Wrong argument count — caught by the compiler, so easy to fix.
  • Wrong argument ordernot caught when types match. The commonest silent bug.
  • Passing a value where an address is neededswap(a, b) instead of swap(&a, &b).
  • Forgetting the array size — the function has no way to find the end.
  • Relying on evaluation orderf(i++, i++) is unspecified behaviour.
  • Not checking argc — reading argv[1] when none was supplied dereferences NULL.
Always validate argc before touching argv. argv[argc] is guaranteed to be NULL, so reading argv[1] with argc == 1 passes a null pointer straight into atoi — an immediate crash. Check the count, print a usage line, and return non-zero.
📝 Key Takeaways
  • Parameters are in the definition; arguments are in the call.
  • Argument count and order must match the parameters.
  • An argument is converted to the parameter type, possibly losing data.
  • The order in which arguments are evaluated is unspecified.
  • main(int argc, char *argv[]) receives command-line arguments.

🧠 Test Your Knowledge

4 Questions
Progress: 0 / 4