PAGEFLOP
FORWARD
SELECTOR
SELAGAIN
WRONGSEL
YOUR SELECTION IS NOT IN THE 0 - #SELIMIT RANGE Please try again
AANVANG
Copyright CourseWare Technologies Inc., 1985-88
Lesson - 12
ADVANCED C CONCEPTS
P1
Advanced C Concepts|Topics to Learn|12-0|10,48
# Topic
--- -------
1 - Using Command Line Arguments
2 - Command Line Arguments Review
3 - Performing Error Handling
4 - The Union Concept
5 - Performing Bit Field Manipulation
6 - Using Pointers to Functions
7 - Second Review
0 - Return to the Main Menu
P2
Advanced C Concepts|Using Command Line Arguments|12-1.1|16,54
Command line arguments are the means to pass
the arguments to the main() program, similar to the
arguments passed to a function
When a program or a command is invoked, the first
word in the command line is the executable UNIX
program; the rest of the words are the actual
arguments to that program. For example,
cat file_1 file_2 file_3
will invoke the program cat and pass to it the three
command line arguments:
file_1, file_2, and file_3.
P3
Advanced C Concepts|Using Command Line Arguments|12-1.2|10,54
The command line arguments are represented in
the main() function with two variables:
argc the number of arguments the program was
invoked with. (The program name is the first
argument.)
argv the pointer to the array of character
strings that contains the arguments.
P4
Advanced C Concepts|Using Command Line Arguments|12-1.3|10,54
In the command line:
cat file_1 file_2 file_3
argc = 4, and argv[0] is the name by which the program
was invoked. They are declared as:
int argc;
char *argv[];
P5
Advanced C Concepts|Using Command Line Arguments|12-1.4| 10 , 58
The following example demonstrates command line
arguments in a C program. The task of the program is
to concatenate the specified files. For example, if
the program name is concat, the command line would
look like this:
concat file_1 file_2 file_3 > destin.dat
The three files would be written one after another into
the destination file destin.dat.
P6
Advanced C Concepts|Using Command Line Arguments|12-1.5| 7 , 43
On the other hand, if the command were:
concat > destin.dat
then the standard input would be written to
destin.dat
P7
Advanced C Concepts|Using Command Line Arguments|12-1.6|17,54
The function that does file copying is filecopy().
For the first command line, the array of arguments
may be represented as follows:
----------
0 | concat |
----------
1 | file_1 |
----------
2 | file_2 |
----------
3 | file_3 |
----------
Since argv is initially pointing to concat the
statement *++argv will move the pointer to the
next element, i.e., file_1, and so on.
P8
Advanced C Concepts|Using Command Line Arguments|12-1.7|12,54
/* Command Line Arguments, An Example */
/* The task is to concatenate files specified on the
command line and store the result in the destination
file and to display the result on the standard output
for verification. */
#include <stdio.h>
main(argc, argv) /* merge files */
int argc; /* number of C_L_A */
char *argv[];
P9
Advanced C Concepts|Using Command Line Arguments|12-1.8|18,58
{ /* Command Line Arguments, An Example */
FILE *fps, *fpd, *fopen();
if ((fpd = fopen("destin.dat","w")) != NULL)
if (argc == 1) /* no args: copy standard input */
filecopy(stdin,fpd);
else {
while (--argc > 0)
if (( fps = fopen(*++argv, "r")) == NULL) {
printf("cat: can't open %s\n", *argv);
break;
}
else {
filecopy(fps, fpd);
fclose(fps);
}
fclose(fpd);
} }
P10
Advanced C Concepts|Using Command Line Arguments|12-1.9|14,53
/* Command Line Arguments, An Example */
filecopy(fps,fpd) /* append the source file to
the destination file and
verify the result */
FILE *fps, *fpd;
{
int c;
while ((c = getc(fps)) != EOF) {
putc(c, fpd);
putchar(c);
}
}
P11
Advanced C Concepts|Performing Error Handling|12-3.1|17,54
Every active C program has three file pointers
assigned to it (that is, it has three files automatically
opened):
stdin the standard input file pointer
stdout the standard output file pointer
stderr the standard error file pointer
If a program encounters some error conditions
it will normally write the diagnostic messages to the
standard error, stderr.
If possible, the output written to the standard
error will appear on the user's terminal, the standard
output.
P12
Advanced C Concepts|Performing Error Handling|12-3.2|13,54
There are system calls associated with
diagnostic error handling:
exit() terminates the program execution when it is
called. The argument to exit() signals a
status condition for program exit. A status
condition 0 signifies normal exit. The function
itself calls fclose() for each open output
file to flush out any buffered output, then it
calls _exit().
_exit() causes immediate termination without buffer
flushing.
P13
Advanced C Concepts|Performing Error Handling|12-3.3|11,54
The following example, identical in mechanics to an
earlier one, shows how the diagnostic conditions are
typically handled from C programs running under the
UNIX operating system. A generic file analog of
printf(), called fprintf(), is used to write the
diagnostic message to the standard error file stderr,
which, if possible, is also written to the standard
output. Note also the use of the system call exit()
which will terminate the program. The argument to
exit() is the value returned by the special shell
variable $?. An argument other than 0 is an error exit.
P14
Advanced C Concepts|Performing Error Handling|12-3.4|9,48
/* Error Handling, An Example */
Using stderr() and exit() with
the program in Example 12.1
#include <stdio.h>
main(argc, argv) /* merge files */
int argc; /* number of C_L_A */
char *argv[];
P15
Advanced C Concepts|Performing Error Handling|12-3.5|17,59
/* Error Handling Example (continued) */
{
FILE *fps, *fpd, *fopen();
if ((fpd = fopen("destin.dat","w")) == NULL) {
fprintf(stderr, "cat: can't create \"destin.dat\" file");
exit(1);
}
else {
if (argc == 1) /* no arguments, copy standard input */
filecopy(stdin,fpd);
else {
while (--argc > 0)
if (( fps = fopen(*++argv, "r")) == NULL) {
fprintf(stderr,"cat: can't open %s\n", *argv);
exit(1); /* diagnostic exit */
}
P16
Advanced C Concepts|Performing Error Handling|12-3.6|11,46
/* Error Handling Example (continued) */
else {
filecopy(fps, fpd);
fclose(fps);
}
fclose(fpd);
}
exit(0); /* correct exit */
}
}
P17
Advanced C Concepts|Performing Error Handling|12-3.7|13,58
/* Error Handling Example (continued) */
filecopy(fps, fpd) /* append the source file to the
destination file and verify the result */
FILE *fps, *fpd;
{
int c;
while ((c = getc(fps)) != EOF) {
putc(c, fpd);
putchar(c);
}
}
P18
Advanced C Concepts|The Union Concept|12-4.1|9,50
A union is a heterogeneous data structure
which may hold elements of different types, one
at a time.
It is the user's responsibility to keep track
of which variable the union currently holds.
Unions may not be initialized!
P19
Advanced C Concepts|The Union Concept|12-4.2|14,54
The syntax for union declaration, union variable
referencing, and union representation, is almost
identical to that of structures, e.g.:
union union_tag {
char typ_char;
int typ_int;
float typ_float;
double typ_double;
};
The size of a union is the size of its largest
element!
P20
Advanced C Concepts|The Unions Concept|12-4.3|16,58
The following example illustrates unions in a C program.
The program mechanics are rather complicated since we're
dealing with structures, pointers to structures, and the
unions. Note that the structure of type struct uni_struct
is composed of a union variable uni_var and a pointer to
the variable of type struct uni_struct (the same as the
structure)--a classic case of self-referential structures.
When the function add_entry() is called, it receives the
union variable entry (the new entry) and a pointer to
the current structure in the list, current_entry. Note
also how the space for the new variable is allocated and
the cast used to obtain the proper type. Finally, the new
structure is filled, added to the list, and the current
pointer is updated and returned to the calling function.
Note also that the function type and the type of the
ptr are identical.
P21
Advanced C Concepts|The Union Concept|12-4.4|13,54
add_entry() Program Example
The function add_entry() adds a new structure entry
to a linked list of various types of variables. The
entries/values are passed to the function in the form
of a union.
union union_tag {
char typ_char;
int typ_int;
float typ_float;
double typ_double;
};
P22
Advanced C Concepts|The Union Concept|12-4.5|11,54
add_entry() Program Example (continued)
struct uni_struct {
union union_tag uni_var;
struct uni_struct *next_union;
};
struct uni_struct *
add_entry( entry, current_entry)
union union_tag *entry; /* new value */
struct uni_struct *current_entry;
P23
Advanced C Concepts|The Union Concept|12-4.6|13,54
Using Unions, An Example
{
char *malloc();
struct uni_struct *ptr; /* pointer to the
next list element */
if ((ptr = (struct uni_struct *) malloc (
sizeof(struct uni_struct))) != NULL) {
ptr -> next_union = current_entry;
ptr -> uni_var = *entry; /* copy value */
}
return ptr;
}
P24
Advanced C Concepts|The Union Concept|12-4.7|9,51
--------------------------------------------------
Pictorial Representation of the structure uni_struct
from the previous screens.
----------- ----------- -----------
<----| | |<----| | |<----| | |
| | | | | | | | |
----------- ----------- -----------
P25
Advanced C Concepts|Performing Bit Field Manipulations|12-5.1|12,54
A field is a set of adjacent bits within
a single int.
Data representation with bit fields is useful
when one is faced with limited storage space, and
when one bitwise operation may give a result regarding
several objects.
The syntax for bit field data structure
declaration is similar to that of a C structure.
P26
Advanced C Concepts|Performing Bit Field Manipulations|12-5.2|17,50
BIT FIELD USAGE EXAMPLE
Using bit fields to represent an individual with
more than one profession
struct {
unsigned a_pro Programmer : 1;
unsigned an_engineer : 1;
unsigned a_gardener : 1;
unsigned a_technician : 1;
unsigned a_pilot : 1;
unsigned a_driver : 1;
unsigned : 1; /* for padding only */
unsigned an_accountant : 1;
} user;
Note: The number following the colon represents
the field width in bits.
P27
Advanced C Concepts|Performing Bit Field Manipulations|12-5.3|18,54
To say that the user is an accountant, a
programmer, and a driver, the operation is:
user.a_programmer = user.an_accountant =
user.a_driver = 1;
To say that the user is neither a technician
nor an accountant, the operation is:
user.a_technician = user.an_accountant = 0;
To test if the user is neither a pilot nor
a gardener nor a technician, the operation is:
if (!(user.a_pilot || user.a_gardener ||
user.a_technician)) {
P28
Advanced C Concepts|Performing Bit Field Manipulations|12-5.4|4,43
-- OR --
if (!user.a_pilot && !user.a_gardener &&
!user.a_technician) {
:
P29
Advanced C Concepts|Using Pointers to Functions|12-6.1|14,56
A function name may be passed from one function
to another in the argument list.
As with arrays, the function name in the argument
list signifies the pointer/address to/of the function.
If the function a passes to the function b several
arguments, including pointers to functions, the function
b would not need to know the actual name of the function
whose address has been passed to it. Function b may use
the address/pointer to the function variable in the calling
statement along with its arguments.
P30
Advanced C Concepts|Using Pointers to Functions|12-6.2|10,54
If the function whose address is known to the
function b, returns a variable of type float, and if
b calls this function variable as func_addr then
inside b this variable may be declared as:
float (*func_addr)();
The actual calling statement will have the form:
(*func_addr)(arg1, arg2, .., argN);
P31
Advanced C Concepts|Using Pointers to Functions|12-6.3|11,54
NOTE: The declaration:
float *func_addr();
says that the function func_addr returns a pointer
to the variable of type float. Care must be taken
not to confuse this with:
float (*func_addr)();
as used above.