With a few exceptions, C++ contains ANSI C as a subset. Bjarne Stroustrup, who developed
C++ in the early 1980s, wrote, "The name signifies the evolutionary nature of the changes from C. '++' is the C
increment operator....The language is not called D, because it is an extension of C that does not attempt to
remedy problems by removing features." C is a procedural language with its emphasis on function calls, while C++
is a hybrid of procedural and object-oriented languages. In this module, we consider syntax that will enable a
C++ programmer to code in C.
Comments
Many versions of C now allow a double slash (//) to indicate that the remainder
of the line is a comment, such as
// declarations
int i; // index
This new syntax allows us to comment out a line easily.
However, in ANSI C a comment begins with the two characters /* and ends with
*/, with no space between the two characters, and a comment cannot contain */ as part of its text.
Since there is no nesting of comments in C, there is a danger of a comment that already exists in a segment will
cause a premature end to a comment. For example, consider the following C segment.
pressure = ComputePressure(volume); /*
calculate pressure */
PrintPressure(volume, pressure);
If during debugging, we attempt to comment out this segment and do not notice the
internal comment, an error arises.
/*
pressure = ComputePressure(volume); /* calculate pressure */
PrintPressure(volume, pressure);
*/
The first */ ends the comment, and the second produces an error. To avoid the problem in
C of "commenting out" a segment containing comments, we use preprocessor directives, such as
#if 0
pressure = ComputePressure(volume); /* calculate pressure */
PrintPressure(volume, pressure);
#endif
| Quick
Review Question |
Quick Review Question 1
| a. Give the character(s) to begin an ANSI C comment. |
|
|
| b. Give the character(s) to end an ANSI C comment. |
|
|
| c. Typing at most one blank, give the preprocessor directive to begin a segment that the compiler
should ignore. |
|
|
| d. Give the preprocessor directive to end a segment that the compiler
should ignore. |
|
|
Call by Reference
Functions are an essential ingredient of structured programming. In the strictest
sense, C offers only one method of passing a value from an argument (in the calling routine) to a parameter (in
the called function), call by value or pass by value. When a function is called, a memory location
is created for the parameter, and the value of the argument is copied to that location. Then, all communication
is severed between the argument and parameter. A change in the value of the parameter does not effect the value
of the corresponding argument.
| Definition |
Pass by value is a method of passing information to
a function whereby the parameter receives a copy of the value of the argument. |
Many times the function must communicate values back to the calling routine. The function
can return one value. If there are more than one, then the function must use pointers as parameters. The value of
the pointer, which is the address it contains, cannot change; but the value of the memory location to which it
points can. For example, suppose we need to call a routine to swap the contents of two int variables. The
swap routine in ANSI C must use pointers to those variables. Within the routine, we dereference the pointers to
access the contents of those variables.
/*
* ANSI C function to swap values
* Pre: x_ptr and y_ptr point to integers.
* Post: The values of *x_ptr and *y_ptr have been swapped.
*/
void swap(int *x_ptr, int *y_ptr)
{
int temp;
temp = *x_ptr;
*x_ptr = *y_ptr;
*y_ptr = temp;
}
The calling function passes to swap the addresses of the variables whose values
we wish to switch. After execution of the following segment, a has the value 5, and b is 3.
int a = 3,
b = 5;
.
.
.
/* call ANSI C swap to exchange values of a and b */
swap(&a, &b);
Figure 1 shows the action of C's swap with a calling function of main.
Figure 1. Action of swap in ANSI C with a calling function of main
C does not have the call by reference or pass by reference mechanism for
binding arguments and parameters that C++ has. With this method, the computer does not create a new memory
location for a parameter, but allows it to share the memory location of the corresponding argument. To indicate
that the parameter should be by reference, C++ uses an ampersand immediately after the type, such as with the
following prototype:
void swap(int&, int&);
Thus, the function definition for swap is as follows:
//
// C++ function to swap values
// Pre: x and y are integer variables.
// Post: The values of x and y have been swapped.
//
void swap(int& x, int& y)
{
int temp;
temp = x;
x = y;
y = temp;
}
To invoke this function in C++, we only need to use integer arguments, such as
int a = 3,
b = 5;
.
.
.
// call C++ swap to exchange values of a and b
swap(a, b);
| Quick
Review Question |
Quick Review Question 2 In the
answers, type exactly one blank before and no blanks after any asterisk.
a. Complete the prototype of a C function GetRate to communicate the
value of a float value through the use of a pointer parameter rate_ptr.
void GetRate(___rate_ptr);
|
|
|
b. Complete the call to GetRate to obtain a value for the variable
rate.
GetRate(___);
|
|
|
c. Suppose the definition of GetRate places 5 in the location to which
rate_ptr points, so that rate obtains the value 5. Complete the
assignment in GetRate:
___ = 5;
|
|
|
Standard Streams
Input and output are not part of the formal definition of the language C. Instead, the
standard stream I/O library defines C I/O functions and macros. These routines handle the input and output of
sequences of characters or streams of data.
In C programs, we include the I/O header file stdio.h instead of the C++
header file iostream.h. The C++ input stream cin corresponds to the standard C input stream
stdin. The output stream cout is comparable to stdout; and cerr
is analogous to stderr. Instead of the extraction operator (>>) for input and an insertion
operator (<<) for output, C employs the function scanf for reading and printf
for printing, respectively. For example, in C++, we can have the following segment:
cout << "Enter the
price:";
cin >> price;
cout << "Enter the quantity: ";
cin >> quantity;
cout << "Quantity = " << quantity <<
" Total = " << price * quantity << '\n';
The equivalent segment in C is as follows:
printf("Enter the
price: ");
scanf("%f", &price);
printf("Enter the quantity: ");
scanf("%d", &quantity);
printf("Quantity = %d Total = %f\n", quantity, price
* quantity);
Because we are reading and returning values for price and quantity,
an ampersand appears before each identifier in the calls to scanf. In C, we must specify how to
convert between a value's internal format in memory and an external format with a conversion
specification. The conversion specification %f is for a float or double value, and
%d is for int. Printing a floating point number with the conversion specification of the form
%m.nf (such as %9.2f) displays the number right-justified in a field width of m (such as 9
characters for the field width) with n digits after the decimal point (such as 2 places after the
decimal). The compiler does not detect an incorrect conversion specification or the omission of & when
necessary, but either error leads to unpredictable results.
| Definition |
A conversion specification specifies to what
notation the computer should convert a value for input or output operations. |
| Quick
Review Question |
Quick Review Question 3
In your answers, use exactly one blank after any comma, single blanks between words in quotation
marks, and no other blanks.
| a. Write a C statement to read a value for the integer variable num. |
|
|
b. Write a C statement to print "The number is ", the value for the integer
variable num, a period, and the new line character. Thus, if num has the
value 5, the output appears as follows with subsequent output another line:
The number is 5.
|
|
|
| c. Give the conversion specification to display the number 27.5 so that exactly
3 blanks appear before the number and one digit (5) appears after the decimal point. |
|
|
Strings
A string or character string is any group of characters enclosed in quotation
marks. There is no string type in C. The language, however, treats an array of type char as a string
if the ASCII value 0, the null character '\0', follows its last meaningful character We sometimes
refer to a character string constant, such as "computer", as a string literal. The length of a
string is the number of non-null characters it contains, so the number of locations needed to store a
string is one more than the string's length. The type of a string literal is char *. The declaration
char str[] = "computer";
is an abbreviation for the declaration
char str[] = { 'c', 'o', 'm', 'p', 'u', 't',
'e', 'r', '\0' };
To print the string that the char array str stores, we can use the
%s conversion specification with printf , such as
printf("%s\n", str);
A minus in front of a field width, such as %-9s, causes the string to be
left-justified. To read or print one character, we employ the conversion specification %c, such as
printf("The first character is %c.\n",
str[0]);
With the conversion specification %s , we can read a string into str using a
scanf statement:
scanf("%s", str);
/* No & before string variable str */
Since the array name is a pointer to the first element in the array, we use
str without a subscript; and there is no ampersand (&) before the array name. We can use a maximum
field width with the %s specification in reading a string. For example, for the char array,
str, of 10 elements, we use %9s to read no more than 9 characters and ensure against overflow of the
array.
scanf("%9s", str);
The header file stdio.h declares BUFSIZ to be the size of the
area of memory that holds the input stream. We can declare str to be of that length with
char str[BUFSIZ];
| Quick
Review Question |
Quick Review Question 4
a. Suppose alloy is a 14-element char array. Complete the
statement to read no more than the maximum possible length string into car.
scanf(___, alloy);
|
|
|
| b. Give the conversion specification to display alloy left-justified in
a field of width 20. |
|
|
The detection of erroneous input or validation of data is an important feature of
interactive programming. To validate data, we can read an input datum as a string with the scanf or
gets function. We check the string character by character to make sure it is valid. If input is
satisfactory, then we can use one of the ANSI C standard library function atoi (ASCII to
int) or atof (ASCII to floating point) to return the int or double
equivalent, respectively, of the string argument. For example, if input is the string containing the
user input, which should be an integer, and num is of type int, we perform the conversion with
include <stdlib.h>
...
num = atoi(input);
| Quick
Review Question |
Quick Review Question 5
| a. Give the name of the function that we can use to convert the string "25.6"
held in a character array to the corresponding floating point number. |
|
|
| b. Give the header file that contains the prototype for this function. |
|
|
The ANSI C header file string.h includes the definitions of other
string functions and of the type size_t, which is the type of the value that sizeof
returns. The sizeof operator applied to a type or expression gives the number of storage
bytes needed for the operand. For example, sizeof(float) or sizeof(x) for a
float variable x is the number of byes to store a floating point value in memory.
The ANSI C string library function strlen returns the number of
characters (other than '\0') in the string as a value of type size_t. Thus, after execution of
length = strlen(str);
length holds the length of str. The function strcpy
with prototype in string.h accomplishes string copying. The statement
strcpy(destination, source);
copies the string in source to destination. The function
strcat replaces the first string variable argument with the concatenation or joining of the
two arguments with a call such as
strcat(str1, str2);
The first parameter to the strcat function must be a variable string (an
array) and large enough to hold the concatenated string.
One of the basic operations of word processors is to search for the first
occurrence of a string in the text. In C, the function call strstr(str,
substr) returns a pointer to the first occurrence of the string substr in the string
str. Should substr not be a substring of str, the function returns NULL. A
similar function call, strchr(str, ch), returns a pointer (or NULL) to
the first occurrence of a character, ch, in a string, str. The library function
strcmp (string compare) accomplishes the comparison of strings by returning an integer. If
the first string argument is less than the second, strcmp returns a value less than zero. If the
first argument is equal to the second, the function returns a zero. If the first is greater than the
second, strcmp returns an integer greater than zero. Table 1 presents a summary of these string
functions that we covered.
Table 1 Summary of six string functions
| Function |
Action |
Returns |
| strcat(ToS, FromS) |
Concatenate string FromS onto the end of string ToS |
ToS |
| strchr(s, c) |
Find char c in string s |
Pointer to first occurrence of c in s or NULL |
| strcmp(s1, s2) |
Compare lexically strings s1 and s2 |
If s1 before s2, negative integer; if s1 the same as
s2, 0; if s1 after s2, positive integer |
| strcpy(ToS, FromS) |
Copy string FromS into string ToS |
ToS |
| strlen(s) |
Length of string s |
Length of s |
| strstr(s, find) |
Find string find in string s |
Pointer to first occurrence of substring in s or NULL |
| Quick
Review Question |
Quick Review Question 6
For each of the parts, start with the following declaration-initializations.
char s1[20] = "well",
s2[20] = "come",
*loc;
int comp;
a. Not using quotation marks, give the value of s1,
after execution of the following statement:
s1[strlen(s1) - 1] = '\0';
|
|
|
b. Not using quotation marks, give the value of s1
after execution of the following statement:
strcat(s1, s2);
|
|
|
c. Which variable changes value after execution of the following statement:
strcpy(s1, s2);
|
|
| d. Write statement to point loc to the start of the substring "me" in
s2.Have exactly one blank after any comma and before and after the assignment
operator. |
|
|
e. Give the value of comp after execution of the following statement:
comp = strcmp(s1, s2);
|
|
File I/O
A text file is a file of characters. The data type FILE describes
various features of a file. Each file in a program must have an associated pointer to this type. We can
declare a pointer to file, file_ptr, as
FILE *file_ptr;
We can open a file for reading (input) and a file for writing (output) as follows:
infile_ptr = fopen("astronomy.dat", "r");
/* open input file */
outfile_ptr = fopen("asteroid.dat", "w");
/* open output file */
If the file does not exist, fopen returns a special constant,
NULL. We should verify that the computer successfully opened the file before continuing, such as
if (infile_ptr == NULL)
{
printf("astronomy.dat does not exist.\n");
exit(1);
}
The standard library with header file stdlib.h contains exit,
which aborts the program and returns its argument to the operating system. To close the file with pointer
file_ptr, we use fclose, as follows:
fclose(file_ptr);
The standard I/O library function fprintf, which behaves almost the
same as printf, sends its output to a specified file. An example call to this function follows:
fprintf(outfile_ptr,
"%d\n", amt);
The header file stdio.h also declares a file input function,
fscanf, which reads from the file specified by a FILE pointer as the first parameter.
An example call to this function follows:
fscanf(infile_ptr,
"%d", &amt);
One method to accomplish continuous processing is to read and test for the correct
amount of input in a while condition. Afterwards, we use the feof in an if
statement to check for end-of-file.
while (fscanf(infile_ptr,
"%f", &price) == 1)
{
...
}
if (!feof(infile_ptr))
{
fprintf(stderr, "There was an error reading the
file.\n");
exit(1);
}
The function fputs writes a string to a file, such as
fputs(str, outfile_ptr);
If fputs cannot write the string to the file, the function returns
EOF. The function fgets to read from a file into a string accepts three
arguments, the string variable, the maximum number of characters (including '\0') to place in the string,
and a pointer to the input file. For instance,
fgets(str, 15, infile_ptr);
If fgets cannot read the string to the file, the function returns
NULL. Tables 2 and 3 summarize I/O with strings.
Table 2 Functions to write strings up to '\0'
| Example Function Call |
Write to |
Adds '\n'? |
Error Return |
| printf("%s", str); |
stdout |
no |
negative |
| puts(str); |
stdout
|
yes |
EOF |
| fprintf(outfile_ptr, "%s", str); |
output file |
no |
negative |
| fputs(str, outfile_ptr); |
output file |
no |
EOF |
Table 3 Functions to read strings, placing '\0' at the end
| Example Function Call |
Read from |
Skip White Space before? |
Read |
Stop Reading with |
Error Return |
| scanf("%s", str); |
stdin |
yes |
word |
white space |
EOF |
| gets(str); |
stdin |
no |
line |
'\n' (discard) |
NULL |
| fscanf(infile_ptr, %s", str); |
input file |
yes |
word |
white space |
EOF |
| fgets(str, n, infile_ptr); |
input file |
no |
line |
'\n' (keep), eof, or n - 1 characters |
NULL |
| Quick
Review Question |
Quick Review Question 7
Type exactly one blank before any asterisk, after any comma, and on each side of an
assignment equals.
a. Complete the declaration of fp as a file pointer:
_____fp;
|
|
|
| b. Write a statement to open the file to which fp points for input.
On disk, this file is mustard.mol. |
|
|
| c. If this file is not found, give the subsequent value of fp. |
|
|
| d. Suppose AtomName is a character array of at most three elements.
Using fgets, write a statement to read the next two characters from the file to
which fp points into AtomName. |
|
|
| e. Suppose natoms and nbonds are int variables. Using
fscanf, write a statement to read the next two integers (separated by one blank)
from the file to which fp points into these variables. |
|
|
Enumeration Types
The declaration of structures and enumeration variables in C is similar, but not
identical, to that of C++. Consider the following enumeration definition:
enum answer {NO, YES}; /* C
or C++ definition */
Unlike C++, to declare a variable cont to be of this type in ANSI C, we must
preface answer with enum, as follows:
enum answer cont; /* ANSI C
declaration */
One method of avoiding writing enum repeatedly in declarations is to use a
typedef.
typedef enum answer
answer_t; /* ANSI C definition */
We could also define the values of the enumeration type and define answer_t
in one statement.
typedef enum {NO, YES}
answer_t; /* ANSI C definition */
With either definition, we can declare cont to be of this equivalent type
without using the prefix enum.
answer_t cont; /* ANSI C
declaration */
| Quick
Review Question |
Quick Review Question 8
Complete the type definition of enumeration type color_t.
a b {RED, GREEN, BLUE} c ; |
|
|
Structure Types
Similarly, ANSI C requires declaration of a structure variable to start with
struct, unless we have glued "struct" to the structure name in a typedef. For example, with
the structure definition in C
struct SolventRec_t /* C or
C++ definition */
{
char SolventName[21];
int FreezingPoint;
};
we must declare solvent of this type as
struct SolventRec solvent;
/* ANSI C declaration */
| Quick
Review Question |
Quick Review Question 9
Complete the type definition of structure type BondData_t using typedef.
a b {int first, second, BondType} c ; |
|
|
Type Conversions
The syntax of casting a variable to another type is different in C than in C++. For
example, suppose we want to compute the percentage correct on an exam. There are 250 possible points
(TotalPossible) on the final, and the student earns 200 (TotalEarned) of them. The percentage
score percent is 200 / 250 = 0.80 = 80%. In C or C++, the integer division 200 / 250 results in a
truncation of the quotient to 0. Consequently, we must cast TotalEarned or TotalPossible or
both to a float or double before the division.
int TotalEarned, TotalPossible;
float percent;
.
.
.
percent = (float)TotalEarned / TotalPossible; /* C casting */
To perform this type conversion in C++, we use a function notation, as follows:
percent = float(TotalEarned) /
TotalPossible; // C++ type conversion
Allocation and Deallocation of Space
In C, we can allocate space with malloc (memory allocation) and
restore the space to available memory with free, which are in the standard library,
stdlib. The C++ counterparts of malloc and free are new and
delete, respectively. For example, suppose int_ptr is a pointer to an int.
int *int_ptr;
In C, we can allocate space and point int_ptr to that area using appropriate
casting, as follows:
int_ptr = (int *)malloc(sizeof(int));
In C++, we can use the new operator as
int_ptr = new int;
To allocate an integer array of ten elements dynamically, in C++
we write
array_ptr = new int[10];
In C, we determine the total amount of space and cast as follows:
array_ptr = (int *)malloc(10 *
sizeof(int));
As with new, if malloc cannot allocate space, the operator returns
NULL.
In C, to make available the cell to which int_ptr points we use free:
free(int_ptr);
In C++, we use delete:
delete int_ptr;
If array_ptr points to an array, in C we write
free(array_ptr);
while in C++, we place empty brackets between delete and the array or
pointer name, as follows:
delete [] array_ptr;
| Quick
Review Question |
Quick Review Question 10
Type exactly one blank before any asterisk, after any comma, and on each side of an assignment
equals.
a. Complete the declaration of AtomName as a character pointer.
___AtomName;
|
|
|
| b. Allocate space for 3 characters to which AtomName points. |
|
|
| c. Deallocate the space. |
|
|
Exercises
Write answers to the following exercises in C:
1. Write statements to prompt the user and to read a value for int variable num.
2. Write a statement to print the value of string variable bird and int variable
count along with descriptions of the values.
3. Write statements to print the number and integer total on one line and floating point
average another. Double space the output. If number is zero, display "No data". Otherwise,
compute the average.
4a. Define RhFactor_t as an enumeration type with possible values PLUS and MINUS. Use
typedef
b. Define BloodType_t as an enumeration type with possible values M, N, and MN.
Use typedef.
c. Declare Rh and BloodType to be variables of types RhFactor_t and BloodType_t,
respectively. Have appropriate comments.
d. Declare subject to be a char pointer.
e. Allocate space for subject so that it can hold a name of length 30. Be sure to allocate enough
space to hold the null character, too.
f. Write a prototype for a function GetBloodInfo that has input parameter subject, a
character pointer, and sends back values for the Rh factor and blood type.
g. Call GetBloodInfo, sending it the name of the subject and obtaining the Rh factor and blood type.
h. Define a structure type to contain a subject's name, Rh factor, and blood type. Use typedef.
5a. Declare array_ptr to be a pointer to a float, and dynamically allocate space for a
float array of 100 elements.
b. Write an error message to the standard error file if allocation was not possible.
c. Dynamically deallocate the space obtained in Part a.
Programming Projects
Develop a program in C for one of the following projects:
1. Project 1 or 2 in module "Database
Introduction".
2. Project 1 or 2 in module "Genomic
Data".
3. Project 1 or 2 in module "Genomic
Sequence Comparison".
4. One of Projects 1-6 in module "Searching
Genomic Databases".
5. A psychology researcher's file, R10502.dev,
contains data for an experiment with a pigeon in two-lever box. Each line contains
an event code as in Quick
Review Question 1 of "Relational Databases" and the time of occurrence.
Develop a program to report the count of each event and the average time of pellet
delivery. (Data contributed by Dr. Alliston Reid, Psychology Department, Wofford
College.)
6. A biology researcher's file contains data for a subject's name, Rh factor (+ or -), and blood type
(M, N, or MN). Count the number of subjects in each of the following categories: all, +, -, M, N, MN, + M,
+ N, + MN, - M, - N, and -MN. Use enumeration types.
Copyright © 2002, Dr. Angela B. Shiflet
All rights reserved