Skip to content

Function Argument Parameters

Call by Value

Pass Value(s) to a function

Sum two numbers.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Sum 2 numbers

#include <stdio.h>
#include <limits.h>
#include <stdint.h>

// TIP: Call by value (without use start "*"")
int64_t sum(int64_t a, int64_t b)
{
  // TIP: enlarge to int64_t before add two values
  return ((int64_t)a + (int64_t)b);
}

int main(void)
{
  // TIP: better to use int32_t (not int)
  int32_t x;
  int32_t y = x = INT_MAX;

  int64_t s = sum(x, y);
  printf("0x%X + 0x%X = 0x%lX(%ld)\n", INT32_MAX, INT32_MAX, s, s);

  return 0;
}

Call by Address

Pass Point(s) to a function

Swap 2 numbers.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// an example for swap 2 values with call by address

#include <stdio.h>

// BAD example: call by value
void swap_call_by_value(int p, int q)
{
  int tmp = p;
  p = q;
  q = tmp;
}

// GOOD example: call by address
void swap_call_by_address(int *p, int *q)
{
  int tmp = *p;
  *p = *q;
  *q = tmp;
}

// GOOD example with XOR: call by address
void swap_call_by_address_xor_1(int *p, int *q)
{
  *p ^= *q;
  *q ^= *p;
  *p ^= *q;
}

// GOOD example with XOR: call by address
void swap_call_by_address_xor_2(int *p, int *q)
{
  *p ^= *q ^= *p ^= *q;
}

#if (0)  // There is no call by reference in C
void swap_call_by_reference(int &a, int &b)
{
  int tmp = a;
  a = b;
  b = tmp;
}
#endif

int main(void)
{
  int x = 2, y = 3;
  printf("x: %d, y: %d\n", x, y);

  // incorrect method to swap two values
  swap_call_by_value(x, y);
  printf("BAD example:  x: %d, y: %d\n", x, y);

  // correct method to swap two values by using temporary variable
  swap_call_by_address(&x, &y);
  printf("GOOD example: x: %d, y: %d\n", x, y);

  // correct method to swap two value by using xor
  swap_call_by_address_xor_1(&x, &y);
  printf("GOOD example: x: %d, y: %d\n", x, y);

  swap_call_by_address_xor_2(&x, &y);
  printf("GOOD example: x: %d, y: %d\n", x, y);

#if (0)
  swap_call_by_reference(x, y);
#endif

  return 0;
}

Swap 2 strings.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// https://www.geeksforgeeks.org/swap-strings-in-c/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// BAD example: should be use double (**)
void swap(char *str1, char *str2)
{
  char *temp = str1;
  str1 = str2;
  str2 = temp;
}

// GOOD example: Swap Pointers
void swap1(char **str1_ptr, char **str2_ptr)
{
  char *temp = *str1_ptr;
  *str1_ptr = *str2_ptr;
  *str2_ptr = temp;
}

// GOOD example: Swap Data
void swap2(char *str1, char *str2)
{
  char *temp = (char *)malloc((strlen(str1) + 1) * sizeof(char));
  strcpy(temp, str1);
  strcpy(str1, str2);
  strcpy(str2, temp);
  free(temp);
}

int main()
{
  // TIP: below assigment equs to
  //      char *str1;
  //      char str[] = "geeks";
  //      *str = &str[0];
  //         0   1   2   3   4   5
  //       +---+---+---+---+---+---+
  //       | g | e | e | k | s | \0|
  //       +---+---+---+---+---+---+
  //  ex. 0xB00000000
  //       |
  //       +-------------+
  //  str1 | 0xB00000000 |
  //       +-------------+
  //  ex. 0xB0000010
  //

  char *str1 = "geeks";
  char *str2 = "forgeeks";

  printf("[%s():%d] Original: str1 is %s, str2 is %s\n", __func__, __LINE__, str1, str2);

  swap(str1, str2);
  printf("[%s():%d] BAD:      str1 is %s, str2 is %s\n", __func__, __LINE__, str1, str2);

  swap1(&str1, &str2);
  printf("[%s():%d] GOOD:     str1 is %s, str2 is %s\n", __func__, __LINE__, str1, str2);

  // TIP:
  //         0   1   2   3   4   5   6   7   8   9
  //       +---+---+---+---+---+---+---+---+---+---+
  //       | g | e | e | k | s | \0|   |   |   |   |
  //       +---+---+---+---+---+---+---+---+---+---+
  //  ex. 0x12345678
  char str3[10] = "geeks";
  char str4[10] = "forgeeks";

  swap2(str3, str4);
  printf("[%s():%d] str3 is %s, str4 is %s\n", __func__, __LINE__, str3, str4);

  //getchar();
  return 0;
}

Pass Dobule-Pointer to a function

Copies the C string pointed by source into the pointed.

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>

