7.18. C/C++

Copyright©  Department of Computer Science, University of Regina
Originally Written in 1998 by Zhiwei Wang

C++ was first invented by Bjarne Stroustrup in 1980 at Bell Laboratories in Murray Hill, New Jersey. He initially called it "C with Classes." However, in 1983 the name was changed to C++.

C++ is a superset of C. As a popular programming language, C has many excellent features. However, once a program exceeds 25,000 to 100,000 lines of code, it becomes too difficult to be comprehended as a whole. The purpose of C++ is to overcome this limit and provide a better way to manage larger, more complex programs, by using object oriented programming (OOP).
 
 

7.18.1. C: THE FOUNDATION OF C++

Because C++ is built upon C, you can not program in C++ unless you know

 how to program in C. This manual will first describe the C-like aspects of C++ and deal with C++-specific features later.
 
 

7.18.1.1 PROGRAM FORM

The general form of a C program is illustrated as below, where f1() through fN() represent user-defined functions.
 
 

global declarations
 
 

return-type main(parameter list)

{

statement sequence

}
 
 

return-type f1(parameter list)

{

statement sequence

}
 
 

return-type f2(parameter list)

{

statement sequence

}
 
 

...
 
 

return-type fN(parameter list)

{

statement sequence

}
 
 

When you write a program, you usually include standard library and add some comments. The following is a simple example.
 
 

/************************************************************

Filename: first.cpp

Author: Zhiwei Wang

Date: April 24, 1997

Description: This program prints a string to the monitor.

************************************************************/

#include <stdio.h>
 
 

/* This line is a comment. */

main()

{

// This is the C++ comment.

printf("This is my first C program.\n");

return 0;

}
 
 

This program calls the built-in C function 'printf' and prints out the sentence "This is my first C program. " to the screen. In order to use the 'printf' function, you have to include the <stdio.h> file, because the function prototype of 'printf' is in the header file <stdio.h>. Generally, if you want to use a built-in function, you must include the related header file which contains the function prototype of that function.

The first six lines are the program header; The line between /* and */, and the line after double slash // are comments. Program header and comments are used to increase the readability of the program. They are part of the program documentation.
 
 

7.18.1.2 PROGRAM DOCUMENTATION

By 'program documentation' we mean the following things:
 
 

1. Program header: Usually includes filename, author, date, description

of the program, usage of the program. etc.
 
 

2. Comments: Anything written between the characters /* and */ is a comment.

Comments are embedded in a program to help read the program.

Comments are ignored by the compiler. In C++, you can also use the

characters // to introduce a comments; Anything after // but in the same line is

a comment.

3. Indentation: Used to make a program easier to read.
 
 

Good program documentation will help people understand your program easier.
 
 

7.18.1.3 COMPILATION AND EXECUTION

In hercules, to compile a C program, type the command "cc" followed by the filename of the program and press [return] key; To compile a C++ program, type the command "CC" followed by the filename of the program and press [return] key. By definition, a C++ compiler is also a C compiler. Conventionally, a C program has the '.c' extension while a C++ program has the '.cpp' extension. Since the program 'first.cpp' has the double slash comment symbol, which is only allowed in C++, we will use the 'CC' command to compile it:
 
 

hercules[1]% CC first.cpp
 
 

This will create an executable file named "a.out". To run the program, type the name of the executable file "a.out":

hercules[2]% a.out

This is my first C program.

hercules[3]%
 
 

"a.out" is the default filename for the executable file created after compiling a program successfully. If you want to use another filename, you can use the "o" option followed by whatever filename you prefer. For example, the following command will create an executable file named "first":
 
 

hercules[4]% CC -o first first.cpp
 
 

To run the program, type "first" instead of "a.out":

hercules[5]% first

This is my first C program.

hercules[3]%
 
 

7.18.2 VARIABLES

The following example shows how to use variables. It calculates the circumference of a circle.

