Submitted by Anonymous (not verified) on Sun, 03/10/2013 - 20:04

Pointers and Functions

Before I talk about passing pointers to functions, let's first have a look at how to pass arrays to functions.

Passing Arrays to Functions
In practice, it's usually awkward if you pass more than five or six arguments to a function. One way to save the number of arguments passed to a function is to use arrays. You can put all variables of the same type into an array, and then pass the array as a single argument.

The program in Listing 16.4 shows how to pass an array of integers to a function.

TYPE
Listing 16.4. Passing arrays to functions.


1:  /* 16L04.c: Passing arrays to functions */
2:  #include <stdio.h>
3:
4:  int AddThree(int list[]);
5:
6:  main()
7:  {
8:     int sum, list[3];
9:
10:    printf("Enter three integers separated by spaces:\n");
11:    scanf("%d%d%d", &list[0], &list[1], &list[2]);
12:    sum = AddThree(list);
13:    printf("The sum of the three integers is: %d\n", sum);
14:
15:    return 0;
16: }
17:
18: int AddThree(int list[])
19: {
20:    int i;
21:    int result = 0;
22:
23:    for (i=0; i<3; i++)
24:       result += list[i];
25:    return result;
26: }


The following output is obtained after I run the executable, 16L04.exe, and enter three integers, 10, 20, and 30, from a DOS prompt:

OUTPUT

C:\app>16L04
Enter three integers separated by spaces:
10  20  30
The sum of the three integers is: 60
C:\app>

ANALYSIS

The purpose of the program in Listing 16.4 is to obtain three integers entered by the user, and then pass the three integers as an array to a function called AddThree() to perform the operation of addition.

Line 4 gives the declaration of the AddThree() function. Note that the unsized array, list[], is used in the argument expression, which indicates that the argument contains the start address of the list array.

The list array and an integer variable, sum, are declared in line 8. The printf() function in line 10 displays a message asking the user to enter three integers. Then, line 11 fetches the integers entered by the user and stores them in the three memory locations of the elements in the integer array referenced by &list[0], &list[1], and &list[2], respectively.

The statement in line 12 calls the AddThree() function with the name of the array as the argument. The AddThree(list) expression is actually passing the start address of the list array to the AddThree() function.

The definition of the AddThree() function is in lines 18_26; it adds the values of all three elements in the list array and returns the sum. The result returned from the AddThree() function is assigned to the integer variable sum in line 12 and is printed out in line 13.

NOTE

    You can also specify the size of an array that is passed to a function. For instance, the following

    function(char str[16]);


    is equivalent to the following statement:

    function(char str[]);


    Remember that the compiler can figure out the size for the unsized array str[].
    For multidimensional arrays, the format of an unsized array should always be used in the declaration. (See the section titled "Passing Multidimensional Arrays as Arguments," later in this hour.)

Passing Pointers to Functions

As you know, an array name that is not followed by a subscript is interpreted as a pointer to the first element of the array. In fact, the address of the first element in an array is the start address of the array. Therefore, you can assign the start address of an array to a pointer, and then pass the pointer name, instead of the unsized array, to a function.

Listing 16.5 gives an example of passing pointers to functions, which is similar to the situation in which arrays are passed to functions.

TYPE
Listing 16.5. Passing pointers to functions.


1:  /* 16L05.c: Passing pointers to functions */
2:  #include <stdio.h>
3:
4:  void ChPrint(char *ch);
5:  int DataAdd(int *list, int max);
6:  main()
7:  {
8:     char str[] = "It's a string!";
9:     char *ptr_str;
10:    int list[5] = {1, 2, 3, 4, 5};
11:    int *ptr_int;
12:
13:    /* assign address to pointer */
14:    ptr_str = str;
15:    ChPrint(ptr_str);
16:    ChPrint(str);
17:
18:    /* assign address to pointer */
19:    ptr_int = list;
20:    printf("The sum returned by DataAdd(): %d\n",
21:            DataAdd(ptr_int, 5));
22:    printf("The sum returned by DataAdd(): %d\n",
23:            DataAdd(list, 5));
24:    return 0;
25: }
26: /* function definition */
27: void ChPrint(char *ch)
28: {
29:    printf("%s\n", ch);
30: }
31: /* function definition */
32: int DataAdd(int *list, int max)
33: {
34:    int i;
35:    int sum = 0;
36:
37:    for (i=0; i<max; i++)
38:       sum += list[i];
39:    return sum;
40: }


