Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
69 views

Intro To Programming

This document provides an introduction to programming in C++. It summarizes key concepts such as variables, data types, expressions, control structures, functions, and file input/output. C++ programs consist of functions, with a main function that returns 0. The language supports fundamental data types like integers, floating-point numbers, characters, and Booleans. Expressions can perform math operations and type conversions. Control structures include conditional statements, loops, and switches. Functions allow code reuse through definitions and declarations. File I/O streams like ifstream and ofstream enable reading from and writing to files.

Uploaded by

espyter
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
69 views

Intro To Programming

This document provides an introduction to programming in C++. It summarizes key concepts such as variables, data types, expressions, control structures, functions, and file input/output. C++ programs consist of functions, with a main function that returns 0. The language supports fundamental data types like integers, floating-point numbers, characters, and Booleans. Expressions can perform math operations and type conversions. Control structures include conditional statements, loops, and switches. Functions allow code reuse through definitions and declarations. File I/O streams like ifstream and ofstream enable reading from and writing to files.

Uploaded by

espyter
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 44

Intro to Programming

 
 
review
www.Linux.wfu.edu has linux info
C++ developed in 1980's, introduced object oriented programming
Written to write operating systems, not programs, as result, programs can be object
oriented (not as much as java)
Or function oriented, series of objects that are called, not created
 
C++ programs consist of functions
Every C++ program has only one main function
 
Main function "
Int main()
{
Return 0;
}
" that's all, not all the
You can have them part of an object, but they will be just functions for now. They
consist of multiple statements
 
Simple statements
End with a ;
Compound statements
{ } may contain more simple or compound statements
 
Variable declaration
Binds a symbolic name to memory address
Syntax
"
Type VariableName;
"
"
Type VariableName = UnitExpression;
"
 
Types and literals
C++ like java provides fundamental (available by default) types and literals
 
Characters (ASCII)
Type name char
Literal are single characters within ' ' single quotes
'\n' end line '\t' tab '\b' backspace
Stored using one byte
 
Integers
Type name is int uses 4 bytes
Literal is any number non-decimal and non-E can't start with 0
Long, short, unsigned
Long is 4 bytes
Short is 2 bytes
Unsigned 2 or 4 bytes, positive only
Brown bag meeting on Thursday
 
Real numbers
Type name is float (4 bytes)
Or double (8 bytes)
Literals are any numbers with or with out decimal and or E
 
Boolean
Type name is bool
Literal are true or false
1 byte
 
Examples"
{
int count = 0;
Char ch;
Double x;
Bool done = true;
Return 0;
"
 
Often a program may use a constant like pi 3.14…
If you don't want to change it,
"
const double PI = 3.14;
"
Can't ever change, will throw an exception
 
Expressions
Most have the form
Operand1 operator operand2
 
The data > literals, variables, or another expression
 
Math operators
*/%
+- (PEMDAS order of operations)
 
Mixed expressions
C++ allows 1+1 and 1.0+1.0
Same operation on different types
Simple polymorphism
1.0 + 1 promotes the lower 1 to higher 1.0 (implicit coercion)
 
C++ also does coercion from high to low
 
double x = 5.5000;
int i = x; //wipes out the decimal
double y = i;
 
char ch = 'a'+ 1; //will make ch 'b' because of the ascii
number
 
 
Type casting
"
int i = 5;
int j = 2;
double x = i/j; //x will be 2.0 not 2.5 because both I and
J are integers
"
"
double x = i/static-cast(double)(j);
double x = i/(double)j;
double x = i/(double(j);
"
 
Unary operators
x++
++x
-x
! (not)
 
Like most expressions, two things occur
First is side effect
A change in variable which results in evaluating the expression
Result
Value returned
Chaining
X = y = 3;
<==
Side effect y gets 3
Result is y (is returned)
X=y
Y is stored to x
Result is x
 
 
C++ allows output to a stream
Using << operator
"
Ostream << value;
"
Inserts Value into the Ostream
Cout is the ostream for the terminal
for example
"
int i = 5;
Cout << "the value is" << i;
"
 
"int n = 90;
Cout << "n is " << n << '\n';"
 
Input
C++ allows input from an input stream
Use the >> operator
"Istream >> Variable;"
Cin is the instream for the keyboard
 
int n;
cin >> n;
 
If you wanted to do two integer inputs
"cin >> n >> m;" it will sift through the input and take two inputs
Side effect (chance)
Variable n changes and cin changes
Result (returned)
cin is returned
 
You must declare cin and cout because they are objects
 
To use cin and cout, you have to include the library using the # include statement
Statements;
{expressions}
 
Example.cpp or .c++
"
#include<iostream>
Using namespace std;
int main ()
{
int n1, n2;
cout<< "enter ints";
cin >>n1>>n2;
cout <<"average is "<<(n1+n2)/2.0<<'/n'
return 0;
}
"
Just use notepad or a text editor
 
To Compile
g++ -o example example.cpp
Compiler
executable name it will create
source file
The compiler checks for syntax errors
If possible, it will create the binary/executable file
Source->[compiler]->executable
 
Boolean expressions
Relational
==
!=
<
>
<=
>=
 
Logical
&&
|| (or) and && are short circuit evaluations, if one side is a certain thing,
don't even need to test
! (not)
 
Remember false = 0, true is any other value
 
Conditional operator
Ternary (3 operands) Boolean operation
 
"BooleanExpression?TrueValue:FalseValue"
Like an if/else statement
 
 
Other operators
Subscript arrarys
arraryName [index]
 
Function call
functionName ();
 
Scope operator
Classname::componentName
Dot operator
Class.member
 
Control structures
Three types:
Sequential
Selection (if statements)
If
if (bool) {
Statement;
}
else {
}
 
 
Switch
"switch (expression)
{
case constant1:
Statement;
Break;
Case constant2:
Statement;
Break;
:
Default:
Statement;
}
"
Repetition
While loop
"while (bool)
Statement;"
For loop
"for (init expression;continue expression;
update expression)
Statement;"
Do while loop
"do
Statement;
While(bool);
"
 
File I/O
Must create fstream to read/write to/from
"fstream Variablename;
//then associate it to a file
fstream inFile;
inFile.open("input.dat",ios::in);"
 
All in one line
 
"fstream outfile("output.dat",ios::out);"
ios::in, input only
ios::out, output only, (destroys a file)
 
To do it, you have to import the fstream library
Fexample.cpp
"
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
int n = 0;
int value;
fstream infile("data.dat";ios::in);
//assumes data.dat is a notepad file with 1 2 3 4 x in it
double sum = 0.0;
while (infile>>value)
{
sum += value;
n++;
}
if (n==0)
cout<<"no values in file '\n'";
else
cout << sum /n << '\n';
inFile.close();
return 0;
}
"
Functions
When a code fragment is useful in multiple places, make it a function
Function definition
"returnType Funcitonname (argumentlist)
{
statements;
}"
Function declaration
"returnType FuncitonName (argument list);"
 