/************************************************************

Filename: perimeter.cpp

Author: Zhiwei Wang

Date: April 28, 1997

Description: This program calculates the circumference of circle. Input is the variable named 'diameter';

output is the variable 'perimeter'.

************************************************************/

#include <stdio.h>
 
 

main()

{

/* variable declaration */

float pi = 3.14159;

float perimeter, diameter;
 
 

printf("Please input the diameter: ");
 
 

/* read the value input from the keyboard and store it

in the variable diameter. */

scanf("%f", &diameter);
 
 

/* use the multiplication operator to do the calculation.

and assign the result to variable perimeter. */

perimeter = pi * diameter;
 
 

/* output the perimeter. */

printf("The perimeter is %f.\n", perimeter);

return 0;

}
 
 

The following is the compilation and execution of the program:
 
 

mercury[23]% CC perimeter.cpp

mercury[24]% a.out

Please input the diameter: 3

The perimeter is 9.424770.

mercury[25]%
 
 

A variable is a named location in memory that is used to hold a value assigned to it. Each variable should have a name, begin with a letter of the alphabet or an underscore. The length of the name should be between 1-31 characters. It is a good practice to use meaningful variable names.
 
 

All variables must be declared before they can be used. The general form of variable declaration is
 
 

type variable_list;
 
 

For example, the statement
 
 

float perimeter, diameter;
 
 

declares two variables: perimeter and diameter. Their type is 'float'. The following is a list of fundamental variable types:
 
 

Integral types:
 
 

char                       signed char                unsigned char              
short                      int                        long                       
unsigned short             unsigned                   unsigned long              

Floating types:
 
 
float                      double                     long double                

Please refer to other references for more details of each type.
 
 

The single equal '=' is the assignment sign. You can assign a value to a variable when you declare it, as in the line
 
 

float pi = 3.14159;
 
 

or you can do it later, as in the line
 
 

perimeter = pi * diameter;
 
 

In the preceding statement, the right side of the assignment sign is an 'expression'. The value of this expression is assigned to the variable 'perimeter'. The symbol '*' is an 'operator', standing for multiplication. Operators are discussed in the subsequent section.
 
 

7.18.3 OPERATORS

1. Math Operators

Primary Operators
 
 

Operator            Description                                                 
+                   When used as a binary operator, produces the sum of two     
                    numbers.                                                    
-                   When used as a binary operator, produces the difference     
                    of the two operands. When used as a unary operator,         
                    changes the sign of the operand.                            
*                   Binary. Produces the product of the two operands.           
/                   When / is applied to integers, any remainder is truncated   
%                   Produces a remainder of an integer division. Requires       
                    integers on both sides.                                     

Compound Operators
 
 
Operator            Example                    Equivalent                        
+=                  number += 100;             number = number + 100;            
-=                  number -= 100;             number = number - 100;            
*=                  number *= 100;             number = number * 100;            
/=                  number /= 100;             number = number / 100;            
%=                  number %= 100;             number = number % 100;            

2. Relational Operators
 
 

A binary relational operator operates on two operands and produces a truth value: 1 or 0
 
 

Operator            Description                                                 
==                  Equal to                                                    
>                   Greater than                                                
>=                  Greater than or equal to                                    
<                   Less than                                                   
<=                  Less than or equal to                                       
!=                  Not equal to                                                

3. Logical Operators
A             B             !A            !B            A && B        A || B        
False         False         True          True          False         False         
False         True          True          False         False         True          
True          False         False         True          False         True          
True          True          False         False         True          True          

4. Other Operators
 
 

The ?: operator
 
 

The format is:

conditional_expression ? expression1 : expression2;
 
 

If conditional_expression is true, Then expression1 executes, else expression2 executes.
 
 

Example:

a > b ? (num = 10) : (num = 25);
 
 

is equivalent to
 
 

if (a > b) {

num = 10;

}

else {

num = 25;

}
 
 

