Search

4.7 — Structs

There are many instances in programming where we need more than one variable in order to represent an object. For example, to represent yourself, you might want to store your name, your birthday, your height, your weight, or any other number of characteristics about yourself. You could do so like this:

However, you now have 6 independent variables that are not grouped in any way. If you wanted to pass information about yourself to a function, you’d have to pass each variable individually. Furthermore, if you wanted to store information about someone else, you’d have to declare 6 more variables for each additional person! As you can see, this can quickly get out of control.

Fortunately, C++ allows us to create our own user-defined aggregate data types. An aggregate data type is a data type that groups multiple individual variables together. One of the simplest aggregate data type is the struct. A struct (short for structure) allows us to group variables of mixed data types together into a single unit.

Declaring and defining structs

Because structs are user-defined, we first have to tell the compiler what our struct looks like before we can begin using it. To do this, we declare our struct using the struct keyword. Here is an example of a struct declaration:

This tells the compiler that we are defining a struct named Employee. The Employee struct contains 3 variables inside of it: a short named id, an int named age, and a double named wage. These variables that are part of the struct are called members (or fields). Keep in mind that Employee is just a declaration -- even though we are telling the compiler that the struct will have member variables, no memory is allocated at this time. By convention, struct names start with a capital letter to distinguish them from variable names.

Warning: One of the easiest mistakes to make in C++ is to forget the semicolon at the end of a struct declaration. This will cause a compiler error on the next line of code. Modern compilers like Visual Studio 2010 will give you an indication that you may have forgotten a semicolon, but older or less sophisticated compilers may not, which can make the actual error hard to find.

In order to use the Employee struct, we simply declare a variable of type Employee:

This defines a variable of type Employee named joe. As with normal variables, defining a struct variable allocates memory for that variable.

It is possible to define multiple variables of the same struct type:

Accessing struct members

When we define a variable such as Employee joe, joe refers to the entire struct (which contains the member variables). In order to access the individual members, we use the member selection operator (which is a period). Here is an example of using the member selection operator to initialize each member variable:

As with normal variables, struct member variables are not initialized, and will typically contain junk. We must initialize them manually.

In the above example, it is very easy to tell which member variables belong to Joe and which belong to Frank. This provides a much higher level of organization than individual variables would. Furthermore, because Joe’s and Frank’s members have the same names, this provides consistency across multiple variables of the same struct type.

Struct member variables act just like normal variables, so it is possible to do normal operations on them:

Initializing structs

Initializing structs by assigning values member by member is a little cumbersome, so C++ supports a faster way to initialize structs using an initializer list. This allows you to initialize some or all the members of a struct at declaration time.

In C++11, we can also use uniform initialization:

If the initializer list does not contain an initializer for some elements, those elements are initialized to a default value (that generally corresponds to the zero state for that type). In the above example, we see that frank.wage gets default initialized to 0.0 because we did not specify an explicit initialization value for it.

C++11/14: Non-static member initialization

Starting with C++11, it’s possible to give struct members a default value:

Unfortunately, in C++11, the non-static member initialization syntax is incompatible with the initializer list and uniform initialization syntax, so you’ll have to decide which one to use. For structs, we recommend the uniform initialization syntax.

In C++14, this restriction was lifted and both can be used. If both are provided, the initializer list/uniform initialization syntax takes precedence.

Structs and functions

A big advantage of using structs over individual variables is that we can pass the entire struct to a function that needs to work with the members:

In the above example, we pass an entire Employee struct to printInformation(). This prevents us from having to pass each variable individually. Furthermore, if we ever decide to add new members to our Employee struct, we will not have to change the function declaration or function call!

The above program outputs:

ID:   14
Age:  32
Wage: 24.15

ID:   15
Age:  28
Wage: 18.27

A function can also return a struct, which is one of the few ways to have a function return multiple variables.

This prints:

The point is zero

Nested structs

Structs can contain other structs. For example:

In this case, if we wanted to know what the CEO’s salary was, we simply use the member selection operator twice: myCompany.CEO.wage;

This selects the CEO member from myCompany, and then selects the wage member from within CEO.

You can use nested initializer lists for nested structs:

Struct size and data structure alignment

Typically, the size of a struct is the sum of the size of all its members, but not always!

Consider the Employee struct. On many platforms, a short is 2 bytes, an int is 4 bytes, and a double is 8 bytes, so we’d expect Employee to be 2 + 4 + 8 = 14 bytes. To find out the exact size of Employee, we can use the sizeof operator:

On the author’s machine, this prints:

The size of Employee is 16

It turns out, we can only say that the size of a struct will be at least as large as the size of all the variables it contains. But it could be larger! For performance reasons, the compiler will sometimes add gaps into structures (this is called padding).

In the Employee struct above, the compiler is invisibly adding 2 bytes of padding after member id, making the size of the structure 16 bytes instead of 14. The reason it does this is beyond the scope of this tutorial, but readers who want to learn more can read about data structure alignment on Wikipedia. This is optional reading and not required to understand structures or C++!

Accessing structs across multiple files

Because struct declarations do not take any memory, if you want to share a struct declaration across multiple files (so you can instantiate variables of that struct type in multiple files), put the struct declaration in a header file, and #include that header file anywhere you need it.

Struct variables are subject to the same rules as normal variables. Consequently, to make a struct variable accessible across multiple files, you can use the extern keyword to do so.

A final note on structs

Structs are very important in C++, as understanding structs is the first major step towards object-oriented programming! Later on in these tutorials, you’ll learn about another aggregate data type called a class, which is built on top of structs. Understanding structs well will help make the transition to classes that much easier.

Quiz

1) You are running a website, and you are trying to keep track of how much money you make per day from advertising. Declare an advertising struct that keeps track of how many ads you’ve shown to readers, what percentage of users clicked on ads, and how much you earned on average from each ad that was clicked. Read in values for each of these fields from the user. Pass the advertising struct to a function that prints each of the values, and then calculates how much you made for that day (multiply all 3 fields together).

2) Create a struct to hold a fraction. The struct should have an integer numerator and an integer denominator member. Declare 2 fraction variables and read them in from the user. Write a function called multiply that takes both fractions, multiplies them together, and prints the result out as a decimal number. You do not need to reduce the fraction to its lowest terms.

Quiz Answers

1) Show Solution

2) Show Solution

4.8 -- The auto keyword
Index
4.6 -- Typedefs

