Transcript Document

Why Use Namespaces?
• Classes encapsulate behavior (methods) and
state (member data) behind an interface
• Structs are similar, but with state accessible
• Classes and structs are used to specify selfcontained, cohesive abstractions
– Can say what class/struct does in one sentence
• What if we want to describe more loosely
related collections of state and behavior?
• Could use a class or struct
– But that dilutes their design intent
CSE 332: C++ strings, arrays, vectors, and io
Namespaces
• C++ offers an appropriate scoping mechanism
for loosely related aggregates: Namespaces
– Good for large function collections
• E.g., a set of related algorithms and function objects
– Good for general purpose collections
• E.g., program utilities, performance statistics, etc.
• Declarative region
– Where a variable/function can be declared
• Potential scope
– Where a variable/function can be used
– From where declared to end of declarative region
CSE 332: C++ strings, arrays, vectors, and io
Namespace Properties
• Declared/(re)opened with namespace
keyword
namespace Foo {int baz_;}
namespace Foo {int fxn() {return baz_;}}
• Access members using scoping operator ::
std::cout << “hello world!” << std::endl;
• Everything not declared in another namespace
is in the global (program-wide) namespace
• Can nest namespace declarations
namespace Foo {namespace Err {…}}
CSE 332: C++ strings, arrays, vectors, and io
Using Namespaces
• The using keyword makes elements visible
– Only applies to the current scope
• Can add entire namespace to current scope
using namespace std;
cout << “hello, world!” << endl;
• Can introduce elements selectively
using std::cout;
cout << “hello, world!” << std::endl;
• Can also declare unnamed namespaces
– Elements are visible after the declaration
namespace {int i_; // i_ is now visible
}
CSE 332: C++ strings, arrays, vectors, and io
C++ string Class
#include <iostream>
• <string> header file
#include <string>
• Various constructors
using namespace std;
• Assignment operator
int main (int, char*[])
• Overloaded operators
+= + < >= == []
{
• The last one is really
string s; // empty
useful: indexes string
s = “”;
// empty
if (s[0] == ‘h’) …
s = “hello”;
s += “, ”;
s = s + “world!”;
cout << s << endl; // prints: hello, world!
return 0;
}
CSE 332: C++ strings, arrays, vectors, and io
Using C++ vs. C-style Strings
#include <string>
•
#include <iostream>
using namespace std;
int main (int, char*[])
{
char * w = “world”;
•
string sw = “world”;
char * h = “hello, ”;
string sh = “hello, ”;
cout << (h < w) << endl; // 0: why? •
cout << (sh < sw) << endl; // 1:why?
h += w; // illegal: why?
sh += sw;
cout << h << endl;
•
cout << sh << endl;
return 0;
}
C-style strings are
contiguous arrays of char
– Often accessed through
pointers to char (char *)
C++ string class (template)
provides a rich set of
overloaded operators
Often C++ strings do “what
you would expect” as a
programmer
Often C-style strings do
“what you would expect” as
a machine designer
• Suggestion: use C++ style
strings any time you need to
change, concatenate, etc.
CSE 332: C++ strings, arrays, vectors, and io
Storing Other Data Types Besides char
• There are many options to
store non-char data in C++
– Differ in complexity, ease of use
• Native C-style arrays
0 1 2 3 4
X
– Can not add or remove positions
– Can index positions directly
– Not necessarily zero-terminated (why?)
• STL list container (bi-linked list)
X
0 1 2 3 4
X
– Add/remove positions on either end
– Cannot index positions directly
• STL vector container (“back stack”)
– Can add/remove positions at the back
– Can index positions directly
CSE 332: C++ strings, arrays, vectors, and io
Pointers and Arrays
int main (int argc, char **argv)
{
int arr [3] = {0, 1, 2};
• An array holds a contiguous
sequence of memory locations
int * p = & arr[0];
int * q = arr;
// p, q, arr point to same place
}
int arr [3]
0xefffdad0
int *p
0
1
2
0xefffdad0
int *q
– Can refer to locations using either
array index or pointer notation
– E.g., *arr vs. arr[0]
– E.g., *(arr+1) vs. arr[1]
• Array variable essentially
behaves like a const pointer
– Like int * const arr;
– Can’t change where it points
– Can change locations unless
declared array-of-const
– E.g., const int arr[3];
• Can initialize other pointers to
the start of the array
– Using array name, or using
address of 0th element
CSE 332: C++ strings, arrays, vectors, and io
Pointer Arithmetic With Arrays
int main (int argc, char **argv)
{
int arr [3] = {0, 1, 2};
int * p = & arr[0];
int * q = arr;
// p, q now point to same place
++q; // now q points to arr[1]
}
• Adding or subtracting int n
moves a pointer by n of the
type to which it points
– I.e., by n array positions
– E.g., value in q is increased
by sizeof(int) by ++q
• Can move either direction
– E.g., --q, ++p
• Can jump to a location
int arr [3]
0xefffdad0
int *p
0
1
2
0xefffdad0
int *q
– E.g., p+=2, q-=1
• Remember that C++ (only)
guarantees that
sizeof(char)==1
– But compiler figures out
other sizes for you
CSE 332: C++ strings, arrays, vectors, and io
Arrays of (and Pointers to) Pointers
• Can have pointers to pointers
Can also have an array of
pointers (like a const pointer to
a pointer type)
E.g., argv parameter in main
t e s t \0
– Array of pointers to character
strings
h e l l o \0 – Could also declare as a
pointer to the first pointer
– Notice array dimension is not
specified
0xefffa0d0 0xefffaad0
– Instead a special argument
char * argv[]
(argc) holds array size
int main (int argc, char *argv[])
•
{
// could declare char **argv
for (int i = 0; i < argc; ++i)
cout << argv[i] << endl;
•
}
int argc
2
• By convention, character
strings are zero terminated
– Special char is ‘\0’ not ‘0’
CSE 332: C++ strings, arrays, vectors, and io
Rules for Pointer Arithmetic
int main (int argc, char **argv)
{
int arr [3] = {0, 1, 2};
int * p = & arr[0];
int * q = p + 1;
• You can subtract (but not
add, multiply, etc.) pointers
– Gives an integer with the
distance between them
• You can add/subtract an
integer to/from a pointer
return 0;
}
– E.g., p+(q-p)/2 is allowed
but (p+q)/2 gives an error
int arr [3]
0xefffdad0
int *p
0
1
2
0xefffdad0
int *q
• Note relationship between
array and pointer arithmetic
– Given pointer p and integer
n, the expressions p[n] and
*(p+n) are both allowed
and mean the same thing
CSE 332: C++ strings, arrays, vectors, and io
Watch out for Pointer Arithmetic Errors
int main (int argc, char **argv)
{
int arr [3] = {0, 1, 2};
int * p = & arr[0];
int * q = arr;
// p, q now point to same place
int n;
q+=n; // now where does q point?
}
int arr [3]
0xefffdad0
int *p
0
1
2
0xefffdad0
int *q
• Dereferencing a 0 pointer
will crash your program
• Accessing memory location
outside your program can
–
–
–
–
Crash your program
Let you read arbitrary values
Let you modify that location
Last two: hardest to debug
• Watch out for
– Uninitialized pointers
– Failing to check pointer for 0
– Adding or subtracting an
uninitialized variable to a
pointer
– Errors in loop initialization,
termination, or increment
CSE 332: C++ strings, arrays, vectors, and io
Arrays, Pointers, and Dynamic Allocation
Foo * baz (){
// note the array form of new
int * const a = new int [3];
a[0] = 0; a[1] = 1; a[2] = 2;
Foo *f = new Foo;
f->reset(a);
return f;
}
void Foo::reset(int * array) {
// ctor must initialize to 0
delete [] this->array_ptr;
this->array_ptr = array;
}
• We’ve talked mainly about
stack variables so far
• Arrays, like individual objects,
can be allocated (new) and deallocated (delete) dynamically
– more details in later lectures
• Arrays have a particular syntax
– with [ ] in the new and delete calls
– Ensures constructors and
destructors of elements are
called automatically
• Don’t leak, destroy safely
void Foo::~Foo() {
// note the array form of delete – Requires careful attention to
delete [] this->array_ptr;
details of memory management
}
– More about this in next lectures
CSE 332: C++ strings, arrays, vectors, and io
A Quick Look at Vectors
#include <iostream>
#include <vector>
using namespace std;
int main (int, char *[]) {
• Goals
vector<int> v;
// This would be asking for trouble....
// v[0] = 1; v[1] = 2; v[2] = 4;
// ... but this works fine...
v.push_back (1);
v.push_back (2);
v.push_back (4);
– Give you a good basic data
structure to use for now
– Cover its correct usage
– Start understanding why
• Vectors: nicer than arrays
// ... and now this is ok ...
for (size_t s = 0; s < v.size(); ++s) {
cout << "v[" << s << "] is "
<< v[s] << endl;
}
return 0;
– Less to manage/remember
– Harder to get things wrong
(but still need to be careful)
• Example to the left prints
}
v[0] is 1
v[1] is 2
v[2] is 4
CSE 332: C++ strings, arrays, vectors, and io
Why to Use STL Vectors Instead of C++ Arrays
#include <iostream>
#include <vector>
using namespace std;
int main (int, char *[]) {
• Vectors do a lot of (often tricky)
memory management for you
– Use new[] and delete[] internally
– Resize, don’t leak memory
vector<int> v;
• Easier to pass to functions
// This would be asking for trouble....
// v[0] = 1; v[1] = 2; v[2] = 4;
// ... but this works fine...
v.push_back (1);
v.push_back (2);
v.push_back (4);
// ... and now this is ok ...
for (size_t s = 0; s < v.size(); ++s) {
cout << "v[" << s << "] is "
<< v[s] << endl;
}
return 0;
– E.g., can tell you their size
– Don’t have to pass a separate
size variable
– Don’t need a pointer by reference
in order to resize
• Still have to pay some attention
}
– E.g., push_back allocates more
memory but operator [] won’t
– E.g., vectors copy and take
ownership of objects they contain
CSE 332: C++ strings, arrays, vectors, and io
C++ Input/Output Stream Classes
#include <iostream>
using namespace std;
int main (int, char*[])
{
int i;
// cout == std ostream
cout << “how many?”
<< endl;
// cin == std istream
cin >> i;
cout << “You said ” << i
<< “.” << endl;
return 0;
}
• <iostream> header file
– Use istream for input
– Use ostream for output
• Overloaded operators
<< ostream insertion operator
>> istream extraction operator
• Other methods
– ostream: write, put
– istream: get, eof, good, clear
• Stream manipulators
– ostream: flush, endl, setwidth,
setprecision, hex, boolalpha
CSE 332: C++ strings, arrays, vectors, and io
C++ File I/O Stream Classes
#include <fstream>
using namespace std;
int main ()
{
ifstream ifs;
ifs.open (“in.txt”);
ofstream ofs (“out.txt”);
if (ifs.is_open ()
&& ofs.is_open ())
{
int i;
ifs >> i; ofs << i;
}
ifs.close ();
ofs.close ();
return 0;
}
• <fstream> header file
– Use ifstream for input
– Use ofstream for output
• Other methods
– open, is_open, close
– getline
– seekg, seekp
• File modes
– in, out, ate, app, trunc, binary
CSE 332: C++ strings, arrays, vectors, and io
C++ String Stream Classes
#include <iostream>
• <sstream> header file
#include <fstream>
– Use istringstream for input
#include <sstream>
– Use ostringstream for output
using namespace std;
• Useful for scanning input
int main (int, char*[])
– Get a line from file into string
{
– Wrap string in a stream
ifstream ifs (“in.txt”);
– Pull words off the stream
if (ifs.is_open ())
• Useful for formatting output
{
– Use string as format buffer
string line_1, word_1;
– Wrap string in a stream
getline (ifs, line_1);
istringstream iss (line_1); – Push formatted values into
stream
iss >> word_1;
– Output formatted string to file
cout << word_1 << endl;
}
return 0;
}
CSE 332: C++ strings, arrays, vectors, and io
Using C++ String Stream Classes
• Program gets arguments as
C-style strings
• But let’s say we wanted to
input floating point values
from the command line
• Formatting is tedious and
error-prone in C-style strings
(sprintf etc.)
• iostream formatting is friendly
• Can we get there from here?
#include <string>
#include <cstring>
#include <sstream>
using namespace std;
int main (int argc,
char *argv[])
{
if (argc < 3) return 1;
ostringstream argsout;
argsout << argv[1] << “ ”
<< argv[2];
istringstream argsin (argsout.str());
float f,g;
argsin >> f;
argsin >> g;
cout << f << “ / ” << g << “ is ” << f/g << endl;
return 0;
}
CSE 332: C++ strings, arrays, vectors, and io