Please refer to section ? for if-else statement.
 
 

Example:

num = (a > b) ? 10 : 25;
 
 

In this example, if (a > b) is true, 10 is assigned to num; otherwise 25 is assigned.
 
 

The ++ and -- Increment and Decrement Operators

Operator        Example         Description     Equivalent Statement            
++              i++             Postfix         i = i + 1;            i  += 1;  
++              --i             Prefix          i = i + 1;            i  += 1;  
--              i--             Postfix         i = i + 1;            i  += 1;  
--              --i             Prefix          i = i + 1;            i  += 1;  

Remarks:

variable's value

1. When use a prefix operator, the operation occurs before the variable the variable's value is used in the rest of the expression. When use a postfix operator, the operation occurs after the variable the variable's value is used in the rest of the expression.

 2. Do not attempt to increment or decrement an expression.
 
 

Example:

 a1 = 3;

a2 = 3;

 b1 = ++a1 - 1;

 b2 = a2++ - 1;

 In this example, b1 will have the value 3 but b2 will have the value 2.
 
 

5. Shift Operators

Operator                          Description         Example                    
<<                                Bitwise left shift  num << 3                   
>>                                Bitwise right       num >> 3                   
                                  shift                                          

Compound Operators
&=              |=              ^=              <<=             >>=             

7.18.4 STATEMENTS

7.18.4.1 WHILE LOOPS

while (test expression) {

statements;

}

Test expression checked first. As long as test expression is true, statements execute repeatedly until test expression is false.
 
 

do {

statements;

} while (test expression);

Statements execute first. As long as test expression is true, statements execute repeatedly until test expression is false.
 
 

exit(status);

exit(status) is used in a loop or if statement to leave a program early. status is an integer variable or constant. Include stdlib.h header file when using exit().
 
 

break;

Instead of exiting an entire program, break can be used to exit the most internal loop.
 
 

7.18.4.2 FOR LOOPS

for (start expression; test expression; count expression) {

statements;

}

1. The start expression is evaluated before the loop begins and only be evaluated once. A typical start expression is an assignment statement (such as i=0).
 
 

2. The test expression evaluates to True or False and determines whether the body of the loop will execute or not. An example of a test expression is i < 100.
 
 

3. The count expression executes every time the body of the loop executes. A typical count expression is an increment or decrement statement (i++ or i--).
 
 

4. For loops can be nested.
 
 

5. break may be used in a for loop.

6. continue statement force s the system to perform next iteration of the loop immediately. The rest part after continue statements are ignored for the current iteration.
 
 

7.18.4.3 IF-ELSE STATEMENT

if (expression) {
  statement1;
}
else {
  statement2;
}
If the value of the expression is non-zero, statement1 will be executed, otherwise statement2 will be executed.

The 'else' part can me omitted. In this case, the statement takes the following form:

if (expression) {
  statement1;
}

7.18.4.4 SWITCH STATEMENT

switch (expression) {

case (expression_1) :

statements;

case (expression_2) :

statements;

...

case (expression_n) :

statements;

default :

statements;

}

1. The expression can be any int or char expression, constant, or variable. The subexpression (expression_1, ..., expression_n) can be any other int or char constant.

2. The default is optional and not necessary to be the last line of the switch body.
 
 

3. The case subexpression matches expression executes. If there is no match, default will execute.
 
 

4. Use break statements after each case block to avoid from "falling through" to the rest of the case statements.
 
 

7.18.4.5 GOTO STATEMENT

include <stdio.h>
 
 

main() {

Again:

printf("This message will repeat forever\n");

goto Again;

}

Avoid using goto whenever it is possible.
 
 

7.18.5 VARIABLE SCOPE

7.18.5.1 FUNCTIONS

Functions are the building blocks of C in which all program activity occurs. The general form of a function is

type-specifier function-name(parameter list)

{

body of the function

}
 
 