164 comments to 4.7 — Structs

  • Skylark

    Is there a ‘with’ keyword that allows you to edit variables of a structure without having to re-type the name repeatedly [like in Visual Basic]?


    Employee sFrank //a variable of the Employee type

    with sFrank
    .nEmployeeID = 15
    .nAge = 28
    [end with statement]

    // or something like that?

    Not that I’m lazy or anything…

    PS: I think there are some unwanted borders/shading on this page.

    Bye!

  • Mitul Golakiya

    /* Program of Structure Exerice 1 */

    #include <iostream.h>
    #include <conio.h>

    struct web
    {
    int adv;
    float rate;
    float click;
    };

    float money(int adv,float rate,float click)
    {
    float totalearning;
    totalearning = (adv * rate * click);
    return totalearning;
    }

    web mny;

    void main()
    {
    float res;

    clrscr();

    cout << "n How many advertise was shown: ";
    cin >> mny.adv;

    cout << "n What was rate of click : ";
    cin >> mny.rate;

    cout << "n Average of earning per click : ";
    cin >> mny.click;

    res = money(mny.adv , mny.rate , mny.click);

    cout << "n The Total earning is " << res;

    getch();
    }

    /* End of Program */

  • Astro

    We can pass a structure to a function.

    But can a function return a structure of data?

    Cheers.

  • siku

    Is there such a thing like typedef pointers? I got into trouble to initialize PCOORD. Finally I figured it out but I am not sure that am I doing the right thing? I thought it would be good to put this code example here since the mechanism is used in many places.

    For example (code):

    typedef struct Coordinate
    {
    short X;
    short Y;
    } COORD, *PCOORD;

    int main()
    {
    COORD pos;
    pos.X = 0;
    pos.Y = 0;
    PCOORD pPos = &pos;
    }

    At the beginning my main function looked like the main() below:

    int main()
    {
    //this is the wrong way to do things
    PCOORD pPos;
    pPos->X = 0;
    pPos->Y = 0;
    //if you use pPos now in somewhere compiler gives you warning that pPos is not initialized and my program crashed if I run that.
    // Why is it so? Why I cant initialize?
    }

    • Yes, you can do this -- PCOORD is a typedef’s poniter to a Coordinate struct. You can’t initialize your pPos because pPos is a pointer, and you haven’t set it to point at anything.

  • som shekhar

    When i print the score i got junk , i understood since initially s1 was not initialised, and
    when it is passed to function ReadScore s1 now become a local scope for that function and
    value got destroyed after the function ends and dats y i got junk value.
    But When i am doing like this

    i m still getting junk.Well i have created another structure variable s2, and then i assigned
    s2 to s1, so it will be copying the score, Correct??? then y the value is getting destroyed after the f
    the function ends

    • Quinn

      This is probably old but I’ll answer it anyway, for future reference.

      ReadScore doesn’t return the s1 struct. Since s1 is declared locally in both the main function and the ReadScore function, it’s two separate Score structs. Therefore, when you called ReadScore, it didn’t change the value of main()s s1 Score struct. To change that code to work right, you’d either need to use pointers, or you could return the struct from ReadScore. The following examples exclude your other perfectly fine function and struct declaration.

      Returning struct:

      Or you could use pointers:

      Hope that helps!

  • som shekhar

    Okay i understood what can go wrong in the above problem???correct me if i am wrong!!
    when i declare Score s1; memory has been allocated lets say its address is 123.
    Now when i am passing this s1 to the function ReadScore, this function will create a copy of s1
    which will have different memory,(let say its address is 125) so it does everything right,
    but doesnt touch at all the address 123..which is still junk. SO i m getting junk correct?

    the above problem i overcame ,when i send the reference of the s1!!!
    Or else i can call the PrintScore inside the ReadScore function..this will also eliminates the problem.

    • Chris Walker

      Exactly! This is a pass-parameter-by-value-or-reference issue. As a general rule: if you need to modify the struct/obj and keep changes in the previous scope, pass by reference, not by value. Your description of what was happening in your code is spot on.

  • Kinten

    I have see that some people define structs this way

    What I dont understand is, why they write “something” two times?

    • It’s easier to understand when you use different labels:

      In this case, something is the name of the struct itself. It’s like naming a function, it’s just a label to reference it by later. This doesn’t actually create a struct object, it just lays out what a struct looks like.

      somethingelse declares an actual struct object. It is a variable that takes up memory.

      So when you see something like this:

      It basically means you’re defining a struct named something, and then also defining a local variable with the same name. In my opinion, this is bad coding style since you’re using the same name for two different things.

      Usually when I see this, it’s because people want a “one off” struct -- something that’s only used once. In that case, you can just use an anonymous struct:

      This struct has no name and the type can never be referenced directly. However, something is a variable of that type.

  • surua

    why can’t I print the CEO’s data this way. I think I am doing some silly mistake…

    • manju

      U are actually passing the structure sCEO which is not declared . So the compiler gives u an error . Since the sCEO is a member of sMyCompany. U should use sMyCompany.sCEO in order to access the structure of Employee sCEO .

      The following line would fix ur problem
      PrintInformation(sMyCompany.sCEO);
      instead of
      PrintInformation(sCEO);

  • twilight

    When I understand the solution for 1) right, this is showing us a style of coding this tutorial itself said we should not do.

    The method PrintAdvertising() get’s passed a struct named sAd, while the main-function declares a struct with the name sAd.
    So while in the PrintAdvertising() method, the local sAd is hiding the main()-sAd.

    Am I right or did I understand something wrong? Thx!

    • Alex

      No, it’s fine to do it this way.

      While in function PrintAdvertising(), the struct declared in main() is inaccessible. So it’s fine that PrintAdvertising() uses the same name.

  • Shawn

    Alex

    for the quiz 2 how-come the same result is not produced?

    the correct answer is printed in the above code

    but it just prints 0, in the next code, i know i am doing something wrong with type casting, but what exactly am i doing wrong

    thanks

    • Alex

      The precedence in the second statement is wrong. You’re doing two integer divisions, multiplying them together (which will produce an integer) and then casting the answer to a float.

      You probably meant:

  • Hello Alex,

    I have trouble understanding the following situation, where a struct consisting of int, float and bool types shows a complete size as 12. Whereas, if I display the size of each data-type, it shows 4(int), 4(float), 1(bool).

    Please explain.

    The code:

    The Output:

    Regards,
    Mayur

    • Ole

      Let me quote Alex and highligth the important bit that you wonder about:

      “Typically, the size of a struct is the sum of the size of all it’s members. In this case, since each integer is 4 bytes and a float is 4 bytes, Employee would be 12 bytes. However, some platforms have specific rules about how variables must be laid out in memory — consequently, the compiler may leave gaps between the variables. As a result, we can say the struct will be at minimum 12 bytes.”

      Cheers
      Ole

  • Carter

    struct Fractions
    {
    int nNumerator;
    int nDenominator;
    };

    int multiply(int x, int y)
    {
    return x * y;
    }

    float produceValue(Fractions sAny)
    {
    using namespace std;
    cout << "Enter a Numerator " <> sAny.nNumerator;
    cout << "Enter a Denominator " <> sAny.nDenominator;
    return (float)sAny.nNumerator / sAny.nDenominator;
    }
    int main()
    {
    using namespace std;
    cout << "Now, we are going to multiply two fractions. First: " << endl;
    float x = produceValue;
    cout << "Now, once again " << endl;
    float y = produceValue;

    cout << "The answer is " << multiply(float x, float y);

    return 0;
    }

    didnt work though, does anyone know why?

    • mirondanro

      Try this:

      #include
      #include

      struct Fractions
      {
      int nNumerator;
      int nDenominator;
      };

      float multiply(float x, float y)
      {
      return x * y;
      }

      float produceValue()
      {
      using namespace std;
      Fractions sAny;
      cout <> sAny.nNumerator;
      cout <> sAny.nDenominator;
      float result = (float)sAny.nNumerator / sAny.nDenominator;
      return (result);
      }

      int main()
      {
      using namespace std;
      cout << "Now, we are going to multiply two fractions. First: " << endl;
      float x = produceValue();
      cout << "Now, once again " << endl;
      float y = produceValue();
      cout << "The answer is " << multiply(x, y);
      cin.clear();
      cin.ignore(255, '\n');
      cin.get();
      return 0;
      }

  • BX

    Shouldn’t structure alignment be mentioned in this chapter?

    BTW, great free tutorials. Thanks for your effort.

    • Alex

      I mention it in the article above. Understanding structure alignment isn’t required to use structures or write effective C++ programs. It’s something that curious people can read about if they desire, or come back to later.

  • drow

    #include “stdafx.h”

    #include

    struct advertising
    {
    int nAds_shown;
    float percentThatclicked;
    float averageEarned;
    };

    void read()
    {
    using namespace std;
    advertising scompany;
    cin >> scompany.nAds_shown;
    cin >> scompany.percentThatclicked;
    cin >> scompany.averageEarned;
    }

    int main(advertising scompany)
    {
    using namespace std;
    read();
    cout << scompany.nAds_shown << endl;
    cout << scompany.percentThatclicked << endl;
    cout << scompany.averageEarned << endl;
    cout << scompany.nAds_shown*scompany.percentThatclicked * scompany.averageEarned << endl;
    return 0;
    }

    This code compiles and links without a problem, but when I actually run it it returns very odd numbers.
    Can anyone help?

    • Kiasta

      Try making the void Read() function return the struct advertisementy like so:

      What happens is that when you run through the function Read() it stores the data in the SCOPE, and than is destroyed after the function ends. So when you return scompany and store it into scompany on int main(), it passes the values to the main() scope. There might be a little more to it but basically the values are destroyed when Read() ends so you have to pass it on to main() which I have done. BTW I am unsure as to why you included stdafx.h when you have nothing in your program that needs that header, whats even more curious is the way you included it (with “” instead of ) and that it compiled at all.

  • Kiasta

    In your “Quiz 1 Answer” You did not divide the percentage, or at least turn it into a decimal, so the output will be wrong.

    For example:

    5000 * 50 * $.15 = $37,500
    5000 * (50 / 100) * $.15 = $375

    The two are very different. The user will not know to put a decimal instead of a whole number (in fact they might even put a modulus after the number which is bad). I guess I am just a little nit-picky. BTW here is my answer if you are interested:

    • Alex

      The way the problem was originally specified asked the user to enter a percentage as a number between 0 and 1, so the division by 100 wasn’t necessary. But I think more people probably think about percentages the way you do (between 0 and 100 instead of between 0 and 1), so I’ve altered the question and answer.

  • Rafael

    This is my answer for exercise 1 and 2 :

    Exercise 1 :

    And Exercise 2 :

  • Elqno

    Hello Alex, I have a qst:

    From your code:

    when you made the declaration of this:

    shouldn’t be like this:

    or making the struct a typedef?? :

    I think it should be like that, so then you can declare sJoe as you did…
    I hope that if you reply I will get to my inbox that you did it 😉 so I can check what you wrote 😉

    • Alex

      In C++ using “struct Employee sJoe” or typedefs along with structs isn’t necessary.

      This is one of the areas where C++ improves on C.

  • Sudheer

    Thanks a lot Alex

    Really very useful tutorial on web. Thanks again for the effort 🙂

  • Would someone mind telling me why this is rounding down my answer? I’m not sure what i’m doing wrong.

    It’s giving me the answer 0, but i want 0.75.

    I take it i accidently read over one of the earlier lessons which is really confusing me now.

    • JD

      I kinda doubt you’re still wondering this 2 months later, but in case you haven’t figured it out:

      Because the / operator is in the parenthesis, the division is performed first. Both inputs are integers, so it is performed as an integer operation (and rounded to 0). Only after the division is complete does it convert the result to float. You want the division to be a float operation, so you should cast one of the inputs *before* the division, as follows:

      This will make it a float operation, and it will not be rounded.

  • youjay

    For the Example in the post, I tried the following
    ……
    …….
    int main()
    {
    struct Employee
    {
    int nID, nAge;
    float fWage;
    };
    ….
    …..

    As you can see, I defined struct inside main(). This failed. However, defining Struct outside main() worked? Any reason?

    J

    • WCoaster

      The variables inside the structure are treated as local variables inside main(). When you declare it outside main() they become global variables (evil) 😉

      It should work if you initialize your variables before calling a function.

    • Alex

      I’m not sure why this wouldn’t work. You should be able to declare a struct inside a function (I tested it with Visual Studio 2010 Express and it works).

      If you do this, the struct declaration has local scope, so you’ll only be able to create variables of this struct type within that function.

  • SWEngineer

    Simply well explained tutorial. Thanks.

  • JMan

    why my code always produce interger output?Can anyone please help me?:(

    // Enumeraor.cpp : Defines the entry point for the console application.
    //

    #include “stdafx.h”
    #include

    struct Fraction
    {
    int nNumerator;
    int nDenomintor;
    };

    double Input()
    {
    using namespace std;
    Fraction sFrac;
    cout<<"Enter the numerator of fraction :"<>sFrac.nNumerator;
    cout<<"Enter the denominator of fraction :"<>sFrac.nDenomintor;
    return static_cast(sFrac.nNumerator/sFrac.nDenomintor);
    }

    int main()
    {
    using namespace std;
    double dFracA=Input();
    double dFracB=Input();
    double dResult;
    static_cast(dResult=dFracA*dFracB);
    cout<<"The result is :"<<dResult<<endl;
    return 0;
    }

    • Alex

      Because you’re doing integer division and casting the result to a float instead of doing floating point division.

      Instead of:

      try:

  • Ollie999

    This is such a great website. Thanks very much for these tutorials. They’re absolutely spot on.

    Just one quick question. What would be the best way to make a struct declaration visible throughout the entire project. ie if you declared the struct type in one file and then wanted to create an instance of it in another.

    Would it be good practice to use a separate file for creating all struct and then use an #include in each file where you need to use it?

  • Mindstormscreator

    Just thought I’d share my code like some people are:

    First exercise, in main.cpp:
    #include <iostream>
    #include "main.h"

    using namespace std;

    int main()
    {
    cout << "Hi there! Um, please enter the following:\n" <<
    "-- Total ads shown to users\n" <<
    "-- Percent of ads clicked\n" <<
    "-- Average profit per ad" << endl;
    Advertising sAds;
    cin >> sAds.nAdsShown >>
    sAds.fPercentClicked >>
    sAds.fAverageProfit;
    sAds.fPercentClicked /= 100; // Convert from percent to decimal so next calculation can occur
    cout << "Total profit today: $" <<
    (
    sAds.nAdsShown *
    sAds.fPercentClicked *
    sAds.fAverageProfit
    ) << endl;

    }

    First exercise, main.h:
    #ifndef MAIN_H
    #define MAIN_H

    struct Advertising
    {
    int nAdsShown;
    float fPercentClicked;
    float fAverageProfit;
    };

    #endif

    Second exercise, main.cpp:
    #include <iostream>
    #include "main.h"

    using namespace std;

    int main()
    {
    Fraction sMyFrac, sYourFrac;
    cin >> sMyFrac.nNumer >> sMyFrac.nDenom;
    cin >> sYourFrac.nNumer >> sYourFrac.nDenom;
    Fraction sProduct = multFractions(sMyFrac, sYourFrac);
    printFraction(sProduct);
    }

    Fraction multFractions(Fraction sX, Fraction sY)
    {
    Fraction sProduct;
    sProduct.nNumer = sX.nNumer * sY.nNumer;
    sProduct.nDenom = sX.nDenom * sY.nDenom;
    return sProduct;
    //return (new Fraction{sX.nNumer * sY.nNumer, sX.nDenom * sY.nDenom}); // one-liner?
    }

    void printFraction(Fraction sFrac)
    {
    cout << static_cast<double>(sFrac.nNumer) / sFrac.nDenom;
    }

    Second exercise, main.h:
    #ifndef MAIN_H
    #define MAIN_H

    struct Fraction
    {
    int nNumer;
    int nDenom;
    };

    Fraction multFractions(Fraction sX, Fraction sY);
    void printFraction(Fraction sFrac);

    #endif

  • DrSuse

    I had trouble with :

    void Multiply(Fraction sF1, Fraction sF2)

    because in section 2.1 Basic Addressing and Variable Declaration, it states:

    “The first mistake is declaring each variable as int (or whatever type it is) in sequence. This is not a bad mistake because the compiler will complain and ask you to fix it.

    int nValue1, int nValue2; // wrong (compiler error)

    int nValue1, nValue2; // correct”

    where instead I typed (something like) :
    void Multiply(Fraction sF1, sF2)
    and got compiler errors all over the pace.

    Am I to assume it’s different for function parameters?

    • codeez

      “Am I to assume it’s different for function parameters?”.

      Up to this point in the lessons, I’ve also noticed this hasn’t been explained, but you are right about it for sure!

      • Alex

        Yes, it works differently for function parameters, and it’s inconsistent with the way you declare variables.

        I’m not sure why it was done this way.

        • Andy356

          It’s probably due to the way function declarations are designed. We use

          for declaring, so making the function definition symmetrical would make sense. But then again, keeping it symmetrical with variable definitions would make more sense, since it’s done far more often than function declaration.

  • KanedaSyndrome

    My results:

    main.cpp

    #include <iostream>
    #include "functions2.h"
    using namespace std;

    advertising campaign1;
    fraction frac1, frac2;

    int main()
    {
    campaign1 = getData(campaign1);
    printResults(campaign1);

    cout << endl << "NEXT PART OF THE EXERCISE!" << endl;

    cout << "First fraction" << endl;
    frac1 = getFrac(frac1);
    cout << "Second fraction" << endl;
    frac2 = getFrac(frac2);
    fracProduct(frac1, frac2);

    cin.get(); //for halting the program
    cin.ignore(); //for halting the program
    return 0;
    }

    functions2.cpp

    #include <iostream>
    #include "functions2.h"
    using namespace std;

    advertising getData(advertising x)
    {
    cout << "Input the number of adds in the campaign: ";
    cin >> x.numberAdds;
    cout << "Input the hit rate of the campaign: ";
    cin >> x.hitRatio;
    cout << "Input the average revenue per hit: ";
    cin >> x.avgRevenuePerHit;
    return x;
    }

    void printResults(advertising x)
    {
    float result = x.numberAdds*x.hitRatio*x.avgRevenuePerHit;
    cout << endl << "The campaign has resulted in a total revenue of: " << result << endl;
    }

    fraction getFrac(fraction x)
    {
    cout << "Input a numerator: ";
    cin >> x.numerator;
    cout << "Input a denominator: ";
    cin >> x.denominator;

    return x;
    }

    void fracProduct(fraction x, fraction y)
    {
    float result = static_cast<float>(x.numerator*y.numerator)/(x.denominator*y.denominator);

    cout << "Multiplying the two fractions yields: " << result << endl;
    }

    functions2.h

    #ifndef FUNCTIONS2_H
    #define FUNCTIONS2_H

    struct advertising
    {
    int numberAdds;
    float hitRatio;
    float avgRevenuePerHit;
    };

    struct fraction
    {
    int numerator;
    int denominator;
    };

    advertising getData(advertising x);
    void printResults(advertising x);
    fraction getFrac(fraction x);
    void fracProduct(fraction x, fraction y);

    #endif

    ~KanedaSyndrome

  • Blackout

    This is what I did, I didn’t use structs because I wasn’t sure how, but it works.

  • Speeds03

    This is how I did it. It worked perfectly. But correct me if I should have done it another way. By the way, I pre-set the values for the variables because we aren’t really getting any user data to actually calculate a result.

    #include “stdafx.h”
    #include

    using namespace std;

    struct MoneyPerDay
    {
    int nAdShown; // 45 Ads shown each month
    long float fAdsClicked; // Amount of Ads clicked by users
    long float fAmountPerClick; // Each Ad click revenue is $.10
    long float nUsersPerDay;

    };

    void PrintMoneyEarnedPerDay(MoneyPerDay sMoneyPerDay)
    {
    cout << "Number of users per day: " << sMoneyPerDay.nUsersPerDay << endl;
    cout << "Number of Ads shown: " << sMoneyPerDay.nAdShown << endl;
    cout << "Number of Ads clicked: " << sMoneyPerDay.fAdsClicked << endl;
    cout << "Amount of money per Ad click: " << sMoneyPerDay.fAmountPerClick << endl;
    }

    int main()
    {
    MoneyPerDay sMonday;
    sMonday.nUsersPerDay = 10780;
    sMonday.nAdShown = 45;
    sMonday.fAdsClicked = 20;
    sMonday.fAmountPerClick = .10;

    MoneyPerDay sTuesday;
    sTuesday.nUsersPerDay = 20678;
    sTuesday.nAdShown = 45;
    sTuesday.fAdsClicked = 20;
    sTuesday.fAmountPerClick = .10;

    // Prints stats for monday
    cout << "Monday stats-- " << endl;
    PrintMoneyEarnedPerDay(sMonday);
    cout << "The result is: $" << sMonday.nUsersPerDay / sMonday.fAdsClicked * sMonday.fAmountPerClick << endl;

    cout << " " << endl;

    // Prints stats for tuesday
    cout << "Tuesday stats-- " << endl;
    PrintMoneyEarnedPerDay(sTuesday);
    cout << "The result is: $" << sTuesday.nUsersPerDay / sTuesday.fAdsClicked * sTuesday.fAmountPerClick << endl;

    cout << " " << endl;

    return 0;
    }

    • codeez

      Long float is kind of an oxymoron I think? VS2012 gives warnings:

      nonstandard extension used : long float c:user

      If you meant double the size of float then use ‘double’, but seeing as your data doesn’t exceed a float though, just the float would’ve done. 🙂

      You didn’t need the blanks here: cout << " " << endl; // just do: cout << endl;

      Keep coding. 🙂

  • Zidane

    //This is how I did it. Please comment 😉

    #include
    using namespace std;

    struct Adverts
    {
    unsigned short nAdsShown;
    float fClickRate;
    float fAveEarnPerClick;
    };

    Adverts GetAdsData()
    {
    Adverts Ads;
    cout<>Ads.nAdsShown;
    cout<>Ads.fClickRate;
    cout<>Ads.fAveEarnPerClick;
    return Ads;
    }

    void PrintAdsResult(Adverts Ads)
    {
    cout<<"Total of adverts shown:\t\t"<<Ads.nAdsShown<<endl;
    cout<<"Click through rate:\t\t"<<Ads.fClickRate<<endl;
    cout<<"Average earnings per click:\t"<<Ads.fAveEarnPerClick<<endl;
    cout<<"Total earnings for the day:\t$"<<Ads.nAdsShown * Ads.fClickRate * Ads.fAveEarnPerClick<<endl;
    }

    int main()
    {
    PrintAdsResult(GetAdsData());
    return 0;

    }

  • Zidane

    #include
    using namespace std;

    struct Fraction
    {
    unsigned short nNumerator;
    unsigned short nDenominator;
    };

    Fraction GetFractionData()
    {
    Fraction Fra;
    static int c=1; // ‘c’ is a Fraction Identifier
    cout<<"Fraction "<<c++<<endl;
    cout<>Fra.nNumerator;
    cout<>Fra.nDenominator;

    return Fra;
    }

    void PrintMultiplyFractions(Fraction x, Fraction y)
    {
    cout<<x.nNumerator<<"/"<<x.nDenominator<<
    " * "<<
    y.nNumerator<<"/"<<y.nDenominator<<
    " = "<<
    (static_cast(x.nNumerator * y.nNumerator)/(x.nDenominator * y.nDenominator))<<
    endl;
    }

    int main()
    {
    PrintMultiplyFractions(GetFractionData(),GetFractionData());
    return 0;

    }

  • Arthur_

    Why do you (for the second question) declare the numerator and denominators as integers when you know you are going to need them as floats later? Wouldn’t it be more logical to declare them as floats or longs and then you don’t have to static_cast them later?

    • Alex

      In standard mathematics, the numerators and denominators in fractions are always defined as integers. It’s better to have your code represent mathematical convention and do the conversions when necessary than to do something non-standard for the sake of avoiding a couple of static_casts.

      Plus using floating point numbers would allow you to define fractions like 3.4 / 10.2. Although technically this works (and is equivalent to 1 / 3), we don’t fraction that way. 🙂

  • Leolas

    Hi, this is my code for the question 2; i made it slightly different, so i would like to your opinions/corrections 🙂 . However, i forget the cast for the float, so i think that my code is doing integer division :s, well, i would very appreciate your advices or something 🙂

    #include
    using namespace std;

    struct Fraction
    {
    int nNumerator1;
    int nDenominator1;
    int nNumerator2;
    int nDenominator2;
    };

    void Multiply(Fraction Elements)
    {
    cout << "The product of the two fractions is: " << Elements.nNumerator1 / Elements.nDenominator1 * Elements.nNumerator2 / Elements.nDenominator2;
    }

    int main()
    {
    Fraction Elements;
    cout <> Elements.nNumerator1;
    cout <> Elements.nDenominator1;
    cout <> Elements.nNumerator2;
    cout <> Elements.nDenominator2;

    Multiply(Elements);
    return 0;
    }

  • Edward

    I managed to get my solution to question 2 correct. Initially though I had this code inside my multiply function.

    cout << static_cast((sF1.numerator)/(sF1.denominator))*((sF2.numerator)/(sF2.denominator));

    The program ran and compiled fine but performed integer division when I entered 1/5 * 1/1 in order to test the program, giving an answer of 0 instead of 0.2.

    When I re-ordered that line of code to

    cout << static_cast((sF1.numerator)*(sF2.numerator))/((sF1.denominator)*(sF2.denominator));

    the program works fine and performs the division properly, giving the correct answer (0.2).

    Why is this, to me the functions perform the same operations, am I missing something obvious?

    • Alex

      In the first line, you’re doing integer division and casting the integer result to a float (which is useless).

      In the second line, you’re casting the first operand to a float, which causes the division operator to convert the second operand to a float as well, and do floating point division.

  • Sind

    Can C++ structures include functions inside structure declaration?

  • Josh

    I'm having a bit of trouble with this.

    Stats sVortex = {0, 0, 0, 0, 0};

    i've typed this in, making sure to set sVortext to struct Stats (yes, i have already declared Stats as a struct in my header). This doesn't bring up any problems/compiler errors. However, once I try to reference it: Stats.sVortex.nDex; it says that: class "Stats" has no member "sVortex". No matter what I do, nothing seems to fix it.

    Please help,
    -Josh

  • Adi

    Struct in c++?

    Aren't we supposed to be using Classes.  Doesn't Class supercede Struct?

    • Kevin

      Classes have not yet been covered in the tutorial as are in a later chapter.

    • Janez

      Structure members are public by default and classes have their members private by default. There are some instances where you would use struct instead of class. Search for structs vs. classes for more thorough explanation (answers on stackoverflow are usually really good).

      • Alex

        Structs are simple aggregate types, and their use is appropriate in C++ when you don’t need any member functions or access controls.

  • Kevin

    I completed question 2 slightly differently, it works fine and gives the correct results. Have I done anything that would be considered bad practice or is this OK?  

    [#include "stdafx.h"
    #include <iostream>

    struct FRACTION
    {
        int numer_one;
        int numer_two;
        int denom_one;
        int denom_two;
    };

    void fractionMultiplied(FRACTION fraction)
    {
        using namespace std;
        // fraction multiplication
        float numer_sum = fraction.numer_one * fraction.numer_two;
        float denom_sum = fraction.denom_one * fraction.denom_two;
        float decemal_output = numer_sum / denom_sum;

        cout << "The decimal value of the sum of both of your fractions is: " << decemal_output;
    }

    int main()
    {
        using namespace std;
        FRACTION fraction;
        
        cout << "Enter two fractions to have them multiplied together:" << endl;
        // get fraction numerators and denominators
        cin >> fraction.numer_one;

        cout << " / ";

        cin >> fraction.denom_one;

        cout << " nAnd the other: n";

        cin >> fraction.numer_two;

        cout << " / ";

        cin >> fraction.denom_two;
        // call a function to output the sum of both fractions
        fractionMultiplied(fraction);

        return 0;

    }

    /* END OF PROGRAMME */]

  • Jeremy

    Are structure types generally defined outside all blocks (like a global variable)? This is the only thing I can’t seem to find an answer to. You obviously can declare them in blocks or functions, but is that bad style?

    • Janez

      Yes, they are (usually) defined outside all blocks. Since they are (user-defined) types, you want to access them from multiple functions (like you want to be able to declare variable of type int in multiple blocks).

  • Joseph

    Hi, I don’t get what the point is in using a struct in example 1, can someone explain?

    • Alex

      You mean in quiz 1? Generally structs are useful for keeping related variables together in one place, both for organizational purposes, and because it makes it easier to code.

      Any time you have two or more related non-trivial variables, you should consider putting them in a struct.

  • vinay

    In the quiz question no.1 , there is a below type in the solution

    [   cout << "Total Earnings: $" <<
            (ad.adsShown * ad.clickThroughRate / 100 * ad.averageEarningsPerClick) << endl;]

    please correct the above line from ad.clickThroughRate to ad.clickThroughpercentage as declared in the advertising structure.

  • Denis

    Hello Alex,

    The C++ language (actually its predecessor C) introduces structs as a mean of aggregating the variables into a one logical concept,
    which is a good thing.
    But isn’t it quite redundant as C++ has also got namespaces, which can as well serve us the same purpose?

    Moreover, we can also aggregate functions (behavior) under the same roof along with variables using the concept namespaces.

    What is the advantage of structs then (except for being able to pass and return multiple vars to functions) ?

    Thank you in advance.
    Denis

    • Alex

      Good question.

      Structs define a new data type and allow you to instantiate as many variables of that data type as you like.

      Namespaces do not define a new data type, are intended to provide a way to group related bits of code (functions, data types, etc…) together to avoid naming collisions.

      Although structs and namespaces can both be used to “collect” a group of related variables, I’d argue that structs do it better:
      * Structs allow you to set up a struct once and then instantiate as many of them as you want. With the namespace method, you’d have to define a whole new namespace every time you wanted a new “instance” of your group.
      * As you’ve already noted, you can pass structs into a function in their entirety, whereas with namespaces you’d have to pass each element individually.
      * Structs enforce a consistent naming convention for objects of that type (a good thing). This also makes them easier to debug.

  • Todd

    Typo.

    "The struct should have a (an) integer numerator and a (an) integer denominator member."

    I really enjoyed this section! Structs seem very helpful.

    • Alex

      Thanks for the correction.

      Structs are super useful! However, somewhat comically, they are rarely used in C++, because classes are even MORE useful.

      The good news is that classes build directly on top of structs, so the knowledge you gained here will still be put to good use.

  • mehdi

    Thanks for your excellent tutorial.
    When working with multiple files, do we have to use keyword extern to declare a struct?
    Another question: How can one combine arrays with structs? For example when instead of only two employees (Joe and Frank), we have 1000 employees.

    • Alex

      Declaring a struct defines a new data type. If you want to share a struct declaration across multiple files (so you can instantiate variables of that struct type in multiple files), put the struct declaration in a header file, and #include that header file anywhere you need it.

      If you instantiate a struct variable, and you want to share that variable across multiple files, you can extern that variable.

      Making an array of structs is just like making an array of any other data type. Just use the structs name as the data type. e.g.

      Employee myEmployees[10];

  • techsavvy....aye

    A typo (maybe)

    everywhere you have mentioned joe’s age to be 32 but here "Initializer lists" it is 42.

    Though it isn’t an issue. Just to let you know.

    😛

  • techsavvy....aye

    Just by changing the signs in the void multiply part of the quiz question 2. Why does it give a different answer.

    • Alex

      static_cast(f1.numerator / f1.denominator) does an integer division (dropping any fractional part) and then casts the result to a float (which isn’t useful because we’ve already lost any fractional result).

      The quiz example does the integer multiplication first, casts that to a float, and then does a floating point division (so as not to lose the fractional component).

  • techsavvy....aye

    But I took the example of- Input the first numerator:12

                               Input the first denominator:4

                               Input the second numerator:12

                               Input the second denominator:3

    Which does not include any fractional division but still according to the problem which I had it is giving 4 instead of 12.

    Sorry!!!….to keep bothering you off topic.

    • Alex

      Oh.

      Should be:

  • thanks all
    this note is very necessary

  • "Structs can contain other structs"

    If you want to tell what struct can contain, you should clear everything.  When I finished reading this lesson and moved to comprehensive quiz, I found that you have nested an enumerated  type as a struct member in your solution. Before that, I was believing struct can only contain structs. It is still unclear to me what other kinds of objects a struct can contain.

    One question: I want to create great programs using C++. What should I do after completing your tutorials? How much time would it take to reach there?
    Thanks… 🙂

  • Jacob

    In this segment of code, if Joe and Frank have the same wage, for example, if Joe and Frank both make 24.15, (joe.wage > frank.wage) will evaluate to false, and it will say "Joe makes less than frank"

  • I m trying to write a program that prints a company’s information (e.g. company name, name of CEO etc.). I am using struct to group all the related variables. My struct looks like:

    I defined a void printInfo (Company x) to print information of a company. My main () takes data from user and passes that to printInfo(). Rest of the work is done by printInfo (). My problem is with main () that is following:

    The above code compiles and links fine (not including the void printInfo (), nothing wrong with that). On execution, the program starts from taking input for x.NameOfCompany. That’s okay. But all the other getline () puzzled me. Program never asks for input for one (or both when i change the order of getlines, e.g. putting BranchesIn before NameOfCeo) variables which is set to take input through getline method. What’s the problem. Does getline has any limitations?

    If the code has any syntax or typographical error, please ignore. I swear that was linked and compiled fine.
    Thanx Alex 🙂

    • Alex

      The problem is the way cin works. When it asks for total revenue, and you enter “45” and hit enter, this gets input as “45\n”. The 45 gets extracted to x.Revenue, but the “\n” stays in the input stream. This messes up the next call to getline() (because it sees the ‘\n’ and says, “I’m done!”).

      To fix this, after each call to cin to read in a number, you can use the following to get rid of the extra ‘\n’ stuck in the input stream:

  • Thnx Alex. You are great.
    Still confused, what is 32767 here and should I use cin.ignore. In both the cases where getline (cin, ) and simple cin are used, or only when getline is used. Why this only messes up with getline and not with cin?

    • Alex

      32767 is just a large integer that tells cin.ignore how many characters to look through for a ‘\n’. In this case, you could use a low number since the ‘\n’ is likely going to be the first character (unless the user entered invalid input when asked for an integer).

      Unfortunately, getline and cin just work different with regards to how they handle input (particularly whitespace). They’re a pain, and their error handling capabilities are limited. I personally find it easier to read in everything as a string and then convert the string to an integer when that’s appropriate. That helps avoid unexpected characters in the streams.

  • begginner

    #include<iostream>
    #include<string>
    using namespace std;
    struct advertise
    {

        int no_of_ads;
        int no_of_users;
        int average_per_click;
        };

    getreport(advertise pa)
    {
        cout<<"enter no af ads no of user and avg per click"<<endl;
        cin>>pa.no_of_ads;
        cin>>pa.no_of_users;
        cin>>pa.average_per_click;
        cout<<"no of ads are"<<pa.no_of_ads<<endl;
    cout<<"no of users are"<<pa.no_of_users<<endl;
        cout<<"avaerage per click"<<pa.average_per_click<<endl;
        cout<<"money per day is"<<pa.no_of_ads*pa.no_of_users*pa.average_per_click;
    }

    main(){
        advertise a;
        getreport( a);
        

    }

  • Gayan

  • bio

    2QUIZ:when i try to compile ,i get this msg:    
        [Error] reference to ‘multiplies’ is ambiguous

    • Alex

      The problem is this line:

      It turns out that there’s a std::multiplies function, and the code isn’t sure whether you mean your version of multiplies() or std::multiplies.

      You can fix this by changing the call to multiplies like this:

  • bio

    thanks mate !!!you are awesome!

  • Rob

    Will there be a tutorial on Union types? I’ve come across them while trying SFML Events and I’m not sure if I entirely understand them

  • Gopal

    Hey Alex,

    Nice tutorial. You are doing great job.

    I have a question here. It looks like struct variables (member)act as global variable, whether this may result in evil thing?

    • Alex

      > It looks like struct variables (member)act as global variable, whether this may result in evil thing?

      Why do you say this?

      Struct member variables are part of the struct itself. If the struct is global, they are global. If the struct is local, they are local.

  • Gopal

    Thanks Alex,

    In this case if i want my struct variable as local, i have to have declare/define Structure inside the function (Main or any other user defined function).

    I hope my understanding is clear.

    • Alex

      Not quite. You can declare a struct anywhere. It’s just a declaration, so it doesn’t matter where you do it. It’s common to declare structs in header files and #include them where you need them.

      What matter is where you _define_ your struct variable. If you define the struct variable in global space, your struct is global. If you define it inside a function, it’s local.

  • A. Lousseief

    //
    // This is a simple program to use struct in C++
    // on October 2015 by A. Lousseief
    //
    #include <iostream>
    using namespace std;

    // Definition of struct to create fractions
    struct Fraction {
        int numerator;
        int denominator;
    }f1, f2;

    // function to multiply two fractions i.e f1*f2
    void multiply( Fraction f1, Fraction f2){
    //        cout << static_cast<float>(f1.numerator / f1.denominator)*(f2.numerator / f2.denominator);
            cout <<"\n\t\t(" <<f1.numerator <<"/"<<f1.denominator <<")*("<< f2.numerator <<"/"<< f2.denominator <<") = "     
                 <<"("<<f1.numerator<<"*"<<f2.numerator <<")/("<< f1.denominator<<"*"<<f2.denominator <<") = "    
                 <<"("<< f1.numerator*f2.numerator <<"/"<< f1.denominator*f2.denominator <<")\n\n";    
    }

    int main() {
            // Allocate the first fraction f1
            cout << "Enter the numerator of the first fraction f1: ";
            cin >> f1.numerator;
            cout << "Enter the denominator of the first fraction f1: ";
            cin >> f1.denominator;
            // Allocate the second fraction f2
            cout << "Enter the numerator of the second fraction f2: ";
            cin >> f2.numerator;
            cout << "Enter the denominator of thesecond fraction f2: ";
            cin >> f2.denominator;

            cout <<"\n\t\tThe product of f1 and f2 is: ";

            multiply(f1,f2);

            return 0;
    }

  • Sean Kelly

    Hello Alex, I wanted to thank you for these great tutorials and to ask you a question that is scratching my brain!

    When it comes to the answer of the first question involving the quiz, you print out:

    Now I am just wondering about operator precedence, since * and / are on the same level of precedence and the associativity is from left to right, why does this compile the way you would think it would? I would of thought it would of done ad.adsShown * ad.clickThroughRatePercentage and then do / 100? If you could explain my error that would be awesome!

    • Alex

      You are correct about the precedence and associativity. So this evaluates each term from left to right. First, ad.adsShown is multiplied by ad.clickThroughRatePercentage. Then that’s divided by 100. Then ad.averageEarningsPerClick is multiplied in.

      It’s not clear to me what you were thinking it should actually do instead?

      • Sean Kelly

        I see why I was confused, here is what I was thinking.

        Say you have shown 100 adds but only 10 of them are actually clicked on with each add giving an average of 1$ per click.
        100 * 10 / 100 * 1
        100 * 0.1 * 1
        10 * 1 = $10.

        So when I did my program I wrote it like this:

        I guess it does not matter whether you have it follow precedence or effect the path in the way that I did, the output is always the same.

  • Jane

    #include <iostream>
    #include <string>
    #include <fstream>
    #include <iomanip>
    #include <cmath>
    using namespace std;
    enum CarMake
    {Audi = ‘A’, Chrysler = ‘C’, Ford = ‘F’,
    Honda = ‘H’, Lexus = ‘L’, Mercedes = ‘M’, Nissan = ‘N’, Porche = ‘P’, Volvo = ‘V’};
    struct Date  //declare the struct prototype
    {
      int day;
      int month;
      int year;
    };
    struct Car
    {
       string firstname;
       string lastname;
       int costofthecar;
       Date dateofpickup;
       CarMake cartype;
    };
    int main()
    {
        Car information;
        cout << information.cartype.Audi;//error line

        return 0;
    }

    //Please Why does the compiler say expression must have class type

    • Alex

      This line is incorrectly constructed. I’m not even clear on what you’re trying to do.

      I think you may have meant to do this:

    • Shiva

      Audi = ‘A’ ?

      How can enumerators be assigned character constants? I thought enumerators can be assigned only integer values.

  • Josh

    frank.wage should be initialized to 0, in my point of view.

    Also refer to:
    http://stackoverflow.com/questions/1069621/are-members-of-a-c-struct-initialized-to-0-by-default

  • Anupam

    Would a structure declaration not consume memory even when "non-static member initialization" is used?

  • C++ novice programmer

    void printInformation(Employee employee)
    {
        std::cout << "ID:   " << employee.id << "\n";
        std::cout << "Age:  " << employee.age << "\n";
        std::cout << "Wage: " << employee.wage << "\n";
    }

    void printInformation(Employee)
    {
        std::cout << "ID:   " << Employee.id << "\n";
        std::cout << "Age:  " << Employee.age << "\n";
        std::cout << "Wage: " << Employee.wage << "\n";
    }
    Thank you for this very nice tutorial sir Alex!

    why do we need to use that ’employee’ starting with small letter? I tried to use only the ‘Employee’ with capital in the second example but it says error type name not allowed.

    • Alex

      Employee is the name of the type, and employee is the name of the variable. Similar to “int x”, where int is the type and x is the name of the variable.

  • Shiva

    Quick question on solution to Quiz 2) above:

    Is there any specific reason to define struct member variables of the same type in different lines:

    instead of defining them in a single line:

    ? Both compiles fine. Is it a matter of being a better programming practice?

  • Heitor

    Just one quick question: Is it possible to use Structs in arrays?

    • Shiva

      Just like for any other datatype, you can create an array of structs, if that’s what you mean. e.g.

      Or if you mean arrays inside structs, I think you can do that too:

      Hope that helps. 🙂

  • c++ lover

    i want to ask you a silly doubt

    if i replace

    by

    then can you explain the process

  • Sharaf

    if we have to use a struct we should define a variable under stuct

    can we in the same way initialize a function

    like you have done above

    And can you tell me what you have done in

    • Alex

      I’m afraid I don’t understand your first question.

      As for the second one, sure. getZeroPoint() returns a Point3d, which we’re using as an initializer for a Point3d named zero.

      Same thing as this really:

      just with a struct instead of an int.

      • sharaf

        why are you afraid?

        my question says:

        by declaring calc() as int data type, it means function can pass only int to other function (is it correct?)

        now my question is by declaring a function as
        a struct name as you have done

        does this mean this function can only pass Point3d() structure?

        i hope i am clear

        • Alex

          Saying “I’m afraid I don’t understand” is just a polite way of saying “I don’t understand”. I forget that sometimes these things don’t always translate well to non-native English speakers. 🙂

          And yes, you are correct in your assessment. The getZeroPoint() function will return a Point3d back to the caller.

  • Sharaf

    • sharaf

      see the question in comment,

      • Alex

        when b2.brea++ is evaluated, the compiler makes a temporary copy of b2.brea (value 15), increments the real b2.brea (value 16), and then evaluates the expression to the copy of b2.brea (value 15). Since nothing is done with this evaluated value, it is discarded.

        The real b2.brea still has value 16.

        • sharaf

          oh! it means when post increment is used to use the temporary file we must use it at that time

          i guess my assumpsion is correct

  • Patrick

    Hi Alex,

    I am a new in C++ programming and really appreciate your site. By completing your coding quizzes I try to follow best practices that you shared with us and articles written by other programming experts.

    For the line in quiz1 answer: (ad.adsShown * ad.clickThroughRatePercentage / 100 * ad.averageEarningsPerClick) << endl;

    Based on your comment line above the print statement, should this line be changed to: (ad.adsShown * (ad.clickThroughRatePercentage / 100) * ad.averageEarningsPerClick) since we want only clickThroughRatePercentage to divided by 100 and not the multiplication of adsShown and clickThroughRate Percentage?

    As best practice, I think a calculation formula is best to be assigned to variable and then use that variable to print in the console. I can imagine that this will provide debugging advantages (monitoring variables in Watch Window) especially in larger programs?

    Finally, I also tried to create a struct in a separate cpp file but I was unable to reference to the struct under main(). Can I use a class type file for a struct, make a reference in the header file and include the header file that contains the struct in the main source file? When I copy the struct back in the main() source file, my code is building without any compiler errors.

    • Alex

      Parenthesizing ad.clickThroughRatePercentage / 100 doesn’t change the answer (since multiplication and division have the same precedence and are resolved left to right), but it may help improve understanding.

      Assigning values to variables can definitely make debugging easier.

      For the last part, I’m assuming you’re talking about a struct declaration and not an instantiated struct variable? If so, you can put the struct declaration in a header file and then #include it wherever you need it. If you meant an instantiated struct variable, you’ll need to declare a variable forward declaration (using the extern keyword) in any other file you want to use that variable in.

      • Patrick

        Thank you, Alex

        I put the struct in the header file and this resolved my problem. I try to use class and header files for functions and now structs in every exercise just to get used of managing multiple files in a project.

  • Jim

    Alex,
    Shouldn’t this be …Triangle x.length = 2.0 ?
    int main()
    {
        Triangle x; // length = 1.0, width = 1.0
        x.length = 2.0;

        return 0;
    }.

    When we initialize Employee joe do we supply leading commas if we don’t supply an id and age like so Employee joe = { , , 60000.0 } ?

    • Alex

      1) Yes. I’ve updated the example to make it clearer that the 2.0 is just a standard assignment.
      2) I’m not aware of any way to skip initialization values to the left of an initialized value. Why C++ doesn’t support this in the way you suggest, I don’t know.

  • John

    For organizational purposes, it seems that I might want to define a struct within another struct. For example, in the section "Nested Structs" you write the code

    If the struct "Employee" will only ever be used within the struct "Company," then I could combine the two into

    The compiler has no problem allowing me to do this, but you don’t mention it in the lesson. Is doing so acceptable/recommended in C++?

  • Pooja

    Hello Alex,

    Out of curiosity I am asking, Why Union and register types are not included in this chapter?
    Are they available in some other chapter?

  • J3ANP3T3R

    Need help. i noticed that in the quiz i made a wrong script as i had to create two integer variables. the answer to the quiz looks better and faster. however, i should still be able to do some initializing on my struct but it wont let me. says "error C2440: ‘initializing’: cannot convert from ‘initializer list’ to ‘WebsiteEarnings’" what does it mean ?

    struct WebsiteEarnings
        {
            int shown = 0;
            int clicked = 0;
            double earned = 0.0;
        };

    void printWebsiteEarnings(WebsiteEarnings checkWebInfo)
    {
        checkWebInfo.earned = double(checkWebInfo.shown * checkWebInfo.clicked);
        std::cout << checkWebInfo.shown << " X " << checkWebInfo.clicked << " X " << checkWebInfo.earned << std::endl;

    }

    void optCalculateWebProfit()
    {
        std::cout << "nEnter number of Ads shown t: ";
        int ads{ 0 };
        std::cin >> ads;

        std::cout << "nEnter Clicked Percentage t: ";
        int clicked{ 0 };
        std::cin >> clicked;

        WebsiteEarnings webInfo {ads,clicked};
        printWebsiteEarnings(webInfo);

    }

    the error message points to this line of code
    WebsiteEarnings webInfo {ads,clicked};

    • Alex

      You’re using both non-static member initialization AND an initialization list. As the lesson says, in C++11, you can only use one or the other. Although this restriction was removed in C++14, it appears Visual Studio 2015 still doesn’t support this.

  • Jim

    Alex,

    I believe the wording in this lesson is a bit misleading! In the context of this lesson you defined a struct Employee with 3 members (fields).

    Therefore,you just define Employee a new data type here didn’t you?

    After that you wrote that Employee is a variable in various places, this is a bit confusing.

    It seems to me that joe, and frank should be the variable that you are referring to here. Employee can not be change in this context, so it can’t be a variable

    • Alex

      > Therefore,you just define Employee a new data type here didn’t you?

      Yes.

      > After that you wrote that Employee is a variable in various places, this is a bit confusing.

      I can’t find where I said anything like that. Can you paste in the sentence where you think I said this so I can fix it?

      I did say, “When we define a variable such as Employee joe“, the implication here is that joe is the variable, and Employee is the type.

      Thanks!

      • Jim

        Alex,

        The last sentence of your reply cleared up my confusion.
        Employees is the type and joe is the variable.

        "In order to use the Employee struct, we simply declare a variable of type Employee"

        It might have helped if you would have written… we simply declare a variable using the employees first name for the type employee. e.g. employee joe.

        Thanks

  • Seolhyun

    Hi Alex,
    Could you please point out what wrong with may code

    I receive the error:
    |64|error: no matching function for call to ‘Triangle::Triangle(<brace-enclosed initializer list>)’|
    Structs\main.cpp|64|note: candidates are:|

    Finally, thank for your tutor. It’s really useful.

    • Alex

      From the lesson, “Unfortunately, in C++11, the non-static member initialization syntax is incompatible with the initializer list and uniform initialization syntax.”

      You’ve got a non-static member initialization and you’re trying to use uniform initialization, so you’re running into this issue. Remove the non-static member initialization values.

  • K

    Hi, sorry if this is a stupid question but I’m a bit confused with the solution to question 2. I did everything the same except instead of

    it was

    When it was put this way, the answer to (1/2)*(1/2)=0 instead of 0.25 so I changed it to your solution and it comes out as 0.25. As (1/2)*(1/2)=(1*1)/(2*2) I’m just confused. What causes this?

    Again sorry if I’m just having a dumb moment!

    • Alex

      static_cast(f1.numerator / f1.denominator) does an integer division (which causes data loss) and then casts the result to a float (too late).
      static_cast
      (f1.numerator * f2.numerator) does an integer multiplication (which does not cause data loss) and then cases the result to a float so the division that happens just after is a floating point division, not an integer division.

  • Abhi

    Hi,

    In quiz 1, if I use a different function for taking values from user, it returns wierd numbers, why so?

    What’s the mistake?

    • Alex

      Because TakeValue() is not assigning values to main’s version of ad, it’s assigning values to its own local version of ad.

      You could fix this by making TakeValue() return ad, and assign that return value to the ad variable in main.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter

  

  

  

4 × four =