C++ History CPL – Combined Programming Language (1960s, University of Cambridge, University of...
-
Upload
derrick-gardner -
Category
Documents
-
view
219 -
download
2
Transcript of C++ History CPL – Combined Programming Language (1960s, University of Cambridge, University of...
C++ HistoryC++ History
•CPL – Combined Programming Language (1960s, University of Cambridge, University of London)•BCPL – Basic Combined Programming Language (1966, Martin Richards, language for writing compilers)GET "libhdr"LET start() = VALOF{ FOR i = 1 TO 5 DO writef("fact(%n) = %i4*n", i, fact(i)) RESULTIS 0}AND fact(n) = n=0 -> 1, n*fact(n-1)
•B (Dennis Ritchie, Bell Labs, 1969) printn(n,b) { extrn putchar; auto a; if(a=n/b) /* assignment, not test for equality */ printn(a, b); /* recursive */ putchar(n%b + '0');}
•C (Dennis Ritchie, Bell Labs, early 1970s, general purpose)•C++ (Stroustrup, Bell Labs, 1983, C with objects)•C++/CLI (Microsoft, 2005, “Managed” ECMA C++ Standard)
How C++ WorksHow C++ Works
Source Code
Preprocessed
Source Code
Object Code
Executable Code
Preprocessor
Compiler
Linker
Native MSILInterpreter
CPU
OS
C++ PreprocessorC++ Preprocessor
1. Source files processed by preprocessor to shape the code by substituting attributes*, expanding macros, processing conditional directives, including external files, issuing compiler directives
2. Preprocessor directives begin with #
3. Attributes (COM, IDL, compiler, .NET) are enclosed in [], e.g. [in]
* Attributes are Microsoft’s innovation, that just now has been standardized by ECMA
Preprocessor DefinitionsPreprocessor Definitions
#define can define a flow control entity:#define MYHEADER_H* Capitalize the name, use underscore to separate wordsa constant:#define MYHEADER_H#define M_PI 3.1415f* Capitalize the name, use underscore to separate wordsor a macro:#define MAX(a, b) ((a) > (b) ? (a) : (b))* Capitalize the name, enclose operands in parenthesis#undef undefines a previously defined entity:#undef M_PI#undef MAX#undef MYHEADER_H
Including FilesIncluding Files
#include#include "MyHeader.h"
#include <iostream>
* Name your include files .h
What’s appropriate for include files?
* Declarations, e.g. constants, external functions, classes, structures, macros, etc.
What’s inappropriate for include files?
* Code snippets, function bodies, class implementations, i.e. non-declarative code
Conditional CompilationConditional Compilation
#if / #ifdef / #ifndef - #else / #elif - #endif#ifndef MYHEADER_H#include "MyHeader.h"#elif MYHEADER_VERSION < 2#error MyHeader.h version 2 is required#else// Everything is OK#endif
Another example#ifdef DEBUGTRACE("Running in DEBUG mode");#endif
#ifdef NAME is equivalent to #if defined(NAME)
Including Files ProperlyIncluding Files Properly
In the header…#ifndef MYHEADER_H#define MYHEADER_H// Header declarations go here// …#endif
Alternatively in the header…#pragma once// Header declarations go here
In the code…#include <MyHeader.h>
Preprocessor AdvicePreprocessor Advice
• Use preprocessor to define literal constants, macros
• Conditional compilation with minimum effect is OK (e.g. debug vs. non-debug code)
• DO NOT use preprocessor to alter the program logic excessively, especially do not apply conditional compilation directives to large chunks of code
Separating C and C++Separating C and C++
1. There is no clear distinction between C and C++ as far as non-object oriented code is concerned
2. C++ and C coexist within the same source code domain
3. DO NOT mix C and C++ within the same source files
4. Always name pure C files .c as most compilers rely on .c extension to compile the file as C
C++ Source FilesC++ Source Files
•Header Files (Include Files): .h•Source Files: .cpp•No .c, .cxx, or .inl files•Source code files that are not exclusively definitions should NEVER be included
C++ Project OrganizationC++ Project Organization
•Keep you Visual Studio Projects Organized by grouping related files in subfolders (headers together, source files together, etc.)•Include ALL project files in the project•Disabling precompiled headers is a good idea for small projects
C++ Brush up: if-then-elseC++ Brush up: if-then-else
if ( !IsEmpty() )
{
// Do something
}
else
{
// Do something else
}
condition
C++ Brush up: for-loopsC++ Brush up: for-loops
for ( int i = 0; i < 100; i++ )
{
// Do something
}
initialization condition update
* Separate statements within the initialization, condition and update sections must be comma-separated.for ( int i = 0, j = 100; i < 100; i++,j-- )
{
// Do something
}
C++ Brush up: while-loopsC++ Brush up: while-loops
while ( !EOF )
{
// Do something
}
condition
Alternativelydo
{
// Do something
}
while ( !EOF )
C++ Brush up: switchC++ Brush up: switch
switch ( status ){ case 1: // Do something break; case 2: // Do something break; default:}
switch control expression•Do not rely on fall-through from one case statement to another•Always include the default case statement.
C++ Brush up: Primitive TypesC++ Brush up: Primitive Types
Data Type Range Bytes
char -128…127 1
unsigned char 0..255 1
short -32,768…32,767 2
unsigned short 0..65,535 2
int -2,147,483,648...2,147,483,647 4
unsigned int 0..4,294,967,295 4
long -21,47,483,648...21,47,483,647 4
unsigned long 0..4,294,967,295 4
long long ±18,446,744,073,709,551,616 8
bool true / false 1
wchar_t 0..65535 (Unicode character) 2
float ±1.175494351E–38f...3.402823466E+38f 4
double ±2.2250738585072014E–308…1.7976931348623158E+308
8
long double ±2.2250738585072014E–308…1.7976931348623158E+308
8
C++ Brush up: OperatorsC++ Brush up: Operators
Scope new Logical Inequality: !=
:: delete AND: && Assignment
Postfix Comma OR: || =
Subscript: [] , NOT: ! +=
Function call: () Arithmetic Bitwise -=
Cast: () Increment: ++ AND: & *=
Member Access: . Decrement: -- OR: | /=
Member Access: -> Multiplication: * XOR: ^ %=
Conditional Division: / One’s Complement: ~ <<=
? Modulus: % Equality >>=
Memory Addition: + Less than: < &=
Reference: & Subtraction: - Greater than: > ^=
Indirection: * Left shift: << Less than or eq.: <= !=
Address-of: & Right shift: >> Greater than or eq.: >=
sizeof Euality: ==
C++ Brush up: UDTsC++ Brush up: UDTs
User-Defind Types aka Complex Types:struct Rectangle{ int Width; int Height;};Alternativelytypedef struct{ int Width; int Height;} Rectangle;typedef char* PCHAR;Or you can use #define for the latter:#define PCHAR char*;But #define does not define type while typedef does!
C++ Brush up: Scope VisibilityC++ Brush up: Scope Visibility
All declarations in C++ exist within a scope they were defined in. There is a global scope and multiple local scopes defined by {}, e.g.// Global scope
int Age;
{
// Age is visible here
int NewAge;
}
// NewAge is not visible here
* Variables declared within the for-loop initialization block may or may not be visible outside the for-loop depending on the compiler settings!
C++ Brush up: NamespacesC++ Brush up: Namespaces
To avoid name collisions global-scope declarations can be grouped in namespaces:namespace USA;{ struct City;}namespace Russia;{ struct City;}// USA::City and Russia::City structures aren’t the same!
:: operator is used for dereferencing namespaces temporarily, e.g.:USA::City Washington;Russia::City Moscow;
using namespace declaration is used for dereferencing namespaces permanently, e.g.using namespace USA;City Washington; // USA::Washington is assumed
C++ Brush up: Stack & HeapC++ Brush up: Stack & Heap
By default UDTs and primitive types are allocated on stack, which means that the memory is released once the type instance goes out of scope.
In contrast heap represents a permanent storage on which types must be allocated manually using the new operator:MyType* pType = new MyType;The caveat is that the heap-allocated types must be removed manually when no longer needed using the delete operator:delete pType;pType = NULL; // A good practiceFailure to remember to delete heap-allocated types causes memory leaks.
C++ Brush up: Managed HeapC++ Brush up: Managed Heap
In order to avoid memory leaks “new” languages such as Java, C# and C++/CLI rely on autonomous garbage collector process to automatically release heap memory when it is no longer referenced by any object (and thus no longer needed).
Garbage collection offers convenience at the price of efficiency.
C++ Brush up: Memory RulesC++ Brush up: Memory Rules
Still we can avoid memory leaks in “native” C++ if we follow these simple rules:
1. Allocate your types on stack wherever you can.2. Always release temporary heap memory when the
referencing object goes out of scope.3. Always catch exceptions and release temporary
heap memory in the finally block.4. Use _alloca() Microsoft-specific memory allocation
routine (declared in malloc.h) that dynamically allocates memory on stack rather than on heap! alloca-allocated memory will be released automatically when the referencing type goes out of scope or when stack unwinds during the exception processing.
C++ Brush up: PointersC++ Brush up: Pointers
Pointers are a “necessary evil” of C++: C++ pointers can refer to any memory location and can be easily casted from one type to another.MyType* pType = new MyType;
Pointers can be obtained using the address-of operator:int MyValye = 100;int* pMyValue = &MyValue; *pMyValue = 200;
Pointers are a subject to pointer arithmetic:pMyValue++; // Increments pointer address(*pMyValue)++; // Increments the pointed-to value
Null pointers should be represented by NULL rather than 0.#define NULL 0 // Normally already defined
Use const pointers to avoid pointer address modifications:typedef int* PINT;const PINT pMyValue = &MyValue;pMyValue++; // Compile error, const pointer
Without the typedef const modifier DOES NOT define an immutable pointer:const int* pMyValue = &MyValue;pMyValue++; // OK(*pMyValue)++; // Compile error, const value
Always initialize pointers! NULL-value initilization is OK.
C++ Brush up: ReferencesC++ Brush up: References
References are pointers by nature but they do not require dereferencing (*), do not support straight casting into incompatible types, and do not allow pointer arithmetics.
References = safe pointers (kind of)int MyValye = 100;
int& pMyValue = &MyValue;
References cannot be uninitialized!
Use constant references, not pointers to pass UDTs by reference rather than by value:void MyFunction(const City& aCity);
Using constant references in parameters saves time and memory due to elimination of on-stack copy-construction (more on this later).
C++ Brush up: ArraysC++ Brush up: Arrays
C++ arrays are pointers:int Data[10]; // Array declaration
Data[0] = 1; // Element initialization
int* pData = Data; // type of Data is int*
Array Initialization:int Data[2] = {1, 2};
int Data[] = {1, 2}; // Rely on compiler to figure the array size
int Data[3][2] = {{1, 2}, {3, 4}, {5, 6}}; // 2D array
int* pData = Data[0]; // First row pointer
Dynamic allocation:int* pData = new int[32]; // 32-element array
C++ Brush up: StringsC++ Brush up: Strings
C++ arrays are zero-terminated arrays of characters (char or wchar_t depending on the environment:char MyName[50]; // ASCII string
char* YourName = "George"; // ASCII string
wchar_t* UnicodeName = L"UltraMax"; // Unicode
TCHAR* SmartName; // Microsoft's string can be
// ASCII or UNICODE
String functions (e.g. strcpy, strcmp, strcat, etc.) are grouped in string.h STD LIB.
string.h defines string template class (more on this later).
C++ Brush up: ExceptionsC++ Brush up: Exceptions
Key difference between C and C++ is no just classes but also exceptions. Exceptions simplify error handling by breaking sequential program execution.
C approach:
if ( MyFunc() == S_OK )
{
if ( MyFunc2() == S_OK )
{
if ( MyFunc3() == S_OK )
{
}
else
// Report error;
}
else
// Report error;
}
else
// Report error;
C++ approach:
try
{
MyFunc(); // May throw an exception
MyFunc2(); // May throw an exception
MyFunc3(); // May throw an exception
}
catch(...)
{
// Report error
}
__finally
{
// Post-processing (if any)
}
C++ Brush up: try-catch-finallyC++ Brush up: try-catch-finally
In C++ any type can be thrown, e.g.throw "Sample error";throws an exception of type char*.To catch an exception one must enclose the code within a try-catch block.try{ throw "Error occurred";}catch(char* Exception){ count << Exception; throw; // Pass the exception to another handler (optional)}__finally(){ // This block will always execute: with or without the exception}•You can catch exceptions of a specified type only or all types if you specify catch(…) block•You can have multiple catch-blocks for catching exceptions of different types•Microsoft-specific __finally blocks are VERY handy for performing exception post-processing (e.g. releasing heap-allocated memory, closing files, etc.)
C++ Brush up: StreamsC++ Brush up: Streams
C++ standard input stream: cin#include <iostream>void main(){ char* inputText; cin >> inputText;}C++ standard input stream: cout#include <iostream>void main(){ char* outText = "UltraMax"; cout << "I am " << outText;}
Assignment: Email ValidationAssignment: Email Validation
Task: Validate email address.
How?
Think about this problem and come up with a solution (i.e. an algorithm or process). Be as explicit and detailed as you possibly can. Write down your solution in English.