1. The type-specifier specifies the type of value that the function will return using the return statement. If no type is specified, the function is assumed to return an integer value.
 
 

2. All function, except those of type void, return a value. This value is explicitly specified by the return statement, or it is 0 if no return statement is specified.
 
 

3. As long as a function is not declared as void, it can be used as an operand in any valid C expression. However, a function cannot be the target of an assignment.
 
 

7.18.5.2 VARIABLE SCOPE

1. Variable scope refers to the extent to which a given variable can be referenced (visible).
 
 

2. Variables defined in a function are local variables. Their scope is limited to the function. Variables defined outside any function are global variables. Their scope is form the point they are defined down to the end of the file. It is better to use more local variables because global variables can be inadvertently overwritten.
 
 

3. Usually, a local variable comes into existence when the function is entered and is destroyed upon exit. These are called automatic variables. If you don't want the variable to be erased, you have to declare it as static. A static variable does not lose its value when its function ends.
 
 

7.18.5.3 PASSING VALUES

1. Passing by Value (or by Copy): When a variable is passed by value, a copy of the variable's value is assigned to the receiving function's parameter. You can't change the value of the original variable.

2. Passing by Address (or by Reference) When a variable is passed by address, the address of the variable is assigned to the receiving function's parameter. You can change the value of the variable. To pass a variable by address ,you need to do the following:
 
 

(1). Precede the variable in the calling function with an ampersand (&).

 (2). Precede the variable in the receiving function with an asterisk (*) everywhere the variable appears.
 
 

7.18.5.4 FUNCTION RETURN VALUES AND PROTOTYPES

1. To return a value from a function, put the return value after the return statement

 Don't return global variables.

2. Function prototypes

Example:

 Suppose a function is defined as:
 
 

int my_fun(int num, float amount)
 
 

If you call it as

my_fun(2.34, 5);
 
 

the compiler won't complain but the result is unpredictable. In order to avoid this problem, you must prototype the function. To prototype a function, just copy the definition line of the function to the top of your program and add a semicolon at the end of it.
 
 

3. The prototypes of build_in functions are in the corresponding header files.
 
 

7.18.6 ARRAYS AND POINTERS

7.18.6.1 ARRAYS

Arrays are used when many variables all of the same type are desired. For example the declaration
 
 

int number[5]; /* a one dimensional array */

int table[3][4]; /* a two dimensional array */

char hiarray[4][6][3]; /* a three dimensional array */

allocates spaces for the three elements of the array. The elements of the arrays are of type int. and are accessed as a[0], a[1], and a[2]. Note that the subscription (index) starts at 0.

 It's the programmer's responsibility to make sure not to assign values to out-of-range subscription.
 
 

7.18.6.2 INITIALIZING ARRAYS

1. assign values at declaration time.
 
 

Example

char city[7]= "Regina";

int table[3][4] = {

{1, 5, 6, 2},

{8, 1, 3, 5},

{4, 2, 6, 1}

};
 
 

char city2[6] = {'R', 'e', 'g', 'i', 'm', 'a'};

(note that city2[] is not a string.)
 
 

int number[5] = {1, 2, 3, 4, 5};
 
 

1. copy one element at a time. You may use a for loop in the program
 
 

Example

for (i=0; i<array_size; i++) {

number[i] = i + 1;

}
 
 

To copy values from one array to another array, you also need to copy it one element

 by one element.
 
 

Example

int i, j;

int new_table[3][4];

int table[3][4] = {

{1, 5, 6, 2},

{8, 1, 3, 5},

{4, 2, 6, 1}

};
 
 

for (i=0; i<3; i++) {

for (j=0; j<4; j++) {

new_table[i][j] = table[i][j];

}

}
 
 

7.18.6.3 POINTERS BASICS

1. What is a pointer

 A pointer is a variable that contains address of other variable. The first variable is said to

point to the second.
 
 

2. How to declare a pointer

 A pointer declaration consists of a base type, an *, and the variable name. For example:
 
 

