[an error occurred while processing this directive]
HP OpenVMS SystemsC Programming Language |
Compaq C
|
Previous | Contents | Index |
To help you detect run-time errors, the <errno.h> header file defines the following two symbolic values that are returned by many (but not all) of the mathematical functions:
When using the math functions, you can check the external variable errno for either or both of these values and take the appropriate action if an error occurs.
The following program example checks the variable errno for the value EDOM, which indicates that a negative number was specified as input to the function sqrt :
#include <errno.h> #include <math.h> #include <stdio.h> main() { double input, square_root; printf("Enter a number: "); scanf("%le", &input); errno = 0; square_root = sqrt(input); if (errno == EDOM) perror("Input was negative"); else printf("Square root of %e = %e\n", input, square_root); } |
If you did not check errno for this symbolic value, the sqrt function returns 0 when a negative number is entered. For more information about the <errno.h> header file, see Chapter 4.
The <fp.h> header file implements some of the features defined by the Numerical C Extensions Group of the ANSI X3J11 committee. You might find this useful for applications that make extensive use of floating-point functions.
Some of the double-precision functions listed in this chapter return the value ±HUGE_VAL (defined in either <math.h> or <fp.h> ) if the result is out of range. The float version of those functions return the value HUGE_VALF (defined only in <fp.h> ) for the same conditions. The long double version returns the value HUGE_VALL (also defined in <fp.h> ).
For programs compiled to enable IEEE infinity and NaN values, the values HUGE_VAL, HUGE_VALF, and HUGE_VALL are expressions, not compile-time constants. Initializations such as the following cause a compile-time error:
$ CREATE IEEE_INFINITY.C #include <fp.h> double my_huge_val = HUGE_VAL ^Z $ CC /FLOAT=IEEE/IEEE=DENORM IEEE_INFINITY double my_huge_val = HUGE_VAL; .....................^ %CC-E-NEEDCONSTEXPR, In the initializer for my_huge_val, "decc$gt_dbl_infinity" is not constant, but occurs in a context that requires a constant expression. at line number 3 in file WORK1$:[RTL]IEEE_INFINITY.C;1 $ |
When using both <math.h> and <fp.h> , be aware that <math.h> defines a function isnan and <fp.h> defines a macro by the same name. Whichever header is included first in the application will resolve a reference to isnan .
Example 7-1 shows how the tan , sin , and cos functions operate.
Example 7-1 Calculating and Verifying a Tangent Value |
---|
/* CHAP_7_MATH_EXAMPLE.C */ /* This example uses two functions --- mytan and main --- */ /* to calculate the tangent value of a number, and to check */ /* the calculation using the sin and cos functions. */ #include <math.h> #include <stdio.h> /* This function calculates the tangent using the sin and */ /* cos functions. */ double mytan(x) double x; { double y, y1, y2; y1 = sin(x); y2 = cos(x); if (y2 == 0) y = 0; else y = y1 / y2; return y; } main() { double x; /* Print values: compare */ for (x = 0.0; x < 1.5; x += 0.1) printf("tan of %4.1f = %6.2f\t%6.2f\n", x, mytan(x), tan(x)); } |
Example 7-1 produces the following output:
$ RUN EXAMPLE tan of 0.0 = 0.00 0.00 tan of 0.1 = 0.10 0.10 tan of 0.2 = 0.20 0.20 tan of 0.3 = 0.31 0.31 tan of 0.4 = 0.42 0.42 tan of 0.5 = 0.55 0.55 tan of 0.6 = 0.68 0.68 tan of 0.7 = 0.84 0.84 tan of 0.8 = 1.03 1.03 tan of 0.9 = 1.26 1.26 tan of 1.0 = 1.56 1.56 tan of 1.1 = 1.96 1.96 tan of 1.2 = 2.57 2.57 tan of 1.3 = 3.60 3.60 tan of 1.4 = 5.80 5.80 $ |
Table 8-1 lists and describes all the memory allocation functions found in the Compaq C Run-Time Library (RTL). For a more detailed description of each function, see the Reference Section.
All Compaq C RTL functions requiring additional storage from the heap get that storage using the Compaq C RTL memory allocation functions malloc , calloc , realloc , free , and cfree . Memory allocated by these functions is quadword-aligned.
The ANSI C standard does not include cfree . For this reason, it is preferable to free memory using the functionally equivalent free function.
The brk and sbrk functions assume that memory can be allocated contiguously from the top of your address space. However, the malloc function and RMS may allocate space from this same address space. You should not use the brk and sbrk functions in conjunction with RMS and Compaq C RTL routines that use malloc .
Previous versions of the VAX C RTL documentation indicated that the memory allocation routines used the OpenVMS RTL functions LIB$GET_VM and LIB$FREE_VM to acquire and return dynamic memory. This is no longer the case; interaction between these routines and the Compaq C RTL memory allocation routines is no longer problematic (although LIB$SHOW_VM can no longer be used to track Compaq C RTL malloc and free usage).
The Compaq C RTL memory allocation functions calloc , malloc , realloc , and free are based on the LIB$ routines LIB$VM_CALLOC, LIB$VM_MALLOC, LIB$VM_REALLOC and LIB$VM_FREE, respectively.
The routines VAXC$CALLOC_OPT , VAXC$CFREE_OPT , VAXC$FREE_OPT , VAXC$MALLOC_OPT , and VAXC$REALLOC_OPT are now obsolete and should not be used in new development. However, versions of these routines that are equivalent to the standard C memory allocation routines are provided for backward compatibility.
Example 8-1 shows the use of the malloc , calloc , and free functions.
Example 8-1 Allocating and Deallocating Memory for Structures |
---|
/* CHAP_8_MEM_MANAGEMENT.C */ /* This example takes lines of input from the terminal until */ /* it encounters a Ctrl/Z, places the strings into an */ /* allocated buffer, copies the strings to memory allocated for */ /* structures, prints the lines back to the screen, and then */ /* deallocates all the memory used for the structures. */ #include <stdlib.h> #include <stdio.h> #define MAX_LINE_LENGTH 80 struct line_rec { /* Declare the structure. */ struct line_rec *next; /* Pointer to next line. */ char *data; /* A line from terminal. */ }; int main(void) { char *buffer; /* Define pointers to */ /* structure (input lines). */ struct line_rec *first_line = NULL, *next_line, *last_line = NULL; /* Buffer points to memory. */ buffer = malloc(MAX_LINE_LENGTH); if (buffer == NULL) { /* If error ... */ perror("malloc"); exit(EXIT_FAILURE); } while (gets(buffer) != NULL) { /* While not Ctrl/Z ... */ /* Allocate for input line. */ next_line = calloc(1, sizeof (struct line_rec)); if (next_line == NULL) { perror("calloc"); exit(EXIT_FAILURE); } /* Put line in data area. */ next_line->data = buffer; if (last_line == NULL) /* Reset pointers. */ first_line = next_line; else last_line->next = next_line; last_line = next_line; /* Allocate space for the */ /* next input line. */ buffer = malloc(MAX_LINE_LENGTH); if (buffer == NULL) { perror("malloc"); exit(EXIT_FAILURE); } } free(buffer); /* Last buffer always unused. */ next_line = first_line; /* Pointer to beginning. */ while (next_line != NULL) { puts(next_line->data); /* Write line to screen. */ free(next_line->data); /* Deallocate a line. */ last_line = next_line; next_line = next_line->next; free(last_line); } exit(EXIT_SUCCESS); } |
The sample input and output for Example 8-1 are as follows:
$ RUN EXAMPLE line one line two [Ctrl/Z] EXIT line one line two $ |
The C programming language is a good choice if you wish to write operating systems. For example, much of the UNIX operating system is written in C. When writing system programs, it is sometimes necessary to retrieve or modify the environment in which the program is running. This chapter describes the Compaq C Run-Time Library (RTL) functions that accomplish this and other system tasks.
Table 9-1 lists and describes all the system functions found in the Compaq C RTL. For a more detailed description of each function, see the Reference Section.
Example 9-1 shows how the cuserid function is used.
Example 9-1 Accessing the User Name |
---|
/* CHAP_9_GET_USER.C */ /* Using cuserid, this program returns the user name. */ #include <stdio.h> main() { static char string[L_cuserid]; cuserid(string); printf("Initiating user: %s\n", string); } |
If a user named TOLLIVER runs the program, the following is displayed on stdout:
$ RUN EXAMPLE1 Initiating user: TOLLIVER |
Example 9-2 shows how the getenv function is used.
Example 9-2 Accessing Terminal Information |
---|
/* CHAP_9_GETTERM.C */ /* Using getenv, this program returns the terminal. */ #include <stdio.h> #include <stdlib.h> main() { printf("Terminal type: %s\n", getenv("TERM")); } |
Running Example 9-2 on a Compaq VT100 terminal in 132-column mode displays the following:
$ RUN EXAMPLE3 Terminal type: vt100-132 |
Example 9-3 shows how to use getenv to find the user's default login directory and how to use chdir to change to that directory.
Example 9-3 Manipulating the Default Directory |
---|
/* CHAP_9_CHANGE_DIR.C */ /* This program performs the equivalent of the DCL command */ /* SET DEFAULT SYS$LOGIN. However, once the program exits, the */ /* directory is reset to the directory from which the program */ /* was run. */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> main() { char *dir; int i; dir = getenv("HOME"); if ((i = chdir(dir)) != 0) { perror("Cannot set directory"); exit(0); } printf("Current directory: %s\n", dir); } |
Running Example 9-3 displays the following:
$ RUN EXAMPLE4 Current directory: dba0:[tolliver] $ |
Example 9-4 shows how to use the time , localtime , and strftime functions to print the correct date and time at the terminal.
Example 9-4 Printing the Date and Time |
---|
/* CHAP_9_DATE_TIME.C */ /* The time function returns the time in seconds; the localtime */ /* function converts the time to hours, minutes, and so on; */ /* the strftime function uses these values to obtain a string */ /* in the desired format. */ #include <time.h> #include <stdio.h> #define MAX_STRING 80 main() { struct tm *time_structure; time_t time_val; char output_str[MAX_STRING]; time(&time_val); time_structure = localtime(&time_val); /* Print the date */ strftime(output_str, MAX_STRING, "Today is %A, %B %d, %Y", time_structure); printf("%s\n", output_str); /* Print the time using a 12-hour clock format. */ strftime(output_str, MAX_STRING, "The time is %I:%M %p", time_structure); printf("%s\n", output_str); } |
Running Example 9-4 displays the following:
$ RUN EXAMPLE5 Today is Thursday, May 20, 1993 The time is 10:18 AM $ |
Previous | Next | Contents | Index |