Tuesday, April 17, 2018

unique_ptr to Save the Day

#include <iostream>
#include <memory>
#include<time.h>

void processElements(std::unique_ptr<int[]> &, int);

int main(int argc,char *args[]){
    int elements;
    srand(time(0));
    do{
    std::cout<<"Enter the number of items you'd like to store: ";
    std::cin>>elements;
    if(!std::cin){
        std::cin.clear();
    std::cin.ignore(50,'\n');
    }
    else
        continue;
    }while(elements<1);

    std::unique_ptr<int[]> values(new int[elements]);

    for (int i = 0; i < elements; ++i) {
        values[i] = (i == 0) ? 1 : rand()%10+1;
    }

    for (int i = 0; i < elements; ++i) {            //before function call
        std::cout << i << ": " << values[i] << '\n';
    }
    processElements(values,elements);
    for (int i = 0; i < elements; ++i) {            //after function call
        std::cout << i << ": " << values[i] << '\n';
    }

    return 0;
}

void processElements(std::unique_ptr<int[]> &toProcess, int size){
    srand(time(0));
        for (int i = 0; i < size; ++i) {
        toProcess[i] = (i == 0) ? 1 : rand()%10+1;
    }

    for (int i = 0; i < size; ++i) {
        std::cout << i << ": " << toProcess[i] << '\n';
    }
}

Monday, April 16, 2018

Pointers the evil problems

Errors in code to fix  - don't cheat, but the answer is also on this page.  Try to use your debugger to isolate and to locate the errors.  Copy/paste this code and find the problems.

#include <iostream>
using namespace std;

int main(int argc, char **args){
    int *ptr, *current;
    const int SIZE = 5;
    ptr = new int[SIZE];
    int value[SIZE];
    ptr = current = value;

    for (int i = 0; i <= SIZE; i++)
        value[i] = i * 2;
    for (int i = 0; i < SIZE; i++) {
        cout << *ptr << endl;
        ptr++;
    }

    cout << *(--ptr) << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << *current << endl;
        current++;
    }
  
    cout << *(ptr) << endl;
    cout << *(--current) << endl;

    for (int i = 0; i <= SIZE; i++)
        *(ptr++) = i * 2;
  
    for (int i = 0; ptr <= &value[SIZE - 1]; ptr += 1)
        *ptr = i++ * 2;
    ptr--;
    cout << "The value where pointer 'ptr' pointing to is:  " << *ptr << endl;
  
    return 0;
}







Solution
#include <iostream>
using namespace std;

int main(int argc, char **args) {
    int *ptr, *current;
    const int SIZE = 5;
    ptr = new int[SIZE];
    int value[SIZE];
    ptr = current = value;

    for (int i = 0; i < SIZE; i++)
        value[i] = i * 2;
    for (int i = 0; i < SIZE; i++) {
        cout << *ptr << endl;
        ptr++;
    }
   
    cout << *(--ptr) << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << *current << endl;
        current++;
    }
   
    cout << *(ptr) << endl;
    cout << *(--current) << endl;
    ptr = value;                    //fix 2 - reset ptr to base address
    for (int i = 0; i < SIZE; i++)  //fix 3 - invalid index value
        *(ptr++) = i * 2;
   
   
    for (int i = 0; ptr <= &value[SIZE - 1]; ptr += 1)
        *ptr = i++ * 2;
    ptr--;
    cout << "The value where pointer 'ptr' pointing to is:  " << *ptr << endl;

    return 0;
}

Vector passing to function by reference and by pointer

#include<vector>
#include<iostream>

using namespace std;

bool setValues(vector<int> &base, vector<int> &compare);
bool setValues(vector<int> *base, vector<int> *compare);

int main(){
    vector<int> vect1;
    vector<int> vect2;
    vect1.push_back(10);
    vect1.push_back(20);
    vect1.push_back(30);

    if (setValues(vect1, vect2))
        cout << "They are equal" << endl;
    else
        cout << "They are not equal" << endl;

    if (setValues(&vect1, &vect2))
        cout << "They are equal" << endl;
    else
        cout << "They are not equal" << endl;


    for (int value:vect1)
        cout << value << " ";

    return 0;
}
bool setValues(vector<int> &base, vector<int> &compare) {
    bool isEqual = true;
    compare.push_back(10);
    compare.push_back(20);
    compare.push_back(30);
    for (int i = 0; i < base.size();i++) {
        if (base.at(i) != compare.at(i))
            return false;
    }
}

bool setValues(vector<int> *base, vector<int> *compare) {
    bool isEqual = true;
    (*compare).push_back(10);
    (*compare).push_back(20);
    (*compare).push_back(30);
    for (int i = 0; i < (*base).size(); i++) {
        if ((*base).at(i) != (*compare).at(i))
            return false;
    }
}