int *p;
 
 

The base type defines what type of variable the pointer can point to. This is important

because all pointer arithmetic is done relative to its base type.
 
 

3. The address-of (&) operator and the dereferencing (*) operator

& is a unary operator that returns the memory address of its operand. For example,

suppose a variable num has a value of 100, the memory location of num is 2000,

 the statement
 
 

p = &num;
 
 

will assign the address value 2000 to p. In other word, p will have the value 2000, not

100.
 
 

* is a unary operator that is the complement of the &. It returns the value of the variable

pointed to by the pointer follows it. For example, it p has the value 2000, and the value

stored at memory location 2000 is 100. The following statement will assign the value

100 to the variable num1.
 
 

num1 = *p;
 
 

7.18.6.4 POINTER ARITHMETIC

Addition and subtraction can be used on pointers. If you add or subtract a number to a pointer, the actual value of the pointer will increase or decrease by that number times the size of the base type. Let us assume that the size of a character is 1 byte, the size of an integer is 2 bytes. Look at the following example.
 
 

#include <stdio.h>
 
 

main()

{

char *chp = (char *) 3000;

int *ip = (int *) 1000;
 
 

chp = chp + 3; /* chp will have the value 3003 now */

ip = ip + 3; /* ip will have the value 3006 now */

printf("chp has the value %ld, id has the value %ld\n",

chp, ip);

return (0);

}
 
 

Pointer comparisons are also allowed. For example, given two pointers p and q, the following codes are valid.
 
 

if (p<q) {

/* some statements here */

}
 
 

if (p==q) {

/* some statements here */

}
 
 

7.18.6.5 POINTERS AND ARRAYS

There is a close relationship between pointers and arrays. Array name is a pointer that points to the first element of the array. Consider the following codes:
 
 

char str[80], *p1;

p1 = str;

p1 has been set to the address of the first element. If you want to access the fifth element, you can use any of the following expressions:
 
 

str[4]; *(p1+4); p1[4]; *(str+4);
 
 

Usually, if an array is going to be accessed in strictly ascending or descending order, pointer arithmetic is faster than array-indexing. If an array is going to be accessed randomly, array-indexing is better.
 
 

Here is another example:

#include <stdio.h>
 
 

main()

{

int num[30], i, *p;
 
 

p = num;
 
 

for (i=0; i<30; i++) {

num[i]=i;

}
 
 

printf("The 5 th element num[4] is %d\n", num[4]);

printf("The 5 th element *(p+4) is %d\n", *(p+4));

printf("The 5 th element p[4] is %d\n", p[4]);

printf("The 5 th element *(num+4) is %d\n", *(num+4));

}
 
 

7.18.6.6 POINTERS TO POINTERS

A pointer to pointer is a for of multiple indirection. The first pointer contains the address of the second, the second pointer points to the variable. Look at the following example:
 
 

#include <stdio.h>
 
 

main()

{

int x, *p, **q;
 
 

x = 10;

p = &x;

q = &p;
 
 

printf("The value is %d\n", **q);

return 0;

}
 
 

7.18.6.7 DYNAMIC ARRAYS

If you use an array, the size of the array must be known before compiling time. If this size

 is unknown, you might use pointers. These are sometimes called dynamic arrays.
 
 

Example 1

main()

