Bogotobogo
contact@bogotobogo.com
Small Programs - 2012
- C++ Home
- String
- Constructor
- Operator Overloading
- Virtual Functions
- Dynamic Cast Operator
- Type Cast Operators
- Class auto_ptr
- References for Built-in Types
- Pass by Value vs. Pass by Reference
- Memory Allocation
- Friend Functions and Friend Classes
- Functors (Function Objects)
- Static Variables and Static Class Members
- Exceptions
- Stack Unwinding
- Pointers
- Pointers II - void pointers & arrays
- Pointers III - pointer to function & multi-dimensional arrays
- Taste of Assembly
- Small Programs
- Linked List Examples
- Binary Tree Example Code
- Templates
- Standard Template Library (STL) I
- Standard Template Library (STL) II - Maps
- Standard Template Library (STL) III - Iterators
- Standard Template Library (STL) IV - Algorithms
- Object Slicing and Virtual Table
- The this Pointer
- Stack Unwinding
- Upcasting and Downcasting
- Object Returning
- Private Inheritance
- Preprocessor - Macro
- C++_Keywords
- fstream: input & output
- Multi-Threaded Programming - Terminology
- Multi-Threaded Programming II - Native Thread for Win32 (A)
- Multi-Threaded Programming II - Native Thread for Win32 (B)
- Multi-Threaded Programming II - Native Thread for Win32 (C)
- Multi-Threaded Programming II - C++ Thread for Win32
- Multi-Threaded Programming III - C++ Class Thread for Pthreads
- Multithread Debugging
- Socket - Server & Client
- Embedded Systems Programming
- Boost
- make
- Debugging Crash & Memory Leak
- Libraries
- C++ API Testing
- Design Patterns in C++
- Algorithms in C++
- Programming Questions and Solutions
- Blackjack with Qt
- Counting Bits in an Unsigned Integer
- int strlen(const char *)
- char* strcpy(char *, const char*)
- char* strdup(char *)
- void * memcpy ( void * destination, const void * source, size_t sz)
- void *memmove(void *dest, const void *src, size_t sz)
- void * memset ( void * destination, int source, size_t sz )
- Converting String to Integer (atoi())
- Converting Integer to String (itoa())
- ASCII String to Float - atof()
- Reversing a String
- Finding the First Un-repeating (Non-repeating) Character - A
- Finding the First Un-repeating (Non-repeating) Character - B
- Binary Search A
- Binary Search B - Recursive
- Big endian or Little endian
- Hash Table Based on K & R
- Calculator Based on K & R
- Size of struct
- Removing Left Space of a String
Computing the number of 1-bits in an unsigned integer:
/* Counting the Bit Set for an Unsigned Integer */
/*
(A) Loop through all the bits
Computing time is proportional to the number of bits
(B) Computing time is proportional to the number of bits set
*/
#include <iostream>
using namespace std;
/* bit count for unsigned integer */
/* checking if the first bit == 1 while shifting right
(25)
11001 -> 1100 -> 110 -> 11 -> 1
*/
int bit_countA(unsigned int n){
int count = 0;
while(n) {
count += n & 0x1u;
n >>= 1;
}
return count;
}
/* sets the right most bit set 1 to 0 */
/* Computing time is proportional to the number of bits set */
int bit_countB(unsigned int n) {
int count = 0;
while(n) {
count ++;
n &= n - 1;
}
return count;
}
int main()
{
/* 25 (11001) */
unsigned int num = 25;
cout << num <<": # of bits set (A) is " << bit_countA(num) << endl;
cout << num <<": # of bits set (B) is " << bit_countB(num) << endl;
return 0;
}
strlen() counts just the visible characters and not the null character.
int strlen1(const char *s) {
int n=0;
while (*s++) n++;
return(n);
}
int strlen2(const char *s) {
int n=0;
while (s[n]) n++;
return(n);
}
char* strcpy1(char s1[], const char s2[]) {
for(int i=0; i <=strlen(s2); i++) {
s1[i] = s2[i];
}
return s1;
}
char* strcpy2(char *s1, const char *s2) {
char *p = s1;
while(*s2!='\0') {
*s1 = *s2;
s1++;
s2++;
}
*s1 = '\0';
return p;
}
char* strcpy3(char *s1, const char *s2) {
char *p = s1;
while(*s2) *s1++ = *s2++;
*s1 = '\0';
return p;
}
char* strcpy4(char *s1, const char *s2) {
char *p = s1;
while(*s1++ = *s2++);
return p;
}
char* strcpy5(char *s1, const char *s2) {
int i = 0, j = 0;
while(s1[i++] = s2[j++]);
return s1;
}
strdup() does dynamic memory allocation for the character array including the end character '\0' and returns the address of the heap memory:
char *strdup (const char *s) {
char *p = malloc (strlen (s) + 1); // allocate memory
if (p != NULL)
strcpy (p,s); // copy string
return p; // return the memory
}
So, what it does is give us another string identical to the string given by its argument, without requiring us to allocate memory. But we still need to free it, later.
Copy block of memory
Copies the values of sz bytes from the location pointed by source directly to the memory block pointed by destination.
The underlying types of the objects pointed by both the source and destination pointers are irrelevant for this function;
The result is a binary (bit pattern) copy of the data.
The function does not check for any terminating null character in source - it always copies exactly sz bytes.
The behavior of memcpy() is undefined if source and destination overlap.
#include <iostream>
using namespace std;
void *memcpy( void *destination, const void *source, size_t sz ) {
char *dest = (char *)destination;
char const *src = (char *)source;
while (sz--)
*dest++ = *src++;
return destination;
}
int main()
{
char src1[] = "Ludwig Van Beethoven";
char *src2 = "Franz Liszt ";
char dest[40];
cout << "src 1: " << src1 << endl;
memcpy(dest,src1, strlen(src1)+1);
cout << "dest: " << dest<< endl;
cout << "src 2: " << src2 << endl;
memcpy(dest,src2, strlen(src2)+1);
cout << "dest: " << dest<< endl;
return 0;
}
Output is:
src 1: Ludwig Van Beethoven dest: Ludwig Van Beethoven src 2: Franz Liszt dest: Franz Liszt
Memmove() copies n bytes between two memory areas; unlike with memcpy() the areas may overlap. Actually, it is a variant of memcpy() that allows the source and destination block to overlap; otherwise it is equivalent (but slightly slower).
#include <iostream>
using namespace std;
void *memcpy(void *dest, const void *src, size_t sz)
{
char *tmp = (char *)dest;
char *s = (char *)src;
while(sz--) {
*tmp++ = *s++;
}
return dest;
}
void *memmove(void *dest, const void *src, size_t sz)
{
char *tmp, *s;
if (dest <= src) {
tmp = (char *) dest;
s = (char *) src;
while (sz--)
*tmp++ = *s++;
}
else {
tmp = (char *) dest + sz;
s = (char *) src + sz;
while (sz--)
*--tmp = *--s;
}
return dest;
}
int main()
{
char src[50] = "Einstein was a very nice person!";
cout << src << endl;
memmove(src + 20, src + 15, 17);
cout << src << endl;
return 0;
}
Output is:
Einstein was a very nice person! Einstein was a very very nice person!
Sets the first sz bytes of the block of memory pointed by destination to the specified source (interpreted as an unsigned char).
#include <stdio.h>
#include <string.h>
void *MyMemset(void* destination, int source, size_t sz)
{
char *pt = (char *)destination;
while(sz--) {
*pt++ = (unsigned char)(source);
}
return destination;
}
int main()
{
char str1[] = "What the heck is memset?";
char str2[] = "What the heck is memset?";
memset(str1 + 5, '*',8);
puts(str1);
MyMemset(str2 + 5, 'x',8);
puts(str2);
return 0;
}
Output is:
What ******** is memset? What xxxxxxxx is memset?
example A
#include <sstream>
int str2intA(const string &str) {
stringstream ss(str);
int n;
ss >> n;
return n;
}
example B
int str2intB(const string &str){
int n = 0;
int len =str.length();
for(int i = 0; i < len; i++) {
n *= 10;
n += str[i]-'0';
}
return n;
}
example A
#include <sstream>
string int2strA(int n) {
stringstream ss;
ss << n;
return ss.str();
}
example B
string int2strB(int numb) {
int i=0;
int end=10;
char* temp = new char[end];
//store one digit at a time
for(i = 0; numb > 0; i++) {
temp[i] = (numb % 10) + '0';
numb /= 10;
}
// temp has the number in reverse order
int len = i;
int ii = 0;
string s = new char[len];
while(i > 0) s[ii++] = temp[--i];
s.erase(len);
delete temp;
return s;
}
example C
#include <iostream>
#include <cstring>
using namespace std;
// reverse the string
void reverse(char *s)
{
int sz = strlen(s);
char c;
int i, j;
for(i = 0, j = sz -1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
// itoa
void int2strC(int n, char *s)
{
int i = 0;
while( n ) {
s[i++] = n % 10 + '0';
n /= 10;
}
s[i] = '\0';
cout << "before the reverse s = " << s << endl;
reverse(s);
}
int main()
{
char s[10];
int n = 987654321;
cout << "input n = " << n << endl;
int2strC(n, s);
cout << "output s = " << s << endl;
return 0;
}
Output from the run:
input n = 987654321 before the reverse s = 123456789 output s = 987654321
#include <iostream>
using namespace std;
double atofA(char s[])
{
double d = 0, power = 1;
int sign = 1;
int i = 0;
if(s[i] == '-' ) sign = -1;
i++;
while(s[i]) {
if(s[i] == '.') break;
d = d * 10 + (s[i] - '0');
i++;
}
i++;
power = 0.1;
while(s[i]) {
d += (s[i] - '0')*power;
power /= 10.0;
i++;
}
return d*sign;
}
int main()
{
double d = atofA("-314.1592");
cout.precision(7);
cout << d << endl;
return 0;
}
Example A
#include <iostream>
#include <cstring>
void reverse_string(char s[]) {
int i,j,c;
for(i = 0, j = strlen(s)-1; i < j ; i++, j-- ) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
int main() {
char s[] ="reverse me";
reverse_string(s);
std::cout << s << std::endl;
return 0;
}
Example B Printing a String Reversed
Here we have two print functions, one for normal and the other one for printing a string in reverse.
#include <iostream>
using namespace std;
void normalPrint(char *s)
{
if(*s) {
putchar(*s);
normalPrint(s+1);
}
}
void reversePrint(char *s)
{
if(*s) {
reversePrint(s+1);
putchar(*s);
}
}
int main()
{
char *str = "Normal or Reverse";
normalPrint(str);
cout << endl;
reversePrint(str);
cout << endl;
return 0;
}
Output is:
Normal or Reverse esreveR ro lamroN
This code is using map.
- Put all characters into a map.
- If necessary (repeated), it will increment a counter which is the 2nd component of map, value.
- Then, traverse the string and search the map. If found and counter value is 1, return that character.
- Complexity: traversing (O(N)), searching balanced binary tree (O(log(N)) => O(N + log(N)) => O(N)
// Returning a character which is the first non-repeated in a string
#include <iostream>
#include <string>
#include <map>
using namespace std;
char find(string s)
{
map<char,int> myMap;
int len = s.length();
for(int i = 0; i < len; i++) ++myMap[s[i]];
for(int i = 0; i < len; i++)
if(myMap.find(s[i])->second == 1) return s[i];
return 0;
}
int main()
{
string s="abudabi";
cout << find(s);
return 0;
}
This method is using simple array utilizing the inversion of character and integer.
Complexity: O(N) - It needs just two traversing.
// Returning a character which is the first non-repeated in a string
#include <iostream>
#include <string>
using namespace std;
char find(string s)
{
int myArr[256] = {0};
int len = s.length();
for(int i = 0; i < len; i++)
myArr[static_cast<int>(s[i])]++;
for(int i = 0; i < len; i++)
if(myArr[static_cast<int>(s[i])] == 1) return s[i];
return 0;
}
int main()
{
string s="abudabi";
cout << find(s);
return 0;
}
#include <iostream>
using namespace std;
int bsearch(int [], int, int, int);
int main()
{
const int arrSize = 100;
int arr[arrSize];
for (int i = 0; i <= arrSize -1; i++) {
arr[i] = i;
}
int x = 35;
int low = 0;
int high = arrSize -1;
int found = bsearch(arr, x, low, high);
if(found == -1) {
cout << "Could not find " << x << endl;
return 0;
}
cout << "The value " << x << " is at " << found << endl;
return 0;
}
int bsearch(int arr[], int x, int low, int high) {
int mid;
if(high < low) return -1; // no match
while (low <= high) {
mid = low + (high - low) / 2;
if(x < arr[mid])
high = mid - 1;
else if (x > arr[mid])
low = mid + 1;
else
return mid; // this is match
}
}
int bsearch(int arr[], int x, int low, int high) {
int mid;
if(high < low) return -1; // no match
mid = low + (high - low) / 2;
if(x < arr[mid])
bsearch(arr, x, low, mid - 1);
else if (x > arr[mid])
bsearch(arr, x, mid + 1, high);
else
return mid; // this is match
}
Endian is important to know when reading or writing data structures, especially across networks so that different application can communicate with each other. Sometimes the endianness is hidden from the developer. Java uses a fixed endianness to store data regardless of the underlying platform's endianness, so data exchanges between two Java applications won't normally be affected by endianness. But other languages, C in particular don't specify an endianness for data storage, leaving the implementation free to choose the endianness that works best for the platform.
On big-endian (PowerPC and SPARC), the 32-bit value x01234567 is stored as four bytes 0x01, 0x23, 0x45, 0x67, while on little-endian (Intel x86), it will be stored in reverse order.
The picture below is a diagram for the example to check if a machine is little endian or big endian. The box shaded blue is the the byte we are checking because it's where a one-byte type (char) will be stored. The diagram shows where an integer (4-byte) value 1 is stored.
We can distinguish between the LSB and the MSB because the value 1 as an integer, has the value of 1 for LSN, and the value of 0 for MSB.
Note that a little endian machine will place the 1 (0001x, LSB) into the lowest memory address location. However, a big endian machine will put 0 (0001x, MSB) into the lowest memory address location.
Source A
#include <iostream>
using namespace std;
/* if the dereferenced pointer is 1, the machine is little-endian
otherwise the machine is big-endian */
int endian() {
int one = 1;
char *ptr;
ptr = (char *)&one;
return (*ptr);
}
int main()
{
if(endian())
cout << "little endian\n";
else
cout << "big endian\n";
}
Source B
#include <iostream>
using namespace std;
int endian() {
union {
int one;
char ch;
} endn;
endn.one = 1;
return endn.ch;
}
int main()
{
if(endian())
cout << "little endian\n";
else
cout << "big endian\n";
}
It is tempting to use bit operation for this problem. However, bit shift operator works on integer, not knowing the internal byte order, and that property prevents us from using the bit operators to determine byte order.
#include <iostream> using namespace std; #includeusing namespace std; #define HASHSIZE 101 struct nlist { /* table entry: */ struct nlist *next; /* next entry in chain */ char *name; /* defined name */ char *defn; /* replacement text */ }; static struct nlist *hashtab[HASHSIZE]; unsigned hash_function(char *s) { unsigned hashval; for (hashval = 0; *s != '\0'; s++) hashval = *s + 31 * hashval; return hashval % HASHSIZE; } struct nlist *lookup(char *s) { struct nlist *np; for (np = hashtab[hash_function(s)]; np != NULL; np = np->next) if (strcmp(s, np->name) == 0) return np; /* found */ return NULL; /* not found */ } /* install: put (name, defn) in hashtab */ struct nlist *install(char *name, char *defn) { struct nlist *np; unsigned hashval; if ((np = lookup(name)) == NULL) { /* not found */ np = new nlist; if (np == NULL || (np->name = _strdup(name)) == NULL) return NULL; hashval = hash_function(name); np->next = hashtab[hashval]; hashtab[hashval] = np; } else /* already there */ /*free previous defn */ delete np->defn; if ((np->defn = _strdup(defn)) == NULL) return NULL; return np; } /* uninstall: take (name, defn) out of hashtab */ int undef(char * name) { struct nlist * np1; /* name not found */ if ((np1 = lookup(name)) == NULL) return 1; /* name found */ if((np1 = hashtab[hash_function(name)]) != NULL ) { hashtab[hash_function(name)] = np1->next; delete np1; return 0; } /* name not found */ return 1; } void print() { struct nlist *np; for(int i = 0; i < HASHSIZE; i++) { np = hashtab[i]; if(np) cout << np->name << "-->" << np->defn << " "; } cout << endl; } int main() { install("A","65"); install("B","66"); install("C","67"); install("D","68"); install("E","69"); print(); undef("C"); print(); undef("B"); print(); return 0; }
Output from the run:
A-->65 B-->66 C-->67 D-->68 E-->69 A-->65 B-->66 D-->68 E-->69 A-->65 D-->68 E-->69
/* Calculator based on K & R
(1) Not working for '(' such as 1+(5-3)
(2) Added
getop(s);
push(a2f(s));
after '+', '-', '*', and '/' to push next number
*/
#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;
int getop(char []);
void push(double);
double pop(void);
int getch(void);
void ungetch(int);
int a2f(char *);
void calc();
int main()
{
calc();
return 0;
}
const int MAXOP = 100;
const char NUMBER = '0';
void calc() {
int type;
double op2;
char s[MAXOP];
while((type = getop(s)) != EOF) {
switch (type) {
case NUMBER:
push(a2f(s));
break;
case '+':
getop(s);
push(a2f(s));
push(pop() + pop());
break;
case '*':
getop(s);
push(a2f(s));
push(pop() * pop());
break;
case '-':
getop(s);
push(a2f(s));
op2 = pop();
push(pop()-op2);
break;
case '/':
getop(s);
push(a2f(s));
op2 = pop();
if(op2 != 0.0)
push(pop() / op2);
else
cout << "error: division by zero" << endl;
break;
case '\n':
cout << pop() << endl;
break;
default:
cout << "error: unknown command " << s << endl;
}
}
}
// getop(): get next operator or numeric operand
int getop(char s[]) {
int i, c;
while ( (s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if( !isdigit(c) && c != '.')
return c; // not a number
i = 0;
if (isdigit(c)) // collect integer part
while (isdigit(s[++i] = c = getch()))
;
if (c == '.') // collect fraction
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF )
ungetch(c);
return NUMBER;
}
const int BUFSIZE = 100;
char buf[BUFSIZE];
int bufp = 0;
int getch(void) {
return (bufp > 0) ? buf[--bufp] : cin.get();
}
void ungetch(int c) {
if (bufp >= BUFSIZE)
cout << "ungetch(): too many characters\n";
else
buf[bufp++] = c;
}
int a2f(char *s) {
int n = 0;
while(*s) {
n *= 10;
n += (*s++)-'0';
}
return n;
}
const int MAXVAL = 100;
int sp = 0;
double val[MAXVAL];
void push(double f) {
if( sp < MAXVAL )
val[sp++] = f;
else
cout << "error: stack full, can't push "<< f << endl;
}
double pop(void) {
if (sp > 0)
return val[--sp];
else {
cout << "error: stack empty \n";
return 0.0;
}
}
How do we find the number of structures for the given array of structures in the sample code below?
#include <iostream>
using namespace std;
struct vehicle
{
int price;
char type[10];
} car[] =
{
{1,"a"},{2,"b"},{3,"c"}
};
int main()
{
cout << "sizeof(car)=" << sizeof(car) << endl;
cout << "sizeof(*car)=" << sizeof(*car) << endl;
cout << "sizeof(car)/sizeof(*car)=" << sizeof(car)/sizeof(*car) << endl;
return 0;
}
Answer is:
sizeof(car)=48 sizeof(*car)=16 sizeof(car)/sizeof(*car)=3
Note that the size of an array of vehicle struct is not 4+1*10 but 16. This is probably due to padding/allignmment:
4 + 1*4 + 1*4 + (1*2+2) = 16
As an exercise, how about the following example:
struct StructA
{
char ch1;
char ch2;
int n;
};
struct StructB
{
char ch1;
int n;
char ch2;
};
int sizeA = sizeof(StructA); // sizeA = 1 + 1 + (2-padding) + 4 = 8
int sizeB = sizeof(StructB); // sizeB = 1 + (3-padding) + 4 + 1 + (3-padding) = 12
Remember, it is frequently very difficult to predict the sizes of compound datatypes such as a struct or union due to structure padding. Another reason for using sizeof is readability.
#include <iostream>
#include <cassert>
using namespace std;
char *left_space_trim(char *buf, const char *s) {
assert(buf != NULL);
assert( s!= NULL);
while(isspace(*s))
s++;
strcpy(buf,s);
return buf;
}
int main()
{
char *srcStr = strdup(" String with left_side spaces");
char *dstStr = (char*)malloc(strlen(srcStr)+1);
cout << srcStr << "=>" << left_space_trim(dstStr,srcStr) << endl;
return 0;
}
Output is:
String with left_side spaces=>String with left_side spaces
It is also called OBB/OBB (Oriented Bounding Box) Intersection problem. Here, a brute force method will be presented first, and the other one (separating axes approach) which seems more elegant will come later time.
#include <iostream>
class Point
{
public:
Point(float a, float b):x(a),y(b){}
float getX() {return x;}
float getY() {return y;}
private:
float x, y;
};
class Rect
{
public:
Rect(Point a, Point b):ul(a),lr(b){}
float getHeight() {return ul.getY()-lr.getY();}
float getWidth() {return lr.getX()-ul.getX();}
float getXmin() {return ul.getX();}
float getXmax() {return lr.getX();}
float getYmin() {return lr.getY();}
float getYmax() {return ul.getY();}
private:
Point ul,lr;
};
bool overlapped(Rect &r1, Rect &r2)
{
float height1 = r1.getHeight();
float height2 = r2.getHeight();
float width1 = r1.getWidth();
float width2 = r2.getWidth();
// case A: No corners inside
if(r1.getWidth() >= r2.getWidth()) {
if(r2.getXmin() >= r1.getXmin() && r2.getXmax() <= r1.getXmax()
&& r2.getYmin() <= r1.getYmin() && r2.getYmax() >= r1.getYmax() )
return true;
}
else {
if(r1.getXmin() >= r2.getXmin() && r1.getXmax() <= r2.getXmax()
&& r1.getYmin() <= r2.getYmin() && r1.getYmax() >= r2.getYmax() )
return true;
}
// case B: r2's corner inside r1 rect? (compare r1 with r2)
// r2's ul (Xmin, Ymax)
if(r1.getXmin() <= r2.getXmin() && r1.getXmax() >= r2.getXmin()
&& r1.getYmax() >= r2.getYmax() && r1.getYmin() <= r2.getYmax() )
return true;
// r2's ur (Xmax, Ymax)
if(r1.getXmin() <= r2.getXmax() && r1.getXmax() >= r2.getXmax()
&& r1.getYmax() >= r2.getYmax() && r1.getYmin() <= r2.getYmax() )
return true;
// r2's ll (Xmin, Ymin)
if(r1.getXmin() <= r2.getXmin() && r1.getXmax() >= r2.getXmin()
&& r1.getYmax() >= r2.getYmin() && r1.getYmin() <= r2.getYmin() )
return true;
// r2's lr (Xmax, Ymin)
if(r1.getXmin() <= r2.getXmax() && r1.getXmax() >= r2.getXmax()
&& r1.getYmax() >= r2.getYmin() && r1.getYmin() <= r2.getYmin() )
return true;
return false;
}
int main()
{
float x1 = 0.0, y1 = 5.0, x2 = 5.0, y2 = 0.0;
float x3 = 4.0, y3 = 1.0, x4 = 6.0, y4 = -1.0;
Point pt1(x1,y1), pt2(x2,y2);
Point pt3(x3,y3), pt4(x4,y4);
Rect rta(pt1,pt2);
Rect rtb(pt3,pt4);
if(overlapped(rta,rtb))
std::cout << "Overlapped: " << std::endl;
else
std::cout << "Not overlapped: " << std::endl;
return 0;
}
- C++ Home
- String
- Constructor
- Operator Overloading
- Virtual Functions
- Dynamic Cast Operator
- Type Cast Operators
- Class auto_ptr
- References for Built-in Types
- Pass by Value vs. Pass by Reference
- Memory Allocation
- Friend Functions and Friend Classes
- Functors (Function Objects)
- Static Variables and Static Class Members
- Exceptions
- Stack Unwinding
- Pointers
- Pointers II - void pointers & arrays
- Pointers III - pointer to function & multi-dimensional arrays
- Taste of Assembly
- Small Programs
- Linked List Examples
- Binary Tree Example Code
- Templates
- Standard Template Library (STL) I
- Standard Template Library (STL) II - Maps
- Standard Template Library (STL) III - Iterators
- Standard Template Library (STL) IV - Algorithms
- Object Slicing and Virtual Table
- The this Pointer
- Stack Unwinding
- Upcasting and Downcasting
- Object Returning
- Private Inheritance
- Preprocessor - Macro
- C++_Keywords
- fstream: input & output
- Multi-Threaded Programming - Terminology
- Multi-Threaded Programming II - Native Thread for Win32 (A)
- Multi-Threaded Programming II - Native Thread for Win32 (B)
- Multi-Threaded Programming II - Native Thread for Win32 (C)
- Multi-Threaded Programming II - C++ Thread for Win32
- Multi-Threaded Programming III - C++ Class Thread for Pthreads
- Multithread Debugging
- Socket - Server & Client
- Embedded Systems Programming
- Boost
- make
- Debugging Crash & Memory Leak
- Libraries
- C++ API Testing
- Design Patterns in C++
- Algorithms in C++
- Programming Questions and Solutions
- Blackjack with Qt