Sams Teach Yourself C in 24 Hours (42 page)

BOOK: Sams Teach Yourself C in 24 Hours
10.19Mb size Format: txt, pdf, ePub

The purpose of the program in Listing 15.2 is to show you how .to declare and
ANALYSIS
call a function without passing arguments. The program prints out the current date and time on your computer by calling the function GetDateTime(), declared in line 5. Because no argument needs to be passed to the function, the void data type is used as the prototype in the declaration of GetDateTime().

Additionally, another void keyword is used in front of the name of the GetDateTime() function to indicate that this function does return any value either (see line 5.) The statements in lines 9 and 11 print out messages both before and after the GetDateTime() function is called from within the main() function.

In line 10, the function is called by the statement GetDateTime();. Note that no argument should be passed to this function because the function prototype is void.

The definition of GetDateTime() is in lines 15–23; it obtains the calendar time and converts it into a character string by calling several C library functions: time(), localtime(), and asctime(). Then, the character string containing the current date and time is printed out on the screen by the printf() function with the format specifier %s. As you can see, the output on my screen shows that at the moment the executable file 15L02.exe is being executed, the date and time are

Sat Apr 05 11:50:10 1997

time(), localtime(), and asctime() are date and time functions provided by the C language. These functions are discussed in the following subsection. You might notice that the header file time.h is included at the beginning of the program in Listing 15.2 before these time functions can be used.

Using
time()
,
localtime()
, and
asctime()

There is a group of C functions known as
date and time functions
. The declarations of all date and time functions are included in the header file time.h. These functions can give three types of date and time:

• Calendar time

• Local time

• Daylight savings time

20 067231861x CH15 4.10.2000 11:03 AM Page 250

250

Hour 15

Here
calendar time
gives the current date and time based on the Gregorian calendar.

Local time
represents the calendar time in a specific time zone.
Daylight savings time
is the local time under the daylight savings rule.

In this section, three date and time functions—time(), localtime(), and asctime()—

are briefly introduced.

The time() function returns the calendar time.

The syntax for the time() function is

AX

#include

time_t time(time_t *timer);

YNTS
Here time_t is the arithmetic type that is used to represent time. timer is a pointer vari-

,

able pointing to a memory storage that can hold the calendar time returned by this func-

,

tion. The time() function returns -1 if the calendar time is not available on the computer.

The localtime() function returns the local time converted from the calendar time.

The syntax for the localtime() function is

AX

#include

struct tm *localtime(const time_t *timer);

YNTS
Here tm is a structure that contains the components of the calendar time. struct is the

,

keyword for structure, which is another data type in C. (The concept of structures is

,

introduced in Hour 19, “Understanding Structures.”) timer is a pointer variable pointing to a memory storage that holds the calendar time returned by the time() function.

To convert the date and time represented by the structure tm, you can call the asctime() function..

The syntax for the asctime() function is

AX

#include

char *asctime(const struct tm *timeptr);

YNTS
Here timeptr is a pointer referencing the structure tm returned by date and time func-

,

tions like localtime(). The asctime() function converts the date and time represented by tm into a character string..

As shown in Listing 15.2, the statement in line 17 declares a time_t variable called now.

Line 20 stores the calendar time in the memory location referenced by the now variable.

Note that the argument passed to the time() function should be the left value of a variable; therefore, the address-of operator (&) is used prior to now. Then, the expression in 20 067231861x CH15 4.10.2000 11:03 AM Page 251

Working with Functions

251

line 22, asctime(localtime(&now)), obtains the local time expression of the calendar time by calling localtime(), and converts the local time into a character string with help
15

from asctime(). The character string representing the date and time is then printed out by the printf() call in lines 21 and 22, which has the following format: Sat Apr 05 11:50:10 1997\n\0

Note that there is a newline character appended right before the null character in the character string that is converted and returned by the asctime() function..

Functions with a Fixed Number of Arguments

You have actually seen several examples that declare and call functions with a fixed number of arguments. For instance, in Listing 15.1, the declaration of the function_1() function in line 4

int function_1(int x, int y);

contains the prototype of two arguments, x and y.

To declare a function with a fixed number of arguments, you need to specify the data type of each argument. Also, it’s recommended to indicate the argument names so that the compiler can check to make sure that the argument types and names declared in a function declaration match with the implementation in the function definition.

Prototyping a Variable Number of Arguments

As you may remember, the syntax of the printf() function is

int printf(const char *format[, argument, ...]);

Here the ellipsis token ... (that is, three dots) represents a variable number of arguments. In other words, besides the first argument that is a character string, the printf() function can take an unspecified number of additional arguments, as many as the compiler allows. The brackets ([ and ]) indicate that the unspecified arguments are optional.

The following is a general form to declare a function with a variable number of arguments:

data_type_specifier function_name(

data_type_specifier argument_name1, ...

);

Note that the first argument name is followed by the ellipsis (...) that represents the rest of unspecified arguments.

20 067231861x CH15 4.10.2000 11:03 AM Page 252

252

Hour 15

For instance, the declaration of the printf() function would look something like this: int printf(const char *format, ...);

Processing Variable Arguments

There are three routines declared in the header file stdarg.h that enable you to write functions that take a variable number of arguments. They are va_start(), va_arg(), and va_end().

Also included in stdarg.h is a data type, va_list, which defines an array type suitable for containing data items needed by va_start(), va_arg(), and va_end().

To initialize a given array that is needed by va_arg() and va_end(), you have to use the va_start() macro routine before any arguments are processed.

The syntax for the va_start() macro is

AX

#include

void va_start(va_list ap, lastfix);