After executing the 16L05.exe program, the following output is displayed on the screen:

OUTPUT

C:\app>16L05
It's a string!
It's a string!
The sum returned by DataAdd(): 15
The sum returned by DataAdd(): 15
C:\app>

ANALYSIS

The purpose of the program in Listing 16.5 is to demonstrate how to pass an integer pointer that points to an integer array and a character pointer that references a character string to two functions that are declared in lines 4 and 5.

Note that expressions, such as char *ch and int *list, are used as arguments in the function declarations, which indicates to the compiler that a char pointer and an int pointer are respectively passed to the functions ChPrint() and DataAdd().

Inside the main() function body, lines 8 and 9 declare a char array (str) that is initialized with a character string, and a char pointer variable (ptr_str). Line 10 declares and initializes an int array (list) with a set of integers. An int pointer variable, ptr_int, is declared in line 11.

The start address of the str array is assigned to the ptr_str pointer by the assignment statement in line 14. Then, the ptr_str pointer is passed to the ChPrint() function as the argument in line 15. According to the definition of ChPrint() in lines 27_30, the content of the str array whose start address is passed to the function as the argument is printed out by the printf() function that is invoked inside the ChPrint() function in line 29.

In fact, you can still use the name of the str array as the argument and pass it to the ChPrint() function. Line 16 shows that the start address of the character array is passed to ChPrint() via the name of the array.

The statement in line 19 assigns the start address of the integer array list to the integer pointer ptr_int. Then, the ptr_int pointer is passed to the DataAdd() function in line 21, along with 5, which is the maximum number of the elements contained by the list array. From the definition of the DataAdd() function in lines 32_40, you can see that DataAdd() adds all the integer elements in list and returns the sum to the caller. Thereafter, the statement in lines 20 and 21 prints out the result returned from DataAdd().

The expression in line 23 also invokes the DataAdd() function, but this time, the name of the list array is used as the argument to the function. Not surprisingly, the start address of the list array is passed to the DataAdd() function successfully, and the printf() statement in lines 22 and 23 displays the right result on the screen.
Passing Multidimensional Arrays as Arguments

In Chapter 12, "Storing Similar Data Items," you learned about multidimensional arrays. In this section, you're going to see how to pass multidimensional arrays to functions.

As you might have guessed, passing a multidimensional array to a function is similar to passing a one-dimensional array to a function. You can either pass the unsized format of a multidimensional array or a pointer that contains the start address of the multidimensional array to a function. Listing 16.6 is an example of these two methods.

TYPE
Listing 16.6. Passing multidimensional arrays to functions.


1:  /* 16L06.c: Passing multidimensional arrays to functions */
2:  #include <stdio.h>
3:  /* function declarations */
4:  int DataAdd1(int list[][5], int max1, int max2);
5:  int DataAdd2(int *list, int max1, int max2);
6:  /* main() function */
7:  main()
8:  {
9:     int list[2][5] = {1, 2, 3, 4, 5,
10:                      5, 4, 3, 2, 1};
11:    int *ptr_int;
12:
13:    printf("The sum returned by DataAdd1(): %d\n",
14:            DataAdd1(list, 2, 5));
15:    ptr_int = &list[0][0];
16:    printf("The sum returned by DataAdd2(): %d\n",
17:            DataAdd2(ptr_int, 2, 5));
18:
19:    return 0;
20: }
21: /* function definition */
22: int DataAdd1(int list[][5], int max1, int max2)
23: {
24:    int i, j;
25:    int sum = 0;
26:
27:    for (i=0; i<max1; i++)
28:       for (j=0; j<max2; j++)
29:       sum += list[i][j];
30:    return sum;
31: }
32: /* function definition */
33: int DataAdd2(int *list, int max1, int max2)
34: {
35:    int i, j;
36:    int sum = 0;
37:
38:    for (i=0; i<max1; i++)
39:       for (j=0; j<max2; j++)
40:       sum += *(list + i*max2 + j);
41:    return sum;
42: }


