Video

We’re here

Firstly, take a congragulatory moment for yourself. You did it! You’ve completed some of the most basic concepts of programing up until now that are applicable to almost any language you’ll learn. C++ has a total of 58 key words. Up until now, we’ve covered 22 of them! That’s 37%!

bool int void
char long while
double return && (and)
else short || (or)
false signed ^ (xor)
float sizeof ! (not)
for true  
if unsigned  

As a quick review, take a few minutes to go over the list and make sure you rememember them all. If not check out the previous lessons to brush up!

And now back to buisness…

Structs

Structs are a way of grouping types together in C++. Just like functions, structs don’t change what your code does, they simply make it easier for you and anyone else to interpret your code. To help better understand that, this lesson will be organized with a follow along exercise in mind. Take time to implement the solution to every question on your own. The answers will be available, but look at them only after you’ve implemented it on your own.

Part 0

Write code to take in a fraction from a user and print it out.
Do not use decimals to represent the fraction, use only whole numbers.
HintWhat are the parts of a fraction?
HintWhat is the type of the numerator and denominator?
Hint

A fraction is written out like: 1/2.

Solution
Are you sure you want to see the answer?
#include <iostream>

int GetUserInput() {
    int number;
    std::cin >> number;
    return number;
}

void PrintFraction(int numerator, int denominator) {
    std::cout << numberator << '/' << denominator;
}

int main() {
    std::cout << "Enter the numerator: ";
    int numerator = GetUserInput();
    std::cout << "Enter the denominator: ";
    int denominator = GetUserInput();

    PrintFraction(numerator, denominator);
    return 0;
}


Part 1

Write code to reduce a fraction to it's simplest form.
9/18 -> 1/2
1/2  -> 1/2
HintHow do you reduce a fraction?
HintHow can the Greatest Common Factor help?
HintThe Greatest Common Factor of 9 and 18 is 9. 9/18 is (9 / 9)/(18 / 2)
Solution
Are you sure you want to see the answer?
#include <iostream>

int GetUserInput() {
    int number;
    std::cin >> number;
    return number;
}

void PrintFraction(int numerator, int denominator) {
    std::cout << numberator << '/' << denominator;
}

int GreatestCommonFactor(int num1, int num2) {
    for (int i = num1; i > 1; i--) {
        if ((num1 % i == 0) && (num2 % i == 0)) {
            return i;
        }
    }
    return 1;
}

int main() {
    std::cout << "Enter the numerator: ";
    int numerator = GetUserInput();
    std::cout << "Enter the denominator: ";
    int denominator = GetUserInput();
    std::cout << "Input: ";
    PrintFraction(numerator, denominator);
    std::cout << std::endl;


    int gcf = GreatestCommonFactor(numerator, denominator);
    numerator /= gcf;
    denominator /= gcf;
    std::cout << "Simplified: ";
    PrintFraction(numerator, denominator);
    std::cout << std::endl;

    return 0;
}


Part 2

Now you might have realized its not possible to create a function of the sorts SimplifyFraction as then you would somehow have to return both the numerator and denominator. And as we know, we can’t return multiple variables from one function. At least not until now! This is where struct comes into play. A struct lets you group up multiple types together to make a new type of your own. The syntax looks like the following:

struct MyTypeName {
    // struct members
};

The keyword struct is used to indicate that you’re making a new type. MyTypeName is the name of your new type. This of this as another option now available to you just like int, char, or float. And the ; represents the end of the definition. In the struct members, you can add a type and name of all the members you’d like to struct to contain. For example:

struct Student {
    char first_initial;
    char last_initial;
    int grade;
};

In this case, my Student type has 3 members: first_initial, last_initial, and grade. To create a Student variable the following code would work:

struct Student {
    char first_initial;
    char last_initial;
    int grade;
};

int main() {
    Student s;
    s.first_initial = 'V';
    s.last_initial = 'G';
    s.grade = 75;
}

Notice I can use the . symbol to access the members of the s variable which is of type Student. Now lets write a function to print out a Student type. We can’t use std::cout << s; anymore because std::cout only knows how to print what are called primitive types. These are the types that already exist (refer to lesson03 for a complete list). For all custom types you’ll have to write your own function.

void Print(Student a) {
    std::cout << a.first_initial << '.' << a.last_initial << ". :: " << a.grade;
}