Monday, April 9, 2018

C++ and vector dynamic expansion



How Does the capacity changes as the size increases?  Well, this simple test code and chart will clear up the questions.

// This program demonstrates the vector size member function.
#include <iostream>
#include <vector>
#include<cmath>
#include<fstream>
 
using namespace std;
 
int main() {
 ofstream outFile;
 outFile.open("c:\\temp\\analysis.csv");
 vector<int> values;
 cout << typeid(values).name() << endl;
 outFile << "size, capacity, diff, count" << endl;
 // Put a series of numbers in the vector.
 for (int count = 0; count < 20; count++) {
  values.push_back(count * 2);
  outFile << values.size() << "," << values.capacity() << ","
   << abs((int)(values.size() - values.capacity()))
   << "," << count << endl;
 }
 vector<int> temp;
 for (int i : values)         //even copying based on size value will increment capacity beyond size  
  temp.push_back(i);
 values.shrink_to_fit();     //size will match capacity
 outFile.close();
 return 0;
}



This same kind of effect can be observed with string as well.


// This program demonstrates the vector size member function.
#include <iostream>
#include <vector>
#include<cmath>
#include<fstream>
#include<string>
 
using namespace std;
 
int main() {
 ofstream out("c:\\temp\\out.csv");
 string item = "a";
 out << "count,size,capacity" << endl;
 cout <<"1,"<<item.size() << "," << item.capacity() << "," << endl;
 for (int i = 2; i < 1000; i++) {
  item += "a";
  out <<i<<"," << item.size() << "," << item.capacity() << "," << endl;
 }
 out.close();
 return 0;
} 
 
 

Thursday, July 6, 2017

Simple Summary of Typedef, Array, function, C-String concepts

Run this code in your IDE using breakpoints and monitor every variable as you progress.

#include<iostream>
#include<iomanip>
#include<string>

using namespace std;

enum colors { BLUE, WHITE, RED, GREY };
enum models { TOYOTA, FORD, CHEVY, NISSAN };
typedef int zoltan[4][4];

void print(const zoltan cars);
void print(const int favoriteColors[], colors = BLUE);
void initialize(int cars[][4]);
void initialize(int favoriteColors[]);
void printByRow(const zoltan cars, int row);
void printByCol(const zoltan cars, int col);
int sumByRow(const zoltan cars, int row);
int sumByCol(const zoltan cars, int col);
void parallelArrayPrint(string names[], int items[], float prices[], char codes[],int size);

void cStringExercise();

int main() {
    int favoriteColors[4];
    zoltan cars;

    initialize(cars);
    initialize(favoriteColors);
    printByRow(cars, models::CHEVY);
    printByCol(cars, colors::RED);
    cout << sumByRow(cars, models::CHEVY) << endl;
    cout << sumByCol(cars, colors::RED) << endl;
    cStringExercise();
    string names[] = { "Joe","Bob","Sam","Jane" };
    int items[] = {3,5,2,7};
    float prices[] = {23,34,45,56};
    char codes[] = {'A','B','C','D'};
    parallelArrayPrint(names,items,prices,codes,4);
    return 0;
}

void initialize(int favoriteColors[]) {
    int i = 0;
    for (colors c = BLUE; c <= colors::GREY; c = static_cast<colors>(c + 1)) {
        favoriteColors[c] = i++;
    }
}

void initialize(int cars[][4]) {
    for (int row = 0; row <= colors::GREY; row++)
        for (int col = 0; col <= models::NISSAN; col++)
            cars[row][col] = row*col;
}

void print(const int favoriteColors[], colors c) {
    for (; c <= colors::GREY; c = static_cast<colors>(c + 1)) {
        cout << setw(3) << favoriteColors[c];
    }
    cout << endl;
}

void print(const zoltan cars) {
    for (int row = 0; row <= colors::GREY; row++) {
        for (int col = 0; col <= models::NISSAN; col++)
            cout << setw(3) << cars[row][col];
        cout << endl;
    }
}

void printByRow(const zoltan cars, int row) {
    for (int col = 0; col <= models::NISSAN; col++)
        cout << setw(3) << cars[row][col];
    cout << endl;
}

void printByCol(const zoltan cars, int col) {
    for (int row = 0; row <= models::NISSAN; row++)
        cout << setw(3) << cars[row][col];
    cout << endl;
}

int sumByRow(const zoltan cars, int row) {
    int total = 0;
    for (int col = 0; col <= models::NISSAN; col++)
        total += cars[row][col];
    return total;
}

int sumByCol(const zoltan cars, int col) {
    int total = 0;
    for (int row = 0; row <= models::NISSAN; row++)
        total += cars[row][col];
    return total;
}