The following output is displayed on the screen after the executable (16L06.exe) is executed:

OUTPUT

C:\app>16L06
The sum returned by DataAdd1(): 30
The sum returned by DataAdd2(): 30
C:\app>

ANALYSIS

At the beginning of the program in Listing 16.6, I declare two functions, DataAdd1() and DataAdd2(), in lines 4 and 5. Note that the first argument to DataAdd1() in line 4 is the unsized array of list. In fact, list is a two-dimensional integer array declared in lines 9 and 10 inside the main() function body. The other two arguments, max1 and max2, are two dimension sizes of the list array.

As you can tell from the definition of DataAdd1() in lines 22_31, each element of the list array, expressed as list[i][j], is added and assigned to a local variable called sum that is returned at the end of the DataAdd1() function in line 30. Here i is from 0 to max1 - 1, and j is within the range of 0 to max2 - 1.

The DataAdd1() function is called in line 14, with the name of the list array and the two dimension sizes, 2 and 5. The result returned by DataAdd1() is printed out by the statement in lines 13 and 14. So you see, passing a multidimensional array to a function is quite similar to passing a one-dimensional array to a function.

Another way to do the job is to pass a pointer that contains the start address of a multidimensional array to a function. In this example, the DataAdd2() function is declared in line 5 with a pointer expression, int *list, as the function's first argument. The definition of DataAdd2() is given in lines 33_42.

Note that in line 40, each element in the list array is fetched by moving the pointer to point to the memory location of the element. That is, the dereferenced pointer *(list + i*max2 + j) returns the value of an element that is located at row i and column j, if you imagine that the two-dimensional array has both a horizontal and a vertical dimension. Therefore, adding i*max2 to list calculates the address of row i (that is, rows 0 through i-1 are skipped over); then adding j calculates the address of element j (that is, column j) in the current row (i). In this example, the range of the row is from 0 to 1 (that is, 2 rows total); the range of the column is from 0 to 4 (that is, 5 columns total). (See Figure 16.1.)

The result returned by the DataAdd2() function is displayed on the screen by the statement declared in lines 16 and 17.

Related Items

মডুলার C প্রোগ্রামিং (Modular C Programming)

কেবল মাত্র একটি ফাংশন দিয়ে কোনো বড়ো জটিল সমস্যা সমাধানের চেষ্টা করা ভাল প্রোগ্রামিংয়ের পদ্ধতি নয়। সঠিক পদ্ধতি হ'ল সমস্যাটিকে কয়েকটি ছোট ছোট এবং সরল টুকরো করে ফেলা যাতে তা আরও বিশদে বোঝা যায় । তারপরে এই ছোট এবং সরল সমস্যাগুলি সমাধান করার জন্য ছোট ছোট ফাংশন ব্লক তৈরি করা এবং পরে সেগুলি নিয়মানুযায়ী সংযোজিত করা ।

Programming Style

Programming Style

In this section, I'd like to briefly highlight some points that will help you write clean programs that can easily be read, understood, and maintained.

Exercises : Answer the following Question

To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish the exercises provided in the Workshop before you move to the next lesson.

Question and Answer

    Q Is the C preprocessor part of the C compiler?

    A No. The C preprocessor is not part of the C compiler. With its own line-oriented grammar and syntax, the C preprocessor runs before the compiler in order to handle named constants, macros, and inclusion of files.

Compiling Your Code Under Conditions

Compiling Your Code Under Conditions

You can select portions of your C program that you want to compile by using a set of preprocessor directives. This is useful, especially when you're testing a piece of new code or debugging a portion of code.