I could have made this function do anything I want with the members. For example, the following is just as good, it all depends on what I want the code to print out as.

void Print(Student a) {
    std::cout << "First: " << a.first_initial << std::endl
              << "Last: " << a.last_initial << std::endl 
              << "Grade: " << a.grade;
}

Using the Print function is exactly the same for the Student type as it is for ints or any other type.

#include <iostream>

struct Student {
    char first_initial;
    char last_initial;
    int grade;
};

void Print(Student a) {
    std::cout << "First: " << a.first_initial << std::endl
              << "Last: " << a.last_initial << std::endl 
              << "Grade: " << a.grade;
}

int main() {
    Student s;
    s.first_initial = 'V';
    s.last_initial = 'G';
    s.grade = 75;
    Print(s);
}

Similarly you can always return a Student type from a function as well.

#include <iostream>

struct Student {
    char first_initial;
    char last_initial;
    int grade;
};

Student CreateStudent() {
    Student s;
    std::cout << "First Initial: ";
    std::cin >> s.first_initial;
    std::cout << "Last Initial: ";
    std::cin >> s.last_initial;
    std::cout << "Grade: ";
    std::cin >> s.grade;
    return s;
}

int main() {
    Student s = CreateStudent();
}

And last, as with every variable, a struct type will always have a size as well. The size of a struct will be a sum of all the sizes of its members. So Student type has a size of sizeof(char) + sizeof(char) + sizeof(int) = 1 + 1 + 4 = 6 bytes.

Now the task for you is

Create a struct to represent a fraction.
Write code to do Part 0 and 1 using this new struct.
Solution
Are you sure you want to see the answer?
#include <iostream>

struct Fraction {
    int numerator;
    int denominator;
};

Fraction GetUserInput() {
    Fraction val;
    std::cout << "Enter the numerator: ";
    std::cin >> val.numerator;
    std::cout << "Enter the denominator: ";
    std::cin >> val.denominator;
    return val;
}

void PrintFraction(Fraction value) {
    std::cout << value.numberator << '/' << value.denominator;
}

int GreatestCommonFactor(int num1, int num2) {
    for (int i = num1; i > 1; i--) {
        if ((num1 % i == 0) && (num2 % i == 0)) {
            return i;
        }
    }
    return 1;
}

Fraction Simplify(Fraction value) {
    int gcf = GreatestCommonFactor(value.numerator, value.denominator);
    Fraction result;
    result.numerator = value.numerator / gcf;
    result.denominator = value.denominator / gcf;
    return result;
}

int main() {
    Fraction value = GetUserInput();
    PrintFraction(value);
    std::cout << std::endl;

    std::cout << "Simplified: ";
    value = Simplify(value);
    PrintFraction(value);
    std::cout << std::endl;

    return 0;
}


Part 3

  • A struct can have 1 member.
  • The types of members in structs can be other structs.
struct Foo {
    char a;
};

struct Bar {
    Foo f;
    int b;
};

int main() {
    Bar bar;
    bar.b = 10;
    bar.f.a = 'a';
}
  • Remember, the sizeof function can be used to determine the size of any variable or type. sizeof(Foo) would return 1.

Assignment

  1. What’s wrong with code samples 0-1? Can you fix it?
  2. Write a struct to represent each of the following. Create a user input function and a print function for each as well.

    If you cannot include some members of the struct because you aren’t sure what type to use, skip them for now and mention them in comments near the struct defintion.

    Think if you need a struct within a struct for any of the following.

    • Point (on the XY plane)
    • Rectangle (on the XY plane)
    • Driver’s license
    • Calendar Appointment
  3. What is the size for each in 2.
  4. In the code for Part 2, add a function which returns the sum of two fractions.
  5. Write code to tell if two calendar appointments conflict. Use your code from question 2 above.
  6. Referencing your calculator code, create a new calculator which works on fractions.

Code Samples

Sample 0
#include <iostream>

stuct Answers {
    int first;
    int second
    int third;
};

void QuestionA(Answer val) {
    std::cout << "What is my favorite number: ";
    std::cin >> val.first;
}

void QuestionB(Answer val) {
    std::cout << "What is my age: ";
    std::cin >> val.second;
}

