Structures and Function Calls

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

Structures and Function Calls

The C language allows you to pass an entire structure to a function. In addition, a function can return a structure back to its caller.

To show you how to pass a structure to a function, I rewrite the program in Listing 19.1 and create a function called DataReceive() in the program. The upgraded program is shown in Listing 19.3.
 

TYPE
Listing 19.3. Passing a structure to a function.


1:  /* 19L03.c Passing a structure to a function */
2:  #include <stdio.h>
3:
4:  struct computer {
5:     float cost;
6:     int year;
7:     int cpu_speed;
8:     char cpu_type[16];
9:  };
10: /* create synonym */
11: typedef struct computer SC;
12: /* function declaration */
13: SC DataReceive(SC s);
14:
15: main(void)
16: {
17:    SC model;
18:
19:    model = DataReceive(model);
20:    printf("Here are what you entered:\n");
21:    printf("Year: %d\n", model.year);
22:    printf("Cost: $%6.2f\n", model.cost);
23:    printf("CPU type: %s\n", model.cpu_type);
24:    printf("CPU speed: %d MHz\n", model.cpu_speed);
25:
26:    return 0;
27: }
28: /* function definition */
29: SC DataReceive(SC s)
30: {
31:    printf("The type of the CPU inside your computer?\n");
32:       gets(s.cpu_type);
33:    printf("The speed(MHz) of the CPU?\n");
34:       scanf("%d", &s.cpu_speed);
35:    printf("The year your computer was made?\n");
36:       scanf("%d", &s.year);
37:    printf("How much you paid for the computer?\n");
38:       scanf("%f", &s.cost);
39:    return s;
40: }


After I run the executable, 19L03.exe, and enter my answers to the questions, I get the following output, which is the same as the output from the executable program of List-
ing 19.1:

OUTPUT

C:\app>19L03
The type of the CPU inside your computer?
Pentium
The speed(MHz) of the CPU?
100
The year your computer was made?
1996
How much you paid for the computer?
1234.56
Here are what you entered:
Year: 1996
Cost: $1234.56
CPU type: Pentium
CPU speed: 100 MHz
C:\app>

ANALYSIS

The purpose of the program in Listing 19.3 is to show you how to pass a structure to a function. The structure in Listing 19.3, with the tag name of computer, is declared in lines 4_9.

Note that in line 11 the typedef keyword is used to define a synonym, SC, for structure computer. Then SC is used in the sequential declarations.

The DataReceive() function is declared in line 13, with the structure of computer as its argument (that is, the synonym SC and the variable name s), so that a copy of the structure can be passed to the function.

In addition, the DataReceive() function returns the copy of the structure back to the caller after the content of the structure is updated. To do this, SC is prefixed to the function in line 13 to indicate the data type of the value returned by the function.

The statement in line 17 defines the structure model with SC. The DataReceive() function is passed with the name of the model structure in line 19, and then the value returned by the function is assigned back to model as well. Note that if the DataReceive() function return value is not assigned to model, the changes made to s in the function will not be evident in model.

The definition of the DataReceive() function is shown in lines 29_40, from which you can see that the new data values entered by the user are saved into the corresponding members of the structure that is passed to the function. At the end of the function, the copy of the updated structure is returned in line 39.

Then, back to the main() function of the program, lines 21_24 print out the updated contents held by the members of the structure. Because the program in Listing 19.3 is basically the same as the one in Listing 19.1, I see the same output on my screen after running the executable file, 19L03.exe.
Pointing to Structures

As you can pass a function with a pointer that refers to an array, you can also pass a function with a pointer that points to a structure.

However, unlike passing a structure to a function, which sends an entire copy of the structure to the function, passing a pointer of a structure to a function is simply passing the address that associates the structure to the function. The function can then use the address to access the structure members without duplicating the structure. Therefore, it's more efficient to pass a pointer of a structure, rather than the structure itself, to a function.