YNTS
Here ap is the name of the array that is about to be initialized by the va_start() macro

,

,

routine. lastfix should be the argument before the ellipsis (...) in the function declaration.

By using the va_arg() macro, you’re able to deal with an expression that has the type and value of the next argument. In other words, the va_arg() macro can be used to get the next argument passed to the function.

The syntax for the va_arg() macro is

AX

#include

type va_arg(va_list ap, data_type);

YNTS
, Here ap is the name of the array that is initialized by the va_start() macro routine.

data_type is the data type of the argument passed to function.

To facilitate a normal return from your function, you have to use the va_end() function in your program after all arguments have been processed.

The syntax for the va_end() function is

AX

#include

void va_end(va_list ap);

YNTS
, Here ap is the name of the array that is initialized by the va_start() macro routine.

Remember to include the header file stdarg.h in your program before you call va_start(), va_arg(), or va_end().

20 067231861x CH15 4.10.2000 11:03 AM Page 253

Working with Functions

253

Listing 5.3 demonstrates how to use va_start(), va_arg(), and va_end() in a function that takes a variable number of arguments.

15

TYPE

LISTING 15.3

Processing Variable Arguments

1: /* 15L03.c: Processing variable arguments */

2: #include

3: #include

4:

5: double AddDouble(int x, ...);

6:

7: main ()

8: {

9: double d1 = 1.5;

10: double d2 = 2.5;

11: double d3 = 3.5;

12: double d4 = 4.5;

13:

14: printf(“Given an argument: %2.1f\n”, d1);

15: printf(“The result returned by AddDouble() is: %2.1f\n\n”,

16: AddDouble(1, d1));

17: printf(“Given arguments: %2.1f and %2.1f\n”, d1, d2);

18: printf(“The result returned by AddDouble() is: %2.1f\n\n”,

19: AddDouble(2, d1, d2));

20: printf(“Given arguments: %2.1f, %2.1f and %2.1f\n”, d1, d2, d3); 21: printf(“The result returned by AddDouble() is: %2.1f\n\n”,

22: AddDouble(3, d1, d2, d3));

23: printf(“Given arguments: %2.1f, %2.1f, %2.1f, and %2.1f\n”,

24: d1, d2, d3, d4);

25: printf(“The result returned by AddDouble() is: %2.1f\n”,

26: AddDouble(4, d1, d2, d3, d4));

27: return 0;

28: }

29: /* definition of AddDouble() */

30: double AddDouble(int x, ...)

31: {

32: va_list arglist;

33: int i;

34: double result = 0.0;

35:

36: printf(“The number of arguments is: %d\n”, x);

37: va_start (arglist, x);

38: for (i=0; i

39: result += va_arg(arglist, double);

40: va_end (arglist);

41: return result;

42: }

20 067231861x CH15 4.10.2000 11:03 AM Page 254

254

Hour 15

The following output is displayed on the screen after the executable file, 15L03.exe, is run:

Given an argument: 1.5

OUTPUT
The number of arguments is: 1

The result returned by AddDouble() is: 1.5

Given arguments: 1.5 and 2.5

The number of arguments is: 2

The result returned by AddDouble() is: 4.0

Given arguments: 1.5, 2.5, and 3.5

The number of arguments is: 3

The result returned by AddDouble() is: 7.5

Given arguments: 1.5, 2.5, 3.5, and 4.5

The number of arguments is: 4

The result returned by AddDouble() is: 12.0

The program in Listing 15.3 contains a function that can take a variable number
ANALYSIS
of double arguments, perform the operation of addition on these arguments, and then return the result to the main() function.

The declaration in line 5 indicates to the compiler that the AddDouble() function takes a variable number of arguments. The first argument to AddDouble() is an integer variable that holds the number of the rest of the arguments passed to the function each time AddDouble() is called. In other words, the first argument indicates the number of remaining arguments to be processed.

The definition of AddDouble() is given in lines 29–41, in which a va_list array, arglist, is declared in line 31. As mentioned, the va_start() macro has to be called before the arguments are processed. Thus, line 36 invokes va_start() to initialize the array arglist. The for loop in lines 37 and 38 fetches the next double argument saved in the array arglist by calling va_arg(). Then, each argument is added into a local double variable called result.

The va_end() function is called in line 39 after all arguments saved in arglist have been fetched and processed. Then, the value of result is returned back to the caller of the AddDouble() function, which is the main() function in this case.

The va_end() function must be called in a C program to end variable argument processing. Otherwise, the behavior of the program is undefined.

As you can see, within the main() function, AddDouble() is called four times, with a different number of arguments each time. These arguments passed to AddDouble() are displayed by the printf() calls in lines 14, 17, 20, and 23. Also, the four different results returned by AddDouble() are printed out on the screen.

20 067231861x CH15 4.10.2000 11:03 AM Page 255

Working with Functions

255

Learning Structured Programming

15

Now you’ve learned the basics of function declaration and definition. Before we go to the next hour, let’s talk a little bit about
structured programming
in program design.

Structured programming is one of the best programming methodologies. Basically, there are two types of structured programming: top-down programming and bottom-up programming.

When you start to write a program to solve a problem, one way to do it is to work on the smallest pieces of the problem. First, you define and write functions for each piece. After each function is written and tested, you begin to put them together to build a program that can solve the problem. This approach is normally called
bottom-up programming
.

Other books

Rivers: A Novel by Michael Farris Smith
Dead Woods by Poets, Maria C
Queen of His Heart by Marie Medina
The Matchmaker by Marita Conlon-McKenna
Letters to Nowhere by Julie Cross
The Hysterics by Kristen Hope Mazzola
Rock Bottom by Michael Shilling