// pass double point to a function
int my_strcpy(char **dest, char const *src, int len)
{
  // TIP: print the address
  printf("[%12s: %d] destination (%p): %s\n", __func__, __LINE__, dest, *dest);

  // TIP: Initial memory allocation and assign its address to a variable
  char *p = calloc(0, sizeof(char) * (len + 1));       /* +1 for \0 */

  if (p == NULL)
    return 0;

  memcpy(p, src, len + 1);

  // TIP: record to a variable
  *dest = p;
  printf("[%12s: %d] destination (%p): %s\n", __func__, __LINE__, dest, *dest);

  return 1;
}

int main(void)
{
  char *source = "Hello, world! Hello, world! Hello, world! Hello, world!!";
  char *destination = NULL;

  printf("[%12s: %d] source      (%p): %s\n", __func__, __LINE__, source, source);
  printf("[%12s: %d] destination (%p): %s\n", __func__, __LINE__, &destination, destination);

  if (my_strcpy(&destination, source, strnlen(source, UINT_MAX)))
    printf("[%12s: %d] destination (%p): %s\n", __func__, __LINE__, &destination, destination);
  else
    fprintf(stderr, "[%s: %d] out of memory\n", __func__, __LINE__);

  // TIP: Deallocate allocated memory in main()
  if (destination)
  {
    free(destination);
    destination = NULL;
  }
  return 0;
}

Pass a Triple-pointer to a function

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>

#include <ctype.h>

void initialize(double ***A, int r, int c)
{
  *A = (double **)malloc(sizeof(double *) * r);
  for (int i = 0; i < r; i++)
  {
    (*A)[i] = (double *)malloc(sizeof(double) * c);
    for (int j = 0; j < c; j++)
    {
      (*A)[i][j] = 0.0;
    }
  }
}

int main()
{
  double **A;
  initialize(&A, 10, 10);

  return 1;
}

Pass a structure to to a function

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// https://stackoverflow.com/questions/10066709/passing-struct-pointer-to-function-in-c
// https://stackoverflow.com/questions/5060641/does-a-string-created-with-strcpy-need-to-be-freed

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

struct item
{
  char name[10];
  int age;
};

struct item *modify_item2(void)
{
  struct item *retVal = malloc(sizeof(struct item));
  strcpy(retVal->name, "Tom2");
  retVal->age = 5;
  return retVal;
}

void modify_item(struct item **s)
{
  struct item *retVal = malloc(sizeof(struct item));
  strcpy(retVal->name, "Tom");
  retVal->age = 10;

  *s = retVal;
}

int main(void)
{

  struct item *stuff = NULL;

  // Method 1: call by address
  modify_item(&stuff);
  printf("Name: %s\n", stuff->name);
  printf("Age:  %d\n", stuff->age);

  // strcpy doesn't need to be freed
  // strcpy() doesn't create a string, it only copies a string. Memory allocation is completely separated from that process.
  // free(stuff->name);

  if (stuff)
  {
    free(stuff);
    stuff = NULL;
  }

  printf("==================================\n");

  struct item *stuff2 = NULL;

  // Method 2: return a struct
  stuff2 = modify_item2();
  printf("Name2: %s\n", stuff2->name);
  printf("Age2:  %d\n", stuff2->age);

  if (stuff2)
  {
    free(stuff2);
    stuff2 = NULL;
  }

  return 0;
}

Pass a structure-in-structure to a function

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// https://www.geeksforgeeks.org/structure-pointer/

// C program to illustrate the
// structure pointer

#include <stdio.h>

// Structure declaration for
// vertices
struct point {
    int x;
    int y;
};

// Strcuture declaration for
// rectangle
struct rect {

    // An object left is declared
    // with 'point'
    struct point left;

    // An object right is declared
    // with 'point'
    struct point right;
};

// Function to calculate area of
// the given rectangle
void areaOfRectangle(struct rect r)
{
    // Find the area of the rectangle
    // using variables of point
    // structure where variables of
    // point structure is accessed
    // by left and right objects
    int area
        = (r.right.x - r.left.x)
        * (r.right.y - r.left.y);

    // Print the area
    printf("%d", area);
}

// Driver Code
int main()
{
    // Initialize variable 'r'
    // with vertices of rectangle
    struct rect r = { { 2, 3 }, { 5, 2 } };

    // Function Call
    areaOfRectangle(r);

    return 0;
}

Pass a function point to a function

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// https://www.runoob.com/cprogramming/c-fun-pointer-callback.html

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

// pass callback function
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{
  for (size_t i = 0; i < arraySize; i++)
    array[i] = getNextValue();
}

// Get random value
int getNextRandomValue(void)
{
  int a;
  a = rand() % 100 + 1;
  return a;
}

int main(void)
{
  int myarray[10] = {0};

  // TIP: srand in main not in function
  srand(time(NULL));

  // normally function call
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", getNextRandomValue());
  }

  printf("\n");

  // TIP: pass getNextRandomValue as function point to populate_array function
  populate_array(myarray, 10, getNextRandomValue);

  for (int i = 0; i < 10; i++)
  {
    printf("%d ", myarray[i]);
  }

  printf("\n");
  return 0;
}