Generating a musical scale from a root note I'm looking to improve my coding skills. I am new to programming, and after weeks of research and trial and error - I have successfully wrote this basic program to find a music scale by inputting a Root note and Scale.

Since I am pretty much teaching my self - I am looking for criticism to improve my syntax/programming. I compressed the code listed below and localized variables into a 46 line version of this program but really like the layout of the original, so please be brutally honest. Pros and Cons with explanations please?

Note: I was purely being lazy by using #define and plan to replace all strings and vectors with their correct std::typename.

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;map&gt;

#define astring std::string
#define cvector std::vector

astring rootnote = "";
astring scale = "";
void notation();
int root;
cvector&lt;astring&gt; notes;
cvector&lt;astring&gt; order;
void scaler();


int main()
{
    while (rootnote != "null") {

        std::cout &lt;&lt; "Please enter your root note and scale: " &lt;&lt; std::endl;
        std::cin &gt;&gt; rootnote &gt;&gt; scale;

        std::cout &lt;&lt; "\nroot scale: " &lt;&lt; rootnote &lt;&lt; " " &lt;&lt; scale &lt;&lt; std::endl;
        std::cout &lt;&lt; std::endl;

        notation();
        scaler();
    }

    return 0;
}

void notation()
{
    notes.clear();

    cvector&lt;astring&gt; chromatic = { "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B" };

    root = std::distance(chromatic.begin(), std::find(chromatic.begin(), chromatic.end(), rootnote));

    for (int i = root; i &lt; chromatic.size(); i++) { notes.push_back(chromatic[i]); }
    for (int j = 0; j &lt; root; j++) { notes.push_back(chromatic[j]); }

    return;
}

void scaler() {
    order.clear();

    std::map&lt;astring, cvector&lt;int&gt;&gt; scales;
    scales["Major"] = { 0, 2, 4, 5, 7, 9, 11 };
    scales["Minor"] = { 0, 2, 3, 5, 7, 8, 10 };
    scales["Melodic"] = { 0, 2, 3, 5, 7, 9, 11 };
    scales["Harmonic"] = { 0, 2, 3, 5, 7, 8, 11 };

    for (auto i : scales[scale])
        order.push_back(notes[i]);
    for (int j = 0; j &lt; order.size(); j++)
        std::cout &lt;&lt; order[j] &lt;&lt; " ";

    std::cout &lt;&lt; "\n\n" &lt;&lt; std::endl;

    return;
}
Yikes — the global variables make this spaghetti code.  Functions should make it obvious what their input parameters are, and return their output values.  You'd be better off lumping everything into one main() function than using global variables.  Ironically, the two variables that should have been global constants — chromatic and scales — weren't.

It is customary to put main() last, and helper functions first, so that you don't have to write forward declarations.

You used std::find() and std::distance(), so you should #include &lt;algorithms&gt; and &lt;iterator&gt;.  I suggest listing your includes alphabetically.

Behaviour

Please enter your root note and scale: 
F# Major

root scale: F# Major

C D E F G A B 


If the rootnote is not found in chromatic, you should handle that case instead of blindly proceeding based on chromatic.end().

Please enter your root note and scale: 
D Major

root scale: D Major

D E Gb G A B Db 


Those enharmonic equivalents will sound the same, but those should technically be F♯ and C♯.

Please enter your root note and scale: 
null blah

root scale: null blah


Making the user enter the magic word "null" as the root note to exit the program is weird.

Suggested solution

#include &lt;algorithm&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;map&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

const std::vector&lt;std::string&gt; chromatic = {
    "C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"
};

const std::map&lt;const std::string, const std::vector&lt;int&gt;&gt; degrees = {
    {"Major",       { 0, 2, 4, 5, 7, 9, 11, 12 }},
    {"Minor",       { 0, 2, 3, 5, 7, 8, 10, 12 }},
    {"Harmonic",    { 0, 2, 3, 5, 7, 8, 11, 12 }},
    {"Melodic",     { 0, 2, 3, 5, 7, 9, 11, 12 }}
};

std::string scalenotes(const std::string&amp; rootnote, const std::string&amp; scale) {
    int root = std::distance(chromatic.begin(), std::find(chromatic.begin(), chromatic.end(), rootnote));
    if (root &gt;= chromatic.size()) {
        return "";
    }
    std::stringstream ss;
    for (int i : degrees.at(scale)) {
        ss &lt;&lt; chromatic[(root + i) % chromatic.size()] &lt;&lt; " ";
    }
    return ss.str();
}

std::stringstream ask(const std::string&amp; question) {
    std::string line;
    std::cout &lt;&lt; question;
    std::getline(std::cin, line);
    return std::stringstream(line);
}

int main()
{
    std::string rootnote, scale;
    while (ask("Please enter your root note and scale: ") &gt;&gt; rootnote &gt;&gt; scale) {
        std::cout &lt;&lt; "\nroot scale: " &lt;&lt; rootnote &lt;&lt; " " &lt;&lt; scale
                  &lt;&lt; ": " &lt;&lt; scalenotes(rootnote, scale) &lt;&lt; "\n\n";
    }
}