"#include<iostream>
Using namespace std;
void print();//declaration
int main ()
{
cout<<"hello";
print(); //call statements, actual argument list
return 0;
}
void print () //function definition, formal argument list
{
cout<<"world"
}"
 
Passing arguments
The relationship between the actual and formal arguments is determined by
the passing mechanism
1 pass by value (default)
If an argument is passed, the function can change it but it doesn’t get
passed back
If the formal is declared as
Type Argumentname
New variable is created for the formal argument with the actual
argument value, modify the formal, the actual does not change!
2 pass by reference
Formal argument is declared as
Type &argumentname
Name of the formal is alias for the actual and therefore changes in the
formal occur to the actual
3 pass by constant reference
If the formal argument is declared as
Const type &argumentname
Formal is an alias for the actual, but you cannot change the variables
Faster than pass by value
"#include<iostream>
using namespace std;
void input(int &first, int &second); //pass by reference
int calc (int first, int second); //pass by value
void output (int n); //pass by value
int main ()
{
int n1, n2, ans;
input (n1, n2);
ans = calc (n1, n2);
output (ans);
return 0;
}
void input (int &first, int &second)
{
cout<<"enter two integers "
cin >>first>>second;
}
int calc (int first, int second)
{
return first +second;
}
void output (int n)
{
cout << "answer is " <<n<<'\n';
"
Explicitly making a function call itself is recursive programming
Break a problem into smaller parts and call the function on the smaller parts
 
For example, factorials
 
Every recursive algorithm has two parts
Base case, process without recursion, causes you to exit
Recursive step: process recursively on a smaller problem
 
"unsigned long factorial (unsigned long n)
{
if( n== 0)
return 1;
else
return n*factorial (n-1);
}"
5
5*(
4*(
3*(
2*(
1*(
1
Or
 
"return (n==0?1:n*factorial (n-1));"
 
 
#include <cmath> has all of this
 
"double power(double a, int n)
{
If (n == 0)
Return 1;
Else
Return a*power(a,n-1);//won't work as a negative power 2^-3
}"
Code that works for negative powers
"double power(double a, int n)
{
If (n > 1)
return a*power(a,n-1);
Else if (n<0)
Return 1/a*power(a,n+1);
else
Return 1;
}"
 
 
Object
Consists of a name, memory location and value
Block- a pair of {} containing zero or more statements
Constructing the object-bind a name to a memory location
Destructing the object-destroy the bind
Lifetime-time when an object exists, construction to destruction
Auto-objects initialized each time execution passes the declaration
Static-object initialized once, when program begins
Default is auto
Static is explicitly defined
"#include <iosteam>
using namespace std;
double avgValue(double n);
int main ()
{
double n;
cout<<"enter a positive value";
cin>>n;
while(n>0)
{
cout<<"average " <<averageValue(n)<<'\n';
cin<<n;
}
return 0;
}
double avgValue(double n)
{
static int cout = 0;
static double sum = 0.0;
double avg;
count ++;
sum +=n;
avg = sum/count;
return avg;
}"
 
Other storage classes
Register
Externa
Scope
Object's scope reflects its accessibility
Three scope rules
1. Object declared in a block has local scope, can only be accessed
inside that block
2. Function argument has function scope, only accessed within
that function
3. Global, declared outside of a function or block, can be used
wheneva
4. Illegal to have two objects with the same name and scope
"int x = 30;
void f(int x, int &y);
int main ()
{
int y = 35;
int z = 54;
if (z>y)
{
int temp = y;
y = x;
}
x = 54;
int x = 45;//already an x declared, but this works,
and the most recent x will be used
f(x,y); //if you want to use the global x
}"
Enumerations
Suppose a problem involves data that cannot use a fundamental type
Example
Represent a color value, red, blue
Enumerations allow the programmer to define a new integer based type
"enum color {red = 0, blue = 1, yellow = 2};//enum newType
{possible values}, must be global
//considers color an int and will map an integer value
int main()
{
color hue;
hue = red;
hue ++; //hue will become blue
}"
 
"#include<iostream>
using namespace std;
enum Color{Red, Blue, Yellow};
Color colorComp(Color c);
int main ()
{
Color hue = Red;
Color comp = colorComp(hue);
}
Color colorComp(Color c)
{
Switch (c)
{
case Red:
return Blue;
case Blue:
return yellow;
case yellow:
return Red;
default:
return Red;
}
}"
 
Anonymous enumerations
enum {Maxlenght = 10};
 
 
Color hue = Red;
cout<<hue;
cin>>hue;
hue++;
hue + c;
None of these will work the way we want them too
 
Function overloading
c++ allow multiple definitions for the same function if the arguments are
different (number and/or type)
Example
int square (int n);
double square (double n);
It will call each function depending on what you put in the argument of the
function when you call it
 
C++ has more than 40 operators
 
Function call equivalent
2+3;
operator + (2,3);
 
2+3+4;
operator + (operator+(2,3),4);
Side effect and result
 
Operator overloading
1. Must specify the operator being overloaded
2. Specify arguments
3. Specify return type
4. Specify the side effect
 
Only allowed to overload an operator for types that are not defined
 
Assume we have
enum Color{red, green};
Want to output "red" or "green"
Color hue = red;
cout << hue;
 
ostream& operator<<(ostream&out, Color hue);
 
 
 
ostream& operator<<(ostream&out, Color hue)
{
switch (hue)
{
case red:
out<<"red";
break;
case green:
out<<"green";
Break;
default:
out<<"illegal color";
}
}
 
Default arguments
C++ allows one to specify default values for arguments
If an actual argument is omitted, the compiler uses a default value
Rule: default arguments must be the right most in the argument list
int sum(int first, int second = 0; int third = 0);
int sum(int first, int second = 0; int third = 0)
{return first + second + third;}
If only one int is passed thru sum, it will default the other two to 0
Defaults and overloading
Syntax error if a function with defaults makes an overload
 
Arrays
A single dimensional array can store a list of values
All values must be the same type
Declaration
Type ArrayName [Number];
Any defined type, name, amount of elements in array
int grades [11];
//allocates 11 contiguous int memory locations
Int grade [3] = {0,0,0};
Double miles [] = {10.9, 12.4, 18.8};
Int cost [10] = {2};
2,0,0,0,0,0,0,0,0,0,0
Int length [4] = {1,2};
1,2,0,0
 
Int grade [4];
Grade [0] = 100;
For (int i=0;i<3, i++)
Grade [i]=100;
 
Arrays as arguments
Pass a single element out of array, give array name and index for
actual argument
 
Void swap (int&, int&);
 
Int main()
{
Int a[]={1,2,3,4}
Swap (a[0],a[1]);
For(int i=0,i<4,i++)
{
Cout a[i]<<" ";
}
}
 
Pass entire array
*actual and formal arguments must be arrays
*array elements are passed by reference by default
*should pass array size
 
Void intArray(int a[], int length);

Int main ()
{
Int values [5];
Int b[100];
intArray (values, 5);
intArray(b,25);

}
Void intArray(int a[], int length)
{
For (int i=0;i<length=;,i++)
a[i]=0;
}
 
 
Recursive array summation
Int sum (int a[], int size)
If (size == 0) return 0;
Return a[size-1] + sum(a,size-1);
 
 
Compiler directive
Statements are not part of C/C++
Commands given to the compiler, done before the program is compiled
#include
#define
#define value1 value2
Swaps value1 for any instance value2 occurs, works with statements
#define MAX_VALUE 100
 
 
Insert an element into an array
int a[5] = {2,4,6,9}
How to insert a 3 in the second location s
To make it {2 3 4 6 9)
 
Int a[20];
Int maxsize = 20;
Int size;
Int loc;
Int item;
 
If (size < maxsize && loc < size && loc > 0)
{
For (int i = size, i>loc: i--)
a[i] = a [i-1];
a[loc] = item;
Size ++;
}
 
Delete an element from an array
Int a[4] ={2,4,6,9};
To remove the 4 from the array
Copy the 6 to the 4 spot, the 9 to the 6 spot, and that’s it
Int a[20];
Int maxsize = 20;
Int size;
Int loc;
Int item;
 
if (loc>=0 && loc<size)
{
For (int i = loc; i <size-1; i++)
a[i] = a[i+1];
Size--;
}
 
Default arguments
int sum (int a, int b = 0, int c= 0) a value doesn’t have to be passed for b or
c
{
return a+ b + c;
}
 
 
Cstring
A list of characters
Literal enclosed in double quotes "ab"
Always an extra character stored, '\0'
\0 is the sentinel value to indicate the end of the string, it's what makes it a
proper cstring and not just an array of characters
Initialization of cstring
"char name[] = "Nirre";"
N i r r e '\0'
Output a cstring
"cout<<name;" will automatically print out the contents of the array
Cannot read
 
Must add space for the '\0' when dynamically alocating cstrings
"char str[] = "Pluf";
cout<<str<<" length is "<<strlen(str);
char * sPtr = new (nothrow)char[strlen(str)+1];
for(int i = 0, i<=strlen(str), i++;)
sPtr[i]=str[i];"
 
String length
"int n = 0;
while(str[n]!='\0')
n++;
return n"
 
Automatically passed by reference because it's an array, strings are not
 
 
 
Difference between c-string and string
String can be read
String is just a class and an object
String is bigger than cstring;
 
"#include<iostream>
using namespace std;
void readString(char str[], int maxSize);
int main()
{
char str[20];
readString(str,20);
cout<<str<<'\n';
retrun 0;
}
void readString(charStr[],int maxSize)
{
int n = 0;
char ch;
ch=cin.get();
while(ch!='\n'&& n < maxSize - 1)
{
str[n]=ch;
n++;
ch=cin.get();
}
Str[n]= '0';"
 
Possible to define a variable with multiple '*'s
"int** str;//stores the address of a pointer to a pointer to an int"
Each * represents "pointer to" therefore str is a pointer to a pointer to an int
 
"çhar ch = 'A';
char * cPtr1 = &ch;
char ** cpTr2=&cPtr1;
cPtr2 => address of cPtr1
*cPtr2=> address of ch;
**cPtr2=> 'A'
*(&cPtr2)=>the address of cPtr1
&(**cPtr2)=>the address of ch}"
 
 
"char *cPtrList[3];
//array of 3 pointer to character elements
char ch1 ='A';
char ch2 ='B';
cPtrList[0]=&ch1;
cPtrList[1]=&ch2;
cPtrList=>address of cPtrList[0]
*cPtrList=> contents of cPtrList[0]
*cPtrList[0]=>contents of the address of cPtrList[0] which is ch1 or
'A';

char str[]="CD";//automatically adds \0 to the end


cPtrlist[2] = str;
cout<<cPtrList[2]; //[prints out content of address of cPtrList[2]"
 
"char** cPtrList = new (nothrow)char*[3];
cPtrList[0]=new(nothrow) char[3];
cPtrList[0][0]='A';
cPtrlist[0][1]='B';
cPtrList[0][2]='\0';

*(*cPtrList +1)=> the address of [0] then the content of it which is


the address of 'A' which is +1 goes up one set of data to 'B' the
address of it then the contents of it"
 
In DOS and Unix it is possible to pass arguments to the main function with the
command line
To do so must include int argc and char* argv[] in the arguments for main
argc= number of arguments on the command line including the executable name
argv= array of char pointers(cstrings)
"int main (int argc, char* argv[])
{
for(int I = 0, I < argc, i++)
cout<<argv[i]<<'\n';
return 0;
}"
Assume compiled into a.exe
.\a.exe a bc 123
Would print out
a
bc
123
 
 
 
 
"{}"
 
 
 
 
 
 
 
Tuesday, September 25, 2007
8:47 AM
 
Performance analysis
There are several things to consider when considering performance
Correctness
Amount of work done
How to measure amount of work done
Number of lines of code? no
Kloc=1000 lines of code
Execution time? No
Need a method that is dependent of language, architecture
Best approach
Determine a "fundamental operation" required by any
algorithm that solves the problem
Determine # of times a fundamental operation is
performed
 
Ex: searching
Comparing is a fundamental operation
We are interested in the best worst and average cases, given
an input
Linear search
Best case performance B(#of elements)=1
Worst case W(n)=n
Average case performance A(n)=n/2
Binary search
Eliminate half of the list from each compare
Assume ascending sorted list
Compare to middle of list
 
int binarySearch(int value, int list[], int [n])
 
int middle;
int low = 0;
int hi = n-1;
while (low<=hi)
{
middle = (hi + low)/2;
if (value == list[middle])
return 0;//means found
else if(value< list[middle])
hi = middle - 1;
else
low = middle +1;
}
return -1;//means not found
Binary search analysis
Worst case, thing not in the list, and it keeps
splitting the list until it gives up
log2(x)=n
No average
Best case 1
 
 
 
Space used
Optimality
 
Array sorting
Bubble sort
Assume a[5] = {7,3,8,5,2};
Bubble sort would do the following
Compare a[0] to a[1], if out of order, swap
'' '' a[1] to a[2] …
Until end of a pass
Repeat until there is a pass without swaps, sorting is done
After each pass, the largest number will be at the last slot
void bubbleSort(int a[], int n)
{
int pairs = n-1;
bool done = false;
int I;
while (!done)
{
done = true;
for (i=o,i<pairs, i++)
if (a[i]>a[i+1])
{
swap (a[i], a[i+1})
done = false;
}
}
}
 
Assume you have a set of functions you need to use across multiple programs,
HOW?
Not copy and paste
Header and source files
Header file-contains declarations of functions: Name.h
Source file contains definitions of functions: Name.cpp
Example: place swap in header and source files
Swap.h:
"#ifndef SWAP_H
#define SWAP_H
void swap (int& first, int& second);
 
#endif"
 
Swap.cpp
"#include "swap.h"
void swap(int& one, int& two)
{
}"
 
Example.cpp
"#include<iostream>
#include "swap.h"
int main()
{
int x,y;

swap (x,y);
}"
 
 
Compiler statement would be g++ -o example.exe example.cpp swap.cpp
Could take a while to recompile swap.cpp every time,
g++ -c swap.cpp creates swap.o, not an executable, because no main function. Is a
binary version of swap.cpp
 
 
 
 
2-D arrays
C++ allows up to 12 subscripts for arrays
For tables, of same type
Declaration: type name[rows][columns]
"int m[2][2]={{1,2},{3,4}};
Access: m[0][0] = 10;"
 
Passing 2D arrays
Always pass by reference!!
Formal arguments may omit 1st dimension, remaining must be defined exactly
"void initMatrix(int m[][4], int row, column);
int main ()
{
int m[4][4]; #define is better because argument must always
match arrays
 
initMatrix(m,2,2);
}
void initMatrix(int m[][4], int row, column)
{
for(int j =0; j<row; j++)
m[i][j]=0;
}" n2 is worst case scenario operation
 
"#define MAX_SIZE 4
void initMatrix(int m[][MAX_SIZE], int row, column);
int main ()
{
int m[4][4]; #define is better because argument must always
match arrays
 
initMatrix(m,2,2);
}
void initMatrix(int m[][MAX_SIZE], int row, column)
{
for(int j =0; j<row; j++)
m[i][j]=0;
}"
 
 
 
Matrix multiplication
Dot product of rows from A with columns from B
(M*N)*(N*L) = M*L the columns in A must match the rows in B
 
For(int i=0; i<aCol; i+)
for(int j =0; j<bCol; j++)
{
sum =0.0;
for (int k = o; K<aCol;k++)
sum+=a[i][k]*b[k][j];
}
c[i][j]=sum;
}
}
 
 
 
 
Namespace
A name is a collection of definitions/declarations such as class definition and
variable declarations
We use the std which includes the definitions of "standard" C++ libraries
(cout, cin, …)
When you use the statement
Using namespace std;
That the compiler uses the definitions in std
What if you don't use the statement?
Cin and cout are not defined
Therefore namespaces allow programmer to use an identifier multiple
places, in different namespaces.
 
You can defined a namespace
"namespace Name
{
Declarations
Definitions
}"
 
"#include <iostream>
using namespace std;
namespace Space1
{
Void hello(){cout<<"hello";}
}
int main()
{
using namespace1;
hello();
}"
 
"#include<iostream>
using namespace std;
namespace Space1
{
void hello(){cout<<"space1";}
}
namespace space2
{
void hello(){cout<<"space2";
}
int main()
{
Space1::hello();
Space2::helo();
}"
 
 
 
Pointers:
Memory can be visualized as an array of bytes, where each byte has an
address
Before a program is executed, memory is empty, executing the program
allocates memory for the instructions and variables
"int i;
char c;
double r;"
We can acces with the variable name.
C++/C allows programmer to access memory address, using the & unary
operator
i=99
cout<<i<<"'s address is "<<&i;
C++ allows the programmer to store an address
A variable that stores an address is a "pointer"
A pointer is an address
int main()
{
int i=99;
int* iPtr =&i;
cout<<i<<" address is "<iPtr;
}
Even though the variable might take up more than one memory space,
pointers only tell you the first memory spot
Pointer declaration
Type* pointername (ptr is good for the name)
Double* dPtr;
Int* iPtr;
dPtr = iPtr; DOESN’T WORK, can only point to one type
 
How to access memory pointed to
Dereference the pointer using the * unary operator
"int i=99;
int* iPtr = &I;
*iPtr=100;" another term for pointer is alias for i

One difference between C and C++ is C++ has pass by reference


To pass by reference in C++
"void swap(int& a, int& b)
{
int temp = a;
a=b;
b=temp;
}"
To call
"int a =10;
int b =100;
swap(a,b);"
 
In C, you had to use pointers.
"void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}"
To use
"int a = 10;
int b = 100;
swap(&a, &b);" & is for calling the actual memory. * is for modifying
it
 
Pointers and const
Position of const determines what is constant
int i = 99;
const int* iPtr= &i;
*iPtr = 40; illegal
int i =99;
int* const iPtr = &i;
iPtr = &j; illegal

 
Pointers=> * pulls the value, & pulls the address of the pointer
 
Dynamic Object Creation
1. Named variable - automatic, has a name associated with the memory
Normal declaration
2. Anonymous variable - has no name associated with memory
Created with new operator
"new (nothrow) Type;"
Allocates a block of memory large enough for that type
Returns the starting address of the block
 
When program begins execution, it has a segment of unused memory called heap
(free store)
Heap normally located between program and runtime state
It's possible that the heap will overrun the rts
If a program executes a new operation and no memory is available, new
returns 0 and is a null pointer
 
Good programming practice to test for null after a new operation
int * iPtr = new (nothrow) int; won't throw an exception
if (iPtr == 0)
{
cout<< "no memory"; //or cerr<<
exit(1);
}
Rts grows with every function call, shrinks with every function
termination
To reclaim dynamic memory (allocated by new)
Use the delete operator
"delete pointerName;"
Deallocates memory pointed to by PrinterName
Should point to NULL after delete
"#include <cassert>
int *iPtr = new (nothrow) int;
assert (iPtr != 0); "
If the boolean in assert is false, program will terminate and prints the line
number of the assert
To delete the elements in a dynamic array
"if(list)
delete []list;
list = temp;"
 
Why delete
Considering
"int* ptr1 = new (nothrow) int;
int* ptr2 = new (nothrow) int;
*ptr1 = 8;
*ptr2 = 9;
ptr1=ptr2; //legal because both the same type, * or & not
needed}"
The ptr1 will point to the 9, the 8 will get left alone, a Memory Leak
"delete ptr1;"
 
"if ( )
{
int* iPtr = new (nothrow) int;
*iPtr = 99;
cout<<"value is "<<*iPtr<<"\n";
}"
Need a delete iPtr; BEFORE the if brackets close
 
"int * iPtr = new (nothrow) int;
*iPtr = 99;
cout<<"value of memory is "<< *iPtr<<'\n';
delete iPtr;
*iPtr = 100;"
Big problem, compiler won't catch it, runtime error. Allocating a value to
memory that the program may not own anymore
 
Dynamic arrays
"enum{maxSize = 100}
int a [maxSize];"
If we use less than 100 elements, waste of space
If we use more than 100 elements, it'll need to be recompiled
To define a dynamic array, use the new operator
"new (nothrow) Type [integer];"
Integer can be constant, literal, or variable
"int n =5;
int* a = new (nothrow) int[n];
// allocates enough space for 5 element int array
// returns the address of the first (0) element"
*a=90;
 
Pointer math
To access other elements, add an integer to the pointer a+1
&a = 0X0012 since it’s an int, it has 4 bytes and the next memory
would be 16
*(a+1)=100; stores 100 to 0X0016
You have to create a new array with one more element, copy the old
crap, and insert the new one
Deleting is the same principle
 
Normal method still works
a[1] = 100;
Same as
*(a+1) = 100;
Never index beyond the bounds of array
 
Deleting a dynamic array
Use delete operator [] pointer name
"delete [] PointerName"
Pointers and arrays
 
"char* ptr1;
char* ptr2;
char c[10];
ptr1 = new (nothrow) char[10];
ptr2 = new (nothrow) char;
// is the following legal?
c=ptr1; // illegal
ptr1 = c; //legal pointer1 points to the first element of c's
array, ptr1 now is an array name
ptr2 = ptr1; //legal (both memory leaks) }"
 
They are not passed by reference by default like arrays!
To pass a dynamic by reference, you must say "void name(int*&
dynamicArray)" *&
 
 
MAKE
"make"
Maintain programs
Programming project
Large number of programs or modules
Linked to produce final result
Modules
Set of source programs
May be shared with other modules
Change during development
compile
when you write a program now in Fulp's class, you put it all in one
.cpp
What fulp will start having you do soon is you put your int main()
function in one .cpp, your function calls or definitions in another .cpp,
and finally your pre-shit calls in a header file
what makefile does is it links all those files into one file
Final will depend on function1.c function2.c and function3.c
" cc-o final function1.o function2.o function3.o"
It will check to make sure all the .o files are as new as their counter
part .c files, if not, it will require a recompile
Can have multiple levels of dependencies
 
Command generator, creates a series of commands in unix
5 files, main.cpp ioproc.h ioproc.cpp net.h net.cpp
"g++ -c main.cpp
g++ -c ioproc.cpp
g++ -c net.cpp
g++ -o program.exe main.o ioproc.o net.o"
To make a change in main.cpp
"g++ -c main.cpp
g++ -o program.exe main.o ioproc.o net.o"
To make a change to ioproc.h
Create a make file, create a file called makeFile
In it would be:
"program.exe: main.o ioproc.o net.o
g++ -o program.exe main.o ioproc.o net.o // must add a tab before
main.o: main.cpp ioproc.h net.h
g++ -c main.cpp
ioproc.o: ioproc.cpp ioproc.h
g++ -c ioproc.cpp
netio: net.cpp net.h
g++ -c net.cpp"
 
Target: dependencies
Tab=>| command
Target is the desired file, dependencies are anything that, if they change,
mean the target file need to be recompiled
 
To run a make file use this command line
"make" and it looks for a file called makeFile
If it's called something else, lab3.mak
"make -f lab3.mak"
 
Void pointers
A pointer can be assigned to another if it is the same type
"int* iPtr1 = new (nothrow) int (100);
int* iPtr2=iPtr1;
double* dPtr = iPtr1; //illegal
cout<<*dPtr; //also illegal
casting can help here
double *dPtr = (double)iPtr1; not a good idea, won't get the
value you should"
 
Void pointer is the exception, can point to anything
"void *vPtr = iPtr1;
vPtr=dPtr;"
 
Cannot de-reference a void pointer
cout<<*vPtr won’t work
You need to caste it
cout<<*((double*)vPtr)<<'\n';
 
Function pointers
A function name is actually an address, the start of the code therefore
possible to point to a function
"void printInt(int n) {cout<<n<<'\n';}
int main()
{
Void (*fPtr)(int value) = printInt;
(*fPtr)(5);//calls printInt, sends the argument 5"
Syntax:
returnTypeOfFunction (*fPointerName)(arguments of function just the
type)
 
Example
"int countNumber(int a[], int n, int target, bool(*compae)(int
first, int second));
bool greater(int t, int s);
bool less(int t, int s);
int main ()
{
int a[5]={10,20,30,40,50};
int n = 5;
cout<<"Number of elements above 25
"<<countNumber(a,n,25,greater)<<'\n';
cout<<"Number of elements lower 25
"<<countNumber(a,n,25,less)<<'\n';
return 0;
}
bool greater(int t, int s){return f>s;}
bool less(int t, int s){return f<s;}
int countNumber(int a[], int n, int target, bool (*compare)(int
t, int s))
{
int count = 0;
for (int I = 0; i<n, i++)
if((*compare)(target,a[i]))
count++;
return count;
}"
 
Hexidecimal conversion
0x means nothing,

 
Pasted from <http://64.233.169.104/search?
q=cache:VuvNiqUkqMIJ:h71000.www7.hp.com/DOC/73final/4515/4515pro_038.html+decimal+equivalent+hex
adecimal+address&hl=en&ct=clnk&cd=3&gl=us>
 
 
Reference variables
Used for passing by reference, but can also define variables as references
Int I;
Int& r = I;
R is a reference to I, and if we change i, r changes
Must be initialized when declared
Cannot reassign to another variable after declaration
 
Array reference
If you have an array, a[5], just 'a' will return the address of a[0]. a+1 will
return the address of a[1]
Array insert
"void arrayInsert(int value, int*& a, int& n)
{
int* temp = new (nothrow) int [n+1];
temp[0]=value;
for (int i = 0;i<n;i++)
temp[i+1] = a[i];
n++;
if(a)
delete []a;
a=temp;
}"
 
 
"{}"
 
 
 
 
 
 
 
 
 
 
 
 
 
Tuesday, October 23, 2007
9:07 AM
 
Structs
Most real problems involve data items that are not easily modeled using a
fundamental type
 
For example, how do you represent a date
Int day, month, year
 
And you want to store using a single type
Struct allows the programmer to group items
 
"struct DateStruct
{
int day;
int month;
int year;
};"
Use
"DateStruct day;
DateStruct anotherDay = {23,10,2007};"
 
Syntax
"struct Name
{
Type MemberName;
…other members
}; //must have semi colon"
Only defines object, doesn't automatically declare it
 
Better than arrays because it can have different types of values.
To access members, use .
"DateStruct today;
today.day=23;
today.year=2007;
today.month=10;
cout<<today; //won't work, need to overload it
cout<<today.day<<'/'<<today.month…;"
 
Overloading for cout<<
"#include<iostream>
using namespace std;
struct DateStruct
{
int day;
int month;
int year;
};
Ostream& operator<<(ostream& out, DateStruct day)
{
out << day.month<<'/'<<day.day<<'/'<<day.year;
return out;
}
int main ()
{
Datestruct today = {23, 10, 2007};
cout<<today<<'\n';
}"
Can point to a struct
DateStruct today = {23,10,2007};
DateStruct* dPtr = &today;
(*dPtr).day = 24; //dPtr->day=24; also works
 
Object oriented programming
Encapsulate ur shit in classes
Protect the data by grouping in a class the parts (data members) and
functions (member functions)
Date class
Constructor functions
Creates an instance of that class/function thing
Ways to do it
Don't write one, then you get one with 0 arguments by default
Write one with arguments
Write one with default arguments
No return values
And their code can be in line or in a separate file
Functions in the class
You can do it in line for example
int day() const{return day_;}
Or you can make that the .h file and have another .cpp for
date with the actual function
int Date::day(){return day_;}
"class Date
{
public: //member function //other functions canNOT access
this shit
Date (int d = 1, int m = 1, int y = 2004);
//constructor function
int day() const; //const here means cannot mess with
any data members
int month() const;
int year() const;
void advanceDate();
//maybe include an overload for << and >>
private: //data members //other functions outside of Date
can access this shit,
int dat_;
int month_;
int year_;
}
int main()
{
Date d(10,30,2007);
d.avanceDate();
cout<<d.year(); //d.year_ would not return year because
It's private
}"
 
Double colon :: is the scope resolution operator
Functions of our new class, in Date.cpp
"Date::Date(int d, m, y)
{
day_ = d;
month_ = m;
year_ = y;
}
/*alternative
Date::Date( int d, int m, int y):day_(d), month_(m), year_(y){}
//called member initializer
*/
int Date::day() const
{
return day;
}
int Date::month() const
{
return month_;
}
int Date::year() const
{
retrun year_;
}"
 
If in main, to create a Date thing
"main ()
{
Date today(18,3,2004); //march 18th 2004
int day;
day=today.day();
}"
 
Class practice
List
Data members
# of items in a list
List itself (array of ints)
Member functions
Initialize itself
Tell how long list is
Add items to list
Print list
Concatenate two lists
List.h
"#define MAX_SIZE
class List
{
public:
List();
int listSize();
void printList();
void add(int value);
void cat(int l2[];
List operator+(const List& list)
private:
int n_;
int list_[MAX_SIZE];
//? enum{maxSize_ = 100;}
};"
 
List.cpp
"#include<iostream>
#include "List.h"
Using namespace std;
List::List()
{
n_=0;
}
int List::listSize() const
{return n_;}
Void List::add(int value)
{
if (n_=MAXSIZE_)
Cerr<<"List full";
else
{
item_[n_]=value;
n_++;
}
}
Void List::printList() const;
{
for(int i=0;i<n_;i++)
cout<<item_[i]<<' ';
cout<<'\n';
}
//concatenation
//List list1, list2, list3
//want list3=list1+list2;
//list1.operator+(list2);
//LHS.operatorSymbol(RHS)
List List::operator+(const List& list)
{
List temp;
int i;
for (i=o;i<n_;i++) //LHS
temp.list[i]=list_[i];
for(i=o; (i<list.n_)&&(i<(maxSize_-n_); i++)//RHS
temp.list[n_+i]=list.list_[i];
temp.n_=n_+i;
return temp
}
//need to overload = because when you initiate list and do =
{2343,2432432} it will copy all that to the array
const List& operator=(const List& list)
{
//test to see if list = list was called
if (this != list.this)
{
n_=list.n_;
for(int I = 0; i<n_; i++)
list_[i]=list.list_[i];
}
return *this;
}"
"this" is a pointer. Something to do with classes and current object
 
When overloading <<, you need to make it global, because the left side of the
operator is ostream
Use "friend"
 
main.cpp
"#include<iostream>
#include "List.h"
using namespace std;
int main ()
{
List list;
int value;
cout<<Ënter positive int, negative to quit";
cin>>value;
while(value>=0)
{
list.add(value);
cout<<"Enter int, negative to quit";
cint<<value;
}
cout<<"the list is ";
list.print();
return 0;
}"
 
"//overloading a ==
bool operator ==(const List& list) const;

//.cpp file
bool List::operator==(const List& list)
{
if(n_ != list.n_)
return false;
for(int i=0; i<n_; i++)
if(item_[i]!=list.item[i])
return false;
return true;
}"
 
 
 
 
Fundamental data types are available by default
Math * / + - %
Output/input << >>
Logic == != > <
Called "first class" type
What are some non-first class types
Arrays
Fundamental type can represent numbers, integers and real
 
Rational class
1/3 instead of .333333333333
It knows: numerator and denominator
Can do: initialize itself, add, subtract, multiply, divide. Logic. Input/output
Rational.h
"class Rational
{
public:
Rational (int n= 0; int d = 1);
Rational operator+(const Rational r);
Friend ostream& operator<<(ostream& out, const Rational& r);
Friend istream& operator>>(istream& in, const Rational& r);
//need for 3+rational
friend Rational operator+(const Rational& a, const rational& b);

private:
int num_;
int denom_;
void reduce();
};"
 
Rational.cpp
"Rational::Rational (int n = 0, int d = 1)
{
num_=n;
dnom_=d;//with default arguments, works with 0, 1 and 2
constructors
}
ostream& operator<<(ostream& out, const Rational& r)
{
cout<< r.num_<<'/'<<r.denom_;
return out;
}
istream& operator >>(istream& in, Rational& r)
{
char slash;
in>>r.num_>>slash>>r.denom_;
return in;
}
Rational Rational::operator+(const Rational r);
{//r+3 would work, would initiate a new rational with one integer
argument, 3
//3+r won't work though, because it's equivalent to 3.operator(a);
Rational temp;
temp.num_=r.num_*denom+r.denom_*num_;
temp.denom_= denom_*r.denom_;
temp.reduce();
return temp;
}
Rational operator+(const Rational& a, const Rational& b) +
(rational(3))
{
 
}
}"
 
Rules for overloading operators
Use "friend" if the operator has two operands such as ==, !=, <<, >> and
the left hand side is not an instance of the calling class
"member" if the operator has two operands and the left hand side is always
an instance of the calling class
"member" if the operator has one operand
Class Operator Friend/member?

Date << Friend

List + Friend

Rational ++ Member

Rational == Friend
Vector class help
"class Vector
{
public:
Vector(double x = 0.0, double y = 0.0, double z =
0.0);

friend Vector operator+(const Vector& v1, const
Vector& v2);
friend Vector operator+(double x, const Vector&
v2);//this
Vector operator+(double x);//code for this and above
are same more or less

private:
double v_[3];

}
 
//Say it is called like so
Vector v(1.0,2.0,3.0);
Vector v1 = v+5.0;//should be v1=(5+1, 5+2, 5+3);"
 
 
I forget what it's called
Adjlist will represent any size list of integers
It knows: list, size
Can do: create a new list
Empty list (null constructor)
Existing copy of a list (copy constructor)
Destroy the list
Determine size
Add item to list
Concatenate
Assignment
Output
 
"class AdjList
{
public:
AdjList(int size = 0, int initValue=0);
AdjList(const AdjList a);
~AdjList();//called when class is destroyed
int size() const{return size;};
void addItem(int value);
Const AdjList operator =(const AdjList& a);
AdjList operator+(const AdjList a);
friend ostream& operator<<(ostream& out, const
AdjList& a);
private:
int* item_;
int size_;
};

//.cpp file is the following
AdjList::AdjList(int size, int initValue)
{
if (size>0)
{
item_ = new (nothrow)… I fucked this up
size_ = dlkdsalkda
for (int c= 0; c<size; c++)
Item_[c] = initValue;

}
}
AdjList::AdjList(const AdjList& a);// why not call by value?
Saves space
{
if(size_>0) //deep copy, shallow would just be a pointer
{
item_ = new (nothrow) int [a.size_];
size_ = a.size_;
for (int i = 0; i<a.size_;i++)
item_[i]= a.item_[i]
}
else
{
item_=0;
size_=o;
}
}
 
//destructor called when an object is destroyed, used to de-
allocate any dynamic memory used //by class
//name is always ~ClassName, no return or arguments SON
AdjList::~AdjList()
{
if (item_)//if pointing to something besides null
delete[] item_;
}
 
//if the assignment operator is not explicitly overloaded,
default is provided
//why not use default?
//cuz its stupid
//algorithm: delete existing memory of LHS, allocate
const AdjList& AdjList::operator=(const AdjList& a)
{
if (this!=&a)
{
if (item_) delete[] item_;
size_= a.size_;
if(size_>0)
{
item_ = new (nothrow) int [size];
for (int i=0;i<size_; i++)
item_[i]=a.item_[i];
}
else
{item_=0;}
}
 
return *this;
}"
 
Overload + operator
"AdjList AdjList::operator+(const AdjList& a)
{
AdjList temp(size_+a.size_, 0);
int i;
for (i=0;i<size_; i++)
temp.item_[i]=item_[i];
for(i=0=;i<a.size_;i++
temp.item_[size_+i]=a.item_
}"
 
Overload []operator
"int & AdjList::operator[](int index)
{
if(index<1||index>size_)
{
cerr<<"going to burn \n";
return item_[0];
}
return item_[index-1];
}"
 
Add
"void AdjList::addItem(int value)
{
int* temp = new (nothrow) int size[size_+1];
int i;
for(i=0;i<size_;i++)
temp[i]=item_[i];
temp[i] = value;
size_++;
if(item_) delete[] item_;
item_=temp;
}
//or 1 line:
//*this=*this + AdjList(1,value);"
 
 
 
If a class has a pointer data member, you should define
1. Assignment operator =
2. Copy constructor
3. Destructor ~ otherwise memory leak
4. Null constructor, can be included in other constructors with default arguments
=0
 
 
 
Exam
Wednesday, November 28, 2007
12:49 AM
Linked lists
Consider an array storing items
2,4,8,88…
Assume we need to insert a new value
 
How many operations are required?
Fundamental assignment
Adding
Worst(n) = n+1;
Removing
Worst(n)= n-;
We want to develop a non-array data structure to store a list
One way is to use a linked list of names
Multiple arrays with 2 elements
[2, ] [4, ] [8, ] [88, ]
Second element is called a node, address that points to next
element
Assume we want to insert a 3 between 2 and 4,
1. Create node containing 3
2. Make new node point to 4
3. Make the node of 2 point to the 3
To do this, create a struct
Node contains two things, value and next node/pointer
"Struct Node
{
int value_;
Node* next_;
};"
Links are unidirectional, only move forward
To move backward, you can add another node that
points to the previous Node
Otherwise all operations must start at the beginning.
Worst case of this Worst(n) = 1 or constant
"class LinkList
{
public:
LinkList(){head_=0;};
LinkList (const LinkList& list); //copy
constructor
~LinkList;
void addItem(int value);
bool isItem(int vlaue) const;
bool removeItem(int value);
const LinkList& operator=(const LinkList&
list);
friend ostream& operator<<(ostream& out, const
LinkList& list);
private:
Node* head_;
}"
Defining functions
"bool LinkList::isItem(int value) const
{
Node* cursor head_;
while(cursor != 0) //not equal to what ever last node
is, this case, null 0
{
if(cursor->value_==value) //cursor-> same as
(*cursor).value_
return true;
cursor=cursor->next_;
}
//or
bool LinkList::isItem(int value) const
{
for(Node* cursor = head_; cursor; cursor->next_)
if(cursor->value_==value)return true;
return false;
}
/*add item
2 cases to consider
1. Adding to empty list (head_ == 0)
2. Adding to existing list (head_ != 0)
Find end of list
Create new node
Make last node point to new node
*/
void LinkList::addItem(int value)
{
if (head_==0)
{
head_ = new (nothrow) Node;
head_->value_=value;
head_-.next_=0;
}
else
{
Node* cursor = head_;
while(cursor->next_ !=0)
cursor=cursor->next_;
cursor->next_=new(nothrow) Node;
cursor = cursor->next_;
cursor->value_=value
cursor->next_=0;
}
}
/*
Remove item-remove a value from the list
4 cases to worry
3. Empty list
4. First one of list
5. Any element but first
6. Not on list
*/
bool LinkList::removeItem(int value)
{
if(head==0)return false;
Node* current = head_;
Node* previous;
if (head_->value_==value) //(*head_).value_ same
thing
{
head_ = head_->next_;
current -> next_=0;
delete current;
return true;
}
while (current)
{
if (current->value_==value)
{
previous->next_=current->next_;
current->next_=0;
delete current;
return true;
}
previous = current;
current+=current->next_;
}
return false;
}
LinkList::~LinkList()
{
Node* previous=head_;
Node* current = head_;
while(current!=0)
{
current=current->next;
previous->next_=0;
delete previous;
previous = current;
}
}
//copy constructor
LinkList::LinkList(const LinkList list);
{
//deep copy
if (list.head_==0)
head_=0;
else
{
head_=new (nothrow) Node;
head_->value_=list.head->value_;
Node* slist = list.head_;
Node* dlist = head_;
slist = slist->next_;
while(slist!=0)
{
dlist->next_=new (nothrow) Node;
dlist = dlist->next_;
dlist ->value_ = slist->value_;
slist = slist -> next_;
}
dlist->next_=0;
}
}"
 
Linked list with class Node
Methods for a node object
Null constructor with defaults
Destructor
Accessor functions
Overload assignment
"class Node
{
public:
Node(int item = 0, Node* link=0):value_(item),
next_(link){} //called base //initialization list,
only works for constructors
Node(const Node& n);
~Node();
int value()const{return value_;}
Node* next()const{return next_;}
const Node& operator=(const Node& n);
private:
int value_;
Node* next_;
friend class LinkList;
}"
 
Structs and classes: everything is public in structs, classes
have privates
 
"Node::Node(const Node& n)
{
value_=n.value_;
if(n.next_==0)
next_=n.next_;
else
next_=new (nothrow) Node(*(n.next_));
}
"const Node& Node::operator=(const Node& n)
{
if (this!=&n)
{
if(next_)delete next_;
value_=n.value_;
if(n.next_==0)
next_=0;
else
next_=new (nothrow) Node(*(n.next_))
}
}
Node::~Node()
{
if(next_)delete next_;
next_=0;
}
//the new linkedlist with the Node class
class Linkedlist
{
public:
Linklist(){head_=0}
Linklist(const LinkList& list);
~Linklist();
const Linklist& operator=(const Linklist& list);

private:
Node* head_;
};
Linklist::LinkList(const Linklist& list) //copy constructor
{
if (list.head_==0)
head_=0;
else
head_=new (nothrow) Node(*(list.head_));
}
Linklist::~Linklist()
{
if(head_) delete head_;
}
const Linklist& Linklist::operator=(const Linklist& list)
{
if(this!=&list)
{
if(head_) delete head_;
Linklist temp(list;
head_ = temp.head_;
temp.head_=0;
}
return *this;
}
//+operator concatenate
Linklist Linklist::operator+(const Linklist& list)
{
Linklist temp;
Node* cursor= head_;
while(cursor)
{
temp.append(cursor->value);
cursor=->next_;
}
cursor= list.head_;
While(cursor)
{
temp.append(cursor->value_);
cursor=cursor->next_;
}
return temp;
}
Linklist Linklist::operator+(const Linklist& list)
{
Linklist lhs(*this); //need to add a check to make sure lhs
and rhs point to somethin
Linklist rhs(list); //such as if(rhs.head_) or something
Node* cursor = lhs.head_;
while(cursor->next_)
cursor = cursor->next_;
cursor ->next_=rhs.head_;
rhs.head_=0;
return lhs;
}
ostream& operator<<(ostream& out, const Linklist& list)
{
Node* cursor = list.head_;
if(cursor==0)
out<<"empty list";
else
{
while(cursor!=0)
{
out<<cursor->value()<<"; "<<cursor->next();
cursor=cursor->next();//need to use accessing
function () instead of _
}
}
return out;
}
 
}"
A friend of a friend is not a friend
 
"class ExtVector
{
public:
ExtVector(){ev_=0;size_=0;};
ExtVector(const ExtVector& e);
ExtVector(const Vector& v);
ExtVector(){if(ev_)delete[]ev_;}
private:
double* ev_;
int size_;
}
ExtVector::ExtVector(const Vector& v)
{
ev_ = new (nothrow) double [3];
for (int i =0;i<3;double[3])
ev_[i]=v[i+1];
size_=3;
}
//ExtVector + double
ExtVector ExtVector::operator+(double x)//in .h is friend
{
ExtVector temp (*this);//copy of calling object
for(int i=0;i<size_; i++)
temp.ev_[i]+=x;
return temp;
}"
 
 
Templates
Parameterized Polymorphism via templates
Consider the following
"void swap(int& a, int& b);
void swap(double& a, double& b);"
There's actually only one swap function
Templates allow more arguments
Function templates, if you have two or more arguments or more functions
that differ only in the argument types, then write a single function template
swap.h all code must be in .h file, cannot be compiled into .h
"template<typename T> //could add <typename S> if more than one
variable type
void swap(T& a, T& b)
{
T temp = a;
a=b;
b=temp;
}"
main.cpp
"#include "swap.h"
main()
{
int i=10;
int j = 20;
double x=20, y=30;
swap(i,j);
swap(x,y);
}"
Weird syntax
 
Templates really cool as classes
"template <typename T>
class TSimplelist
{
public:
TSimplelist();
void addItem(T item);
Tsimplelist<T> operator+(const TSimplelist<T>& list);
//need <> because they //were high when they made it
private:
int size_;
T item_[maxSize_];
enum{maxSize_=100};
};
 
template<typename T>
TSimplelist<T>::TSimplelist()
{size_=0;}
 
template<typename T>
void TSimplelist<T>::addItem(T item)
{
if(size_==maxSize_}
cout<<"list full\n";
else
{
item_[size_]=item;
size_++;
}
}"
 
main.cpp
"#include"tsimplelist.h"

main()
{
TSimplelist<int> iList;
TSimplelist<string> strList;
iList addItem(10);
}"
 
Make file
# Assignment: lab10 Date: 11/27/2007
 
CC = g++
CFLAGS = -g -pg -ansi
 
lab10.exe: vector1.o vector2.o driver.o extvec1.o extvec2.o
$(CC) -o lab10.exe driver.o vector1.o vector2.o extvec2.o extvec1.o
vector2.o: vector2.cpp vector.h
$(CC) -c vector2.cpp
vector1.o: vector1.cpp vector.h
$(CC) -c vector1.cpp
driver.o: driver.cpp
$(CC) -c driver.cpp
extvec1.o: extvec1.cpp extvec.h
$(CC) -c extvec1.cpp
extvec2.o: extvec2.cpp extvec.h
$(CC) -c extvec2.cpp
clean:
\rm -f *.o driver
make
 
Inheritance
Software reuse in which new classes are created from existing classes
Base class-existing class
Derived class-new class
3 types of inheritance
Public inheritance
Gets everything that base class has, but new functionalities in
derived class
"incremental programming"
"is a" relationship where an object of the derived class
can be treated as an object of the base
Hiding may occur, derived class defines a member
already, defined in base
Private inheritance
Public members in base are private in derived.
Protected inheritance
Gay
Extend Linklist to include a counter for the number of nodes- countlist
class CountList: public Linklist
{
public:
CountList();
CountList(const CountList& list);
~CountList();
const CountList& operator=(const CountList& list);
int count() const;
void addItem(int item);
void removeItem(int item);
private:
int count_;
}
countlist.cpp
"CountList::CountList():Linklist(), count_(0) {}
CountList::CountList(const CountList* list):Linklist(list),
count_(list.count_){}
//can pass CountList
list because it "is a"
CountList::~CountList(){}
const CountList& CountList::operator=(const CountList&)
{
//need to call base list function
*this.LinkList::operator=(list);
count_=list.count_;
return *this;
}
int CountList::count()const
{
return count_;
}
void CountList::addItem(int item)
{
LinkList::addItem(item);
count_++;
}
void CountList::removeItem(int item)
{
if (isItem(item))
{
LinkList::removeItem(item);
count_--
}
}"
 
Substituting a derived class for a base class is legal because of the "is a" relationship
Slicing may occur - if the derive class has more data members, when it gets sent
back, they are lost, deleted
"CountList list1;
list1.addItem(1);
LinkList list2;
list2=list1;//illegal
cout<<list1;//won't print count however, duh
 
//if you send list1 to a base function and it gets sliced,
count will still be //available when the variable comes
back"
 

 
Final Exam
Saturday 12/15 9am
Or Thursday 12/13 2pm
Everything except inheritance
21 questions
5 short answer
6 TF (can't use keyword 'this' in friend functions)
3 trace (pointer oriented)
6 class functions (dynamic arrays, linked list (current lab), node class)
1 makefile (simple, like the one on test 2)
 
"{}"
 

You might also like