{

float *p;

int n;
 
 

printf("Please enter array size: ");

scanf("%d", &n);
 
 

if ( !(p = (int *) malloc(n * sizeof(float)) ) {

printf("Out of memory. \n");

exit(1);

}
 
 

/* now you can use p as an array of n floats */

/* some codes here */

free (p);

/* some codes here */

}
 
 

Example 2
 
 

int **get_array_space(int row, int col)

{

int **p;

int i;
 
 

if ( !(p = (int *) calloc(row, sizeof(int)) ) {

printf("Out of memory. \n");

exit(1);

}

for (i=0; i<col; i++ ) {

if ( !(p[i] = (int *) calloc(col, sizeof(int)) ) {

printf("Out of memory. \n");

exit(1);

}

}

return p;

}
 
 

void release_array_space(int **p, int row)

{

int i;
 
 

for (i=0; i<row; i++) {

free(p[i];

}

free(p);

}
 
 

7.18.7 STRUCTURES

7.18.7.1 STRUCTURES

A structure is a collection of one or more variable types. The following is an example to define a structure:
 
 

struct address {

char name[30];

char street[40];

char city[20];

char state[3];

char zip[10];

int grade;

float balance;

struct address *next;

struct address *prior;

};
 
 

In the declaration, struct is a key-word which tells the compiler that a structure template is being defined. address is the tag of the structure. After this declaration, you can use struct address as a data type to declare some variables. For example;
 
 

struct address list_entry; /* Define a variable list_entry which is a structure */
 
 

struct address *info; /* Define a point to the struct

address */
 
 

struct address *dls_store(struct address*, struct address*); /* Prototype of a function which returns a point

to structure address */
 
 

If list_entry is a variable of structure address, we use the . operator to refer to its field.

For example, the following code assign the string "Tom Smith" to the name field and 95 to the grade field of the variable list_entry:
 
 

strcpy(list_entry.name, "Tom Smith");

list_entry.grade = 95;
 
 

If info is a pointer to structure address, we use -> to refer to its field.

For example, the following code assign the string "Tom Smith" to the name field and 95 to the grade field of the structure address pointed by info:
 
 

struct address *info;
 
 

info = (struct address *)malloc(sizeof(list_entry));

if (!info) {

printf("\nout of memory");

return;

}

strcpy(info->name, "Tom Smith");

info->grade = 95;
 
 

7.18.7.2 ARRAYS OF STRUCTURES

We can define an array of structures. For example:
 
 

struct address my_friends[50];
 
 

The following codes assign a value to the balance field of the second element in the array:
 
 

my_friend[1].balance = 56.7;

7.18.7.3 LINKED LISTS

If the size of a array is unknown in advance, a linked list can be used instead of an array of structures. Linked lists can be linked either singly or doubly. A singly linked list contains a link to the next data item. A doubly linked list contains links to both the next and the previous element in the list.
 
 

Look at the example program for details.
 
 

7.18.8 DISK FILES

The most common functions are listed below. The prototypes of these functions are in stdio.h
 
 
Name                Function                                                    
fopen()             Open a string                                               
fclose()            Close a string                                              
putc()              Write a character to a stream                               
getc()              Reads a character from a stream                             
fseek()             Seeks to specified byte in a stream                         
fprintf()           A stream version of console I/O function printf()           
fscanf()            A stream version of console I/O function scanf()            
feof()              Returns true if end of file is reached                      
ferror()            Return true if an error has occurred                        
rewind()            Resets the file position locator to the beginning of the    
                    file                                                        
remove()            Erases a file                                               

The prototype for fopen() is
 
 

FILE *fopen(char *filename, char *mode);
 
 

where mode is one of the values listed below:

Mode                Meaning                                                     
"r"                 Open a text file for reading                                
"w"                 Create a text file for writing                              
"a"                 Append to a text file                                       
"rb"                Open a binary file for reading                              
"wb"                Create a binary file for writing                            
"ab"                Append to a binary file                                     
"r+"                Open a text file for read/write                             
"w+"                Create a text file for read/write                           
"a+"                Open or create a text file for read/write                   
"r+b"               Open a binary file for read/write                           
"w+b"               Create a binary file for read/write                         
"a+b"               Open or create a binary file for read/write                 
"rt"                Open a text file for reading                                
"wt"                Create a text file for writing                              
"at"                Append to a text file                                       
"r+t"               Open a text file for read/write                             
"w+t"               Create a text file for read/write                           
"a+t"               Open or create a text file for read/write