void cStringExercise() {
    string names[] = { "Joe","Bob","Sam","Jane" }; //just to see that a one dimensional string array is a two dimensional char array
    char names2[4][4];
    cin >> names2[0];
    cin >> names2[1];
    cin >> names2[2];
    cin >> names2[3];
    cout << names2[0] << endl;
    cin.ignore(100,'\n');
    //what's wrong with this?
    cin.get(names2[0], 4);
    cin.ignore(100, '\n');
    cin.get(names2[1], 4);
    cin.ignore(100, '\n');
    cin.get(names2[2], 4);
    cin.ignore(100, '\n');
    cin.get(names2[3], 4);
    cin.ignore(100, '\n');
    cout << names2[0] << endl;
}

void parallelArrayPrint(string names[],int items[], float prices[], char codes[],int size) {
    cout << showpoint << fixed << setprecision(2);
    for (int index = 0; index < size; index++) {
        cout <<setw(6)<< names[index] << ", you have purchased " << items[index] << " items that costs $" <<setw(7)<< prices[index] * items[index] << " item code: " << codes[index] << endl;

}

}

Monday, January 23, 2017

Code::Block and MinGW

Quick getting started guide video: https://youtu.be/86xvFbCHPvo

You have to consider the IDE that you will chose to use in your journey of learning.  You need to consider the programming languages that are used today in order to pick an IDE that will support most of the languages. 

Installing an IDE does not guarantee that you will have all the components that you will need. The compiler and the debugger can be chosen by personal preference as separate components. 

So, when evaluating an IDE, consider all these components and do not look at an IDE like it must have everything right "out of the box". 

In this case, Code::Block is the interface that allows you to enter the source code and MinGW provides the facility to GNU GCC compiler and GDB debugger in a separate install.

Friday, November 18, 2016

Array, Enum, Function, Typedef



In this example, we have everything we learned in chapters 7 and 8. 

You should have the breakpoints set as shown below and run the code in debugger to visualize how the array is filled and how it is processed one element at a time.

 

#include<iostream>
#include<time.h>
#include<string>
#include<iomanip>

using namespace std;

namespace zoltan{
    enum models{ TOYOTA, FORD, CHEVY, MAZDA, PORSCHE };
    enum colors{ RED, YELLOW, BLUE, BLACK };
    typedef int dealerships[PORSCHE + 1][BLACK + 1];
}
using namespace zoltan;

void fillArray(int [][BLACK+1]);
int totalColor(dealerships,colors);
int totalModel(dealerships,models);
string decodeColor(colors);
string decodeModel(models);

int main(){
    cout << "Hello Enum based Arrays" << endl;
    int dealership[5][4] = { { 2, 3, 4, 5  },
                           { 3, 4, 5, 6  },
                           { 5, 6, 7, 8  },
                           { 7, 8, 9, 10 },
                           { 1, 2, 3, 4  } };
    zoltan::dealerships richland;
    fillArray(richland);
    int color=totalColor(dealership,BLUE);
    int model=totalModel(richland,PORSCHE);
  
    cout << setw(11) << " ";
    for (colors col = RED; col <= BLACK; col = static_cast <zoltan::colors>(col + 1))
        cout <<setw(8)<< decodeColor(col);
    cout << endl;

    for (models row = TOYOTA; row <= PORSCHE; row = static_cast <models>(row + 1)){
        cout << setw(10) << decodeModel(row) << ":";
        for (colors col = RED; col <= BLACK; col = static_cast <zoltan::colors>(col + 1)){
            cout << setw(8)<<richland[row][col];
        }
        cout << endl;
    }

    return 0;
}
void fillArray(dealerships passedArray){
    srand(time(NULL));
    for (models row = TOYOTA; row <= PORSCHE; row = static_cast <models>(row + 1))
    for (colors col = RED; col <= BLACK; col = static_cast <zoltan::colors>(col + 1))   //you can use the namespace or not
        passedArray[row][col] = rand() % 50;
}
int totalColor(dealerships d, colors c){  //Process by column
    int total = 0;
    for (models row = TOYOTA; row <= PORSCHE; row = static_cast <models>(row + 1))
        total+=d[row][c];
    return total;
}
int totalModel(dealerships d, models m){  //process by row
    int total = 0;
    for (zoltan::colors col = RED; col <= BLACK; col = static_cast <zoltan::colors>(col + 1))
        total+=d[m][col];
    return total;
}

string decodeColor(colors c){
    switch (c){
        case RED: return "red";
        case YELLOW: return "yellow";
        case BLUE: return "blue";
        case BLACK: return "black";
    };
}

string decodeModel(models m){
    switch (m){
    case TOYOTA: return "toyota";
    case FORD: return "ford";
    case CHEVY: return "chevy";
    case MAZDA: return "mazda";
    case PORSCHE: return "porsche";
    }
}