Accordingly, the program in Listing 19.3 can be rewritten to pass the DataReceive() function with a pointer that points to the structure. The rewritten program is shown in Listing 19.4.

TYPE
Listing 19.4. Passing a function with a pointer that points to a structure.


1:  /* 19L04.c Pointing to a structure */
2:  #include <stdio.h>
3:
4: struct computer {
5:    float cost;
6:    int year;
7:    int cpu_speed;
8:    char cpu_type[16];
9: };
10:
11: typedef struct computer SC;
12:
13: void DataReceive(SC *ptr_s);
14:
15: main(void)
16: {
17:    SC model;
18:
19:    DataReceive(&model);
20:    printf("Here are what you entered:\n");
21:    printf("Year: %d\n", model.year);
22:    printf("Cost: $%6.2f\n", model.cost);
23:    printf("CPU type: %s\n", model.cpu_type);
24:    printf("CPU speed: %d MHz\n", model.cpu_speed);
25:
26:    return 0;
27: }
28: /* function definition */
29: void DataReceive(SC *ptr_s)
30: {
31:    printf("The type of the CPU inside your computer?\n");
32:       gets((*ptr_s).cpu_type);
33:    printf("The speed(MHz) of the CPU?\n");
34:       scanf("%d", &(*ptr_s).cpu_speed);
35:    printf("The year your computer was made?\n");
36:       scanf("%d", &(*ptr_s).year);
37:    printf("How much you paid for the computer?\n");
38:       scanf("%f", &(*ptr_s).cost);
39: }


Similarly, I obtain output that is the same as the one from the program in Listing 19.3 after I run the executable (19L04.exe) of the program in Listing 19.4:

OUTPUT

C:\app>19L04
The type of the CPU inside your computer?
Pentium
The speed(MHz) of the CPU?
100
The year your computer was made?
1996
How much you paid for the computer?
1234.56
Here are what you entered:
Year: 1996
Cost: $1234.56
CPU type: Pentium
CPU speed: 100 MHz

C:\app>

ANALYSIS

The program in Listing 19.4 is almost identical to the one in Listing 19.3, except that the argument passed to the DataReceive() function is a pointer defined with SC—that is, structure computer. (Refer to lines 11 and 13.) Also, the DataReceive() function does not need to return a copy of the structure because the function can access all members of the original structure, not the copy, via the pointer passed to it. That's why the void keyword is prefixed to the function name in line 13.

The statement in line 17 defines the structure model. And in line 19, the address of the model structure is passed to the DataReceive function by applying the address-of operator (&).

When you look at the definition of the DataReceive() function in lines 29_39, you see that the dereferenced pointer *ptr_s is used to reference the members of the model structure. For instance, to access the char array of cpu_type, (*ptr_s) is used in the (*ptr_s).cpu_type expression to indicate to the compiler that cpu_type is a member in the structure pointed to by the pointer ptr_s. Note that the dereferenced pointer *ptr_s has to be enclosed within the parentheses (( and )).

Another example is the &(*ptr_s).cpu_speed expression in line 34, which leads to the address of the cpu_speed variable that is a member of the structure pointed to by the pointer ptr_s. Again, the dereferenced pointer *ptr_s is surrounded by the parentheses (( and )).

The next subsection shows you how to use the arrow operator (->) to refer to a structure member with a pointer.
Referencing a Structure Member with ->

You can use the arrow operator -> to refer to a structure member with a pointer that points to the structure.

For instance, you can rewrite the (*ptr_s).cpu_type expression in Listing 19.4 with this:

ptr_s -> cpu_type

or you could replace the &(*ptr_s).cpu_speed expression with this:

&(ptr_s->cpu_speed)

Because of its clearness, the -> operator is more frequently used in programs than the dot operator. Exercise 3, later in this hour, gives you a chance to rewrite the entire program in Listing 19.4 using the -> operator.

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.