int QuestionC(Answer val) {
    std::cout << "What lesson is this: ";
    std::cin >> val.third;
}

int main {
    Answers correct;
    correct.first = 360;
    correct.second = 25;
    correct.third = 11;

    Answers user;
    QuestionA(val);
    QuestionB(val);
    QuestionC(val);

    if (correct == user) {
        "You got the rigth answer!";
    } else {
        "Close but not quite! The answer was: " << correct;
    }

    return 0;
}
Sample 1
Hint
int GetSomething() {
    return 6;
}

char GetSomething() {
    return 'c'
}

int main() {
    std::cout << GetSomething() << std::endl;
}

Can you tell what this code will print out? Since you can’t tell which GetSomething() the user wants to call, the computer can’t either. Its important to distinguish functions by name so its clear which one is being called. Be sure to take note of the error this produces so you can recognize it in the future.

#include <iostream>

// ------------------- DO NOT CHANGE THIS IN THIS SECTION -------------------
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------

/* Category Types:
 * 1: Shopping
 * 2: Transportation
 * 3: Other
 */

struct Purchase {
    unsigned int category;    // A category as described above.
    int amount;               // The cost of the purchase.
}

struct Budget {
    unsigned int category;    // A category as described above.
    int limit;                // The maximum amount available for the specified category.
};

/* Prints out a budget in a human readable foramt.
 * Args: 
 *   budget: A Budget Type to Print.
 */
void Print(Budget budget) {
    if (budget.category == 1) {
        std::cout << "Shopping: ";
    } else if (budget.category == 2) {
        std::cout << "Transportation: ";
    } else if (budeget.category == 3) {
        std::cout << "Other: ";
    } else {
        std::cout << "Error Invalid Category! ";
    }
    std::cout << '$' << budget.amount;
}
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------

Budget FromUser() {
    Budget budget;
    std::cin << budget.category;
    std::cin << budget.limit;
    return budget;
}


Purchase FromUser() {
Purchase item;
    std::cin << item.category;
std::cin << item.limit;
    return item;
}



// ------------------- DO NOT CHANGE CODE IN THIS SECTION -------------------
// ----------------------- Updating comments is ok. -------------------------
// --------------------------------------------------------------------------

/* The comment for this function is removed, try to understand what this 
 * function does by reading it. Once you understand, you are welcome to update 
 * this comment to help you remember.
 */
void BudgetStatus(Budget budget, int total_spent) {
    std::cout << "Budget ";
    Print(budget);
    if (total_spent < budget.limit) {
        std::cout << " And you remained within your budget!";
    } else {
        std::cout << " You blew the budget!";
    }
    std::cout << std::endl;
}

/* The comment for this function is removed, try to understand what this 
 * function does by reading it. Once you understand, you are welcome to update 
 * this comment to help you remember. Feel free to add comments before lines in
 * the code below as well.
 */
int main() {
    std::cout << "Enter a limit for shopping category" << std::endl;
    Budget limit_shopping = GetBudgetFromUser(1);
    Print(limit_shopping);
    std::cout << std::endl;

    std::cout << "Enter a limit for transportation category" << std::endl;
    Budget limit_transportation = GetBudgetFromUser(2);
    Print(limit_transportation);
    std::cout << std::endl;

    std::cout << "Enter a limit for other category" << std::endl;
    Budget limit_other = GetBudgetFromUser(3);
    Print(limit_other);
    std::cout << std::endl;

    Purchase item0 = GetPurchaseFromUser();
    Print(item0);
    
    Purchase item1 = GetPurchaseFromUser();
    Print(item1);
    
    Purchase item2 = GetPurchaseFromUser();
    Print(item2);

    int total_other = GetTotalForCategory(limit_other.category, item0, item1, item2);
    int total_shopping = GetTotalForCategory(limit_shopping.category, item0, item1, item2);
    int total_transportation = GetTotalForCategory(limit_transportation.category, item0, item1, item2);

    BudgetStatus(limit_other, total_other);
    BudgetStatus(limit_shopping, total_shopping);
    BudgetStatus(limit_transportation, total_transportation);
}
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------


End of Assignment Checklist

  • I finished all the assignments.
  • I shared my assignments with others.
  • I provided feedback for assignments of at least 2 others.
  • I addressed the feedback from others and thanked them for the review.