170 likes | 293 Views
Built-In (a.k.a. Native) Types in C++. int, long, short, char (signed, integer division) unsigned versions too unsigned int , unsigned long , etc. C++ guarantees a char is one byte in size Sizes of other types are platform dependent Can determine using sizeof() , <climits> INT_MAX
E N D
Built-In (a.k.a. Native) Types in C++ • int, long, short, char (signed, integer division) • unsigned versions too unsigned int, unsigned long, etc. • C++ guarantees a char is one byte in size • Sizes of other types are platform dependent • Can determine using sizeof() , <climits> INT_MAX • float, double (floating point division) • More expensive in space and time • Useful when you need to describe continuous quantities • bool type • Logic type, takes on values true, false
User (& Library) DefinedTypes in C++ • enumerations enum primary_color {red, blue, yellow}; • functions and operators • For example, things called from main function • structs and classes • Similar abstractions in C++, extend C structs
struct My_Data { My_Data (int i) : x_(i) {} int x_; }; class My_Object { public: My_Object (); ~My_Object (); private: int y_; }; Struct members are public by default Class members are private by default Both can have Constructors Destructors Member variables Member functions Common practice: use structs for data use classes for objects with non-trivial methods Comparing C++ Classes and Structs
More About Both Native and User Types • Pointers • raw memory address of an object or variable • its type constrains what types it can point to (more later) • can take on a value of 0 (not pointing to anything) • References • “alias” for an object or variable • its type constrains what types it can refer to (more later) • cannot be 0 (always references something else) • Mutable (default) vs. const types (read right to left) const int i; // read-only declaration int j; // readable and writable declaration
Scopes in C++ • Each symbol is associated with a scope • The entire program (global scope) • A namespace (namespace scope) • Members of a class (class scope) • A function (function scope) • A block (block scope) • A symbol is only visible within its scope • Helps hide unneeded details (abstraction) • Helps prevent symbol conflicts (encapsulation)
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 self-contained, 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
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
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 {…}}
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 }
#include <iostream> #include <string> using namespace std; int main (int, char*[]) { string s; // empty s = “”; // empty s = “hello”; s += “, ”; s = s + “world!”; cout << s << endl; // prints: hello, world! return 0; } <string> header file Various constructors Assignment operator Overloaded operators += + < >= == [] The last one is really useful: indexes string if (s[0] == ‘h’) … C++ string Class
#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. Using C++ vs. C-style Strings
#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 C++ Input/Output 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 C++ File I/O Stream Classes
#include <iostream> #include <fstream> #include <sstream> using namespace std; int main (int, char*[]) { ifstream ifs (“in.txt”); if (ifs.is_open ()) { string line_1, word_1; getline (ifs, line_1); istringstream iss (line_1); iss >> word_1; cout << word_1 << endl; } return 0; } <sstream> header file Use istringstream for input Use ostringstream for output Useful for scanning input Get a line from file into string Wrap string in a stream Pull words off the stream Useful for formatting output Use string as format buffer Wrap string in a stream Push formatted values into stream Output formatted string to file C++ String Stream Classes
#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; } 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? Using C++ String Stream Classes
Storing Other Data Types Than char • There are many options to store non-char data in C++ • Differ in complexity, ease of use • Native C-style arrays • Can not add or remove positions • Can index positions directly • Not necessarily zero-terminated (why?) • STL list container (bi-linked list) • 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 0 1 2 3 4 X X 0 1 2 3 4 X
A Quick Look at Vectors • Goals • Give you a good basic data structure to use for now • Cover its correct usage • Start understanding why • Vectors: nicer than arrays • 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 • #include <iostream> • #include <vector> • using namespace std; • int main (int, char *[]) { • 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); • // ... and now this is ok ... • for (size_t s = 0; s < v.size(); ++s) { • cout << "v[" << s << "] is " • << v[s] << endl; • } • return 0; • }