#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2006
    Posts
    48
    Rep Power
    0

    Question Moving into intermediate C++, learning how to write programs?


    This is a very hard issue to put into words but I will attempt to do so.

    Between 2004-2007 I went to college pursuing a degree in Computer Science AAS-T. So I learned the basics of programming in C++, C#, Java, etc. Over the last few months I have refreshed my memory first in C# and lately in C++. I am sticking with C++ for now. I am doing this on my own, not for any class or anything.

    My goal is to write my own applications and games. And yes, I know the whole spiel everyone always gives on that. I only mention this because that is where my focus and interest is located. That is what I am working towards.

    I know the basics of the C++ language. If you tell me to code something to calculate some value and print it to the screen, I can do that. I understand what an integer is, what a string is, all the way up to arrays, vectors, functions and classes. I also understand the concept of looping, and that games usually run in some sort of a loop state. I understand some more advanced things like pointers, addresses and even polymorphism and inheritance. I know my way around CodeBlocks and Visual Studio Express 2010 fairly well.

    But I am stuck. To give an example, I am working through Michael Dawson's C++ Game Programming book, and one of the assignments is to write a program that will allow a user to add a game title and list the titles they have added. I tried to do this with functions but got errors. I tried to do it all in the main function but got even more errors. I closed CodeBlocks down in frustration and didn't save anything.

    The problem is I understood what to do and for the most part how to do it. But I keep smashing my nose on what I refer to as the "invisible maze." There are all these rules, all these specific ways that things have to be done, so that it doesn't matter if you have memorized the entire language, if you do not know these rules you can't code anything. In other words it is not enough to know the C++ language, you have to know where you can and can not use every single statement or combinations of statements in C++! You also have to know the limits of each and every statement or combination of statements as well as where you can use them. Does that make any sense? Did I explain that well enough?

    In my case I knew how to use vectors and push_back to add something. But how do I use that in a function? I know how to make a console menu and even set up a default case that keeps the user from entering something wrong. But how do I call a function in a switch statement, or can I even? Is this even making sense?

    Now I am not seeking answers to my questions here. I just want to help you understand what I mean when I say I am stuck. If I were to set out and try to code something, more than likely I would smash my nose up against countless invisible walls in the maze of rules that nobody seems to talk about. Go ahead, look in any book. See if it tells you the specifics of where you can or can not use vectors as well as how to use them say in a for loop or a switch statement or a function. I would be surprised if you found anything.

    So this thread is about finding the rule book, making the "invisible maze" visible. Understanding not only the language of C++ but how to make my own programs in it. All this is tied together. I'm seeking a good C++ book or video series that will help in this. Help me transition from console programming to GUI. Teach perhaps the basics of Win32, DirectX or OpenGL. But also explain not only the code I am typing as a follow along, but also the rules for the code. How I can not use something in certain ways, or how I can. Something that instructs using functions, classes, and even separating them out into separate files. It's time to move from coding everything inside the main function, or even on the same page of the main function, to coding it all outside the main function, and calling these things from main. And always, always explaining the rules in exhaustive and annoying detail so that I know exactly how to use any part of the C++ code I am working with.

    I tried YouTube searching for Intermediate C++, Game C++, will try perhaps Beginners Win32 or C++ Rules. I just can't seem to find anything. I will however give you an example that shows the type of tutorials I am looking for, and I recommend this resource to those learning the language:
    http://www.whatsacreel.net76.net/cpptutes.html

    In just a few videos I understood how to construct a game using functions and many of the rules were explained as well, although not as well as I would like. The guy is humorous too which also helps. I'm looking for more tutorials like that, which explain the rules even more in-depth. In book or video form. If you know of anything, would you mind sharing a link? Also what should I look for when searching for learning how to write programs, the process of taking code and making something with it, not just learning the language itself? Also what should I look for to help me understand the rules and see this "invisible maze" so I don't get frustrated trying to write programs? I don't know what words to use, what the right question to ask may be.

    I just want to understand exactly how to use my knowledge of C++ to make stuff. It's not enough to know the language, I want to understand it, understand what I am doing, why it has to be done in whatever specific way it needs to be done, etc. That was the problem I had with Chili's Beginner DirectX lessons. He shows what to code, but explains very little, and hardly mentions the rules, the process of why things have to be done a certain way, at all. I had to quit that series and then I was lucky enough to find What'sACreel?'s videos. But now I have finished them and need something else slightly more advanced.

    My apologies for the long post. I appreciate you taking the time to read it, and I thank you ahead of time for your help.
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    software design

    You might be able to build a garden shed with just a hammer, nails, saw and a few planks of wood, but when it comes to building a house, you need a PLAN.

    First you need requirements (what do you want). For assignments and exercises, the requirements are laid out in front of you.

    The next step is design (how you're going to do it). Here you break the problem down into successively smaller and smaller steps (adding detail as you go). If the task was "build a toast making robot", the obvious first division is "toaster" and "robot".

    When you've decomposed the problem into sufficiently small components (that is, you can see an obvious way of implementing it), then you can start coding.

    Yes, this will be hard at first, and you'll make many design mistakes, but it is an essential skill if you want to be more than just a cubicle monkey. But like any skill, you get better with practice.

    When you write code, do so in small steps of "edit, compile, test". This is typically done one function at a time. When you have a few functions, try making a test which exercises all of them together.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    In addition, if you are going to add a technique to your program, such as reading input in a certain format or adding a data structure (eg, a linked list, queue, stack, binary tree), then first develop and test it out in a separate smaller program that only exercises that technique. Once you have worked out all the problems and feel confident about it, then integrate it into the program.

    This can also be used to figure out why something in your program doesn't work. Copy the problematic code out into a small test program and debug that. Then when you discover the error, you can correct it in the original program. It is so much easier to debug a small program than it is a large application.

    When testing your code, one approach is, as salem suggested, to test each function. A systematic way to do this is to write a test driver, which is usually little more than a program with a main() function that calls the function multiple times with different arguments, reporting the results of each function call. It can be as simple or as elaborate as you want it to be. In order to know what arguments to use, you need to determine what range of values the function will handle, which will help you to determine its boundary conditions. Then you use arguments that will test the range of values and the boundary conditions. Boundary conditions can be when a data structure is empty or full, or when an expression approaches a singularity (refer to calculus; eg, what happens to (42/(x-3)) when x==3 or as x approaches 3 from either direction?), or when a wrong value is input.

    Look into some style guides as well. I learned a lot from Scott Meyers' Effective C++ and can recommend it. You should also choose and use a indenting style and be very consistent in using it. I personally very much prefer the Allman. You choice should be one that makes your code more readable and easier to understand. That is not only for the benefit of others, but mainly for your own benefit. If you don't, then you will be making it much harder for yourself to spot your own mistakes.

    Also, develop or adopt a system of version control. As you make changes to your code, you may find that some of the changes you made have broken something that used to work, or else you decide that you don't want to use those changes after all, so you will need to still have the old code to be able to go back to it. Also when something suddenly doesn't work anymore, it helps a lot to be able to compare the new version with the older version to see what had changed so that I can try to figure out what has caused the problem. So in addition, you should look into a utility for comparing files and displaying the differences. We use a commercial version control program and for comparing files we use Beyond Compare, which is very affordable. Earlier for version control, I would create new sub-directories to store each version's source files into. The important thing is to develop the discipline of saving older versions in order to back yourself up as you are developing your program.

    Obviously, we cannot download all our knowledge to you. While a few of the things that salem and I (mostly salem) have told you will be taught in school, the real world of programming and software development is very different from school. In school, you work alone writing a program that fits in one single source file and whose life cycle ends at the end of the semester if not the moment that you turn in that assignment. In the real world, you will be working as part of a team (hence the importance of the readability of your code as well as your ability to conform to a specific style that management will impose on you), the source code can easily consist of over 100 source files, and the program will remain in use for several years, even decades. In school, all you are doing is the initial development of the program mainly for the purpose of learning how to use the language. In the real world, the vast majority of your work is in maintenance. Bugs will be discovered that you will need to fix. New features will need to be added which you will need to add while keeping the rest of the program working correctly. Both those tasks depend absolutely on the code's organization and readability -- after a few months, you will be unable to recognize even your own code, let alone remember what it did and why you did it that way, so you will very much need to be able to read your own code. And far worse, that program will then form the baseline for several other software products, which brings us back to what salem told you about: the design of the program. The initial design of the program will determine how hard or how much more doable all those tasks of creating and maintaining the code, as well as adapting that code into new products. They don't teach you those things in school, or else when a professor mentions it the students don't realize how important what he just said really is.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2006
    Posts
    48
    Rep Power
    0

    Post


    Thank you both for your replies. I do appreciate the information you have shared. However it seems my question was not clear enough, so I will provide another example:

    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
        vector<string> games;
    
        cout << "1. Add" << endl;
        cout << "2. List" << endl;
        cout << "3. Exit" << endl;
        cout << "> ";
    
        while (true)
        {
            char answer;
            cin >> answer;
    
            switch(answer)
            {
                case '1':
                        string title;
    
                        cout << "Enter the game's title (q to quit):" << endl;
    
                        while(title != "q" && title != "Q")
                        {
                            cout << "> ";
                            cin >> title;
                            if(title != "q" && title != "Q")
                                games.push_back(title);
                        }
                    cout << "1. Add" << endl;
                    cout << "2. List" << endl;
                    cout << "3. Exit" << endl;
                    cout << "> ";
                    continue;
    
                case '2':
                        cout << "These are my favorite games:" << endl;
                        for(int i = 0; i < games.size(); ++i)
                            cout << games[i] << endl;
                    break;
    
                case '3':
    
                    return false;
    
                default:
                        cout << "\nThat was an invalid response!" << endl;
                        cout << "> ";
                    continue;
            }
            break;
        }
        return 0;
    }
    This is the program I was referring to, after I have been working on it. I still can't get to accept titles with more than one name BTW. Anyhow if you were to compile this it would not run, you would some errors, here is one of them:
    crosses initialization of 'std::string title'

    It turns out that string can not be run in a switch statement like this. Here then is an example of one of those walls in the invisible maze I was referring to. Thankfully after I smacked into this one I was able to Google a solution:

    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
        vector<string> games;
    
        cout << "1. Add" << endl;
        cout << "2. List" << endl;
        cout << "3. Exit" << endl;
        cout << "> ";
    
        while (true)
        {
            char answer;
            cin >> answer;
    
            switch(answer)
            {
                case '1':
                    {
                        string title;
    
                        cout << "Enter the game's title (q to quit):" << endl;
    
                        while(title != "q" && title != "Q")
                        {
                            cout << "> ";
                            cin >> title;
                            if(title != "q" && title != "Q")
                                games.push_back(title);
                        }
                    cout << "1. Add" << endl;
                    cout << "2. List" << endl;
                    cout << "3. Exit" << endl;
                    cout << "> ";
                    }
                    continue;
    
                case '2':
                    {
                        cout << "These are my favorite games:" << endl;
                        for(int i = 0; i < games.size(); ++i)
                            cout << games[i] << endl;
                    }
                    break;
    
                case '3':
    
                    return false;
    
                default:
                    {
                        cout << "\nThat was an invalid response!" << endl;
                        cout << "> ";
                    }
                    continue;
            }
            break;
        }
        return 0;
    }
    Who would have thought that simply adding brackets, making each case a separate block, would fix the problem? Well is this in any book on C++ programming? Any video tutorial? Let's see... I have about half a dozen books and one reference, pretty sure without looking that this is not in there. Nor has any video I ever watched mentioned this. And don't tell me, "Well you just have to code stuff like this, get errors, get frustrated, Google your brains out, that's how you learn." Because that's a big stinking pile of crap.

    I'm looking for more than just how to construct a program. I know all about psudeo-code, working with smaller parts, etc. Good advice, but I am well aware of this. I guess what I mean is how do I learn how to make a program without the rule book? Sure I could pseudo-code something, follow the basic usage information everyone provides, but chances are an error like this string thing will pop up. It would be nice to know about these things before I try to code something.

    Well I hope that clarifies things. I do appreciate the help and responses. I understand this is a tough question to answer.
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    That's just simply scope, more specifically local scope. It's a basic concept that all C++ text books should cover.

    Don't throw away the "rule book". Always keep it standing by as a reference. And maybe review it now and again to refresh your memory about things like local scope.

    Have you learned any foreign languages? Have you ever heard of Berlitz? That was a chain of schools that started around 1900 for teaching languages; in mid-century Berlitz also sold learning aids, including phonograph records. A linguistics major in my Russian class described the Berlitz Method as "memorizing a million and one sentences and hoping that one of them will come up in a conversation." I mention that because it seems to describe what you are saying that you're looking for.

    Instead, become as thoroughly familiar with the grammar as you can be, while learning to express your ideas in that language (be it human or C++). Learn the concepts that the language uses and depends on, such scope. And learn to read code in order to understand what it is saying. Just as with a human language, get to the point where you can start to think in that language; at that point you will have largely internalized knowledge of the grammar and using the syntax so that practically all you need to do is to think about what you want to say and you will produce the code syntactically correct. And when you read code, you will be able to feel when something doesn't look quite right. And when you get error messages and warnings (which are far more important than error messages are), you will understand what they are telling you.

    All it takes to get to that point is lots and lots of practice and experience. No "rule book" or any other book will do it for you; there is no Royal Road to programming. You just need to keep working at it until it becomes second nature.
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    How about beginning with the basics of using some functions rather than piling everything into a big unmanageable main.

    Say
    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    void showMenu()
    {
      cout << "1. Add" << endl;
      cout << "2. List" << endl;
      cout << "3. Exit" << endl;
    }
    
    istream & prompt(char &answer)
    {
      showMenu();
      cout << "> ";
      cout.flush();
      cin >> answer;
      return cin;
    }
    
    void doInput(vector < string > &games)
    {
      string title;
    
      cout << "Enter the game's title (q to quit):" << endl;
      while (title != "q" && title != "Q") {
        cout << "> ";
        cin >> title;
        if (title != "q" && title != "Q")
          games.push_back(title);
      }
    }
    
    void doPrint(vector < string > &games)
    {
      cout << "These are my favorite games:" << endl;
      for (int i = 0; i < games.size(); ++i)
        cout << games[i] << endl;
    }
    
    int main()
    {
      vector < string > games;
      char answer;
    
      while (prompt(answer)) {
        switch (answer) {
        case '1':
          doInput(games);
          break;
        case '2':
          doPrint(games);
          break;
        default:
          {
            cout << "\nThat was an invalid response!" << endl;
          }
          break;
        }
      }
      return 0;
    }
    > I still can't get to accept titles with more than one name BTW
    You need to use getline instead of >>

    > It turns out that string can not be run in a switch statement like this
    Of course it can, but you have to write it like this.
    Code:
            switch(answer)
            {
                case '1':
                {
                        string title;
                        // rest of code
    Without the extra { } creating a scope within a specific case, what you have looks like this (to the compiler).
    Code:
            switch(answer)
            {
                string title;
                case '1':
    
                        cout << "Enter the game's title (q to quit):" << endl;
    
                        while(title != "q" && title != "Q")
    Since the declaration of the variable binds closely to the opening brace, you get the situation that the initialisation is skipped by the 'goto' for the first case.

    > I have about half a dozen books and one reference, pretty sure without looking that this is not in there.
    I'm losing my will to care, if you just dismiss every problem as "it won't be in my books".

    Besides, it doesn't matter how many books you have that go unread, there is only so much you can learn from reading. The rest comes from practical experience

    > I know all about psudeo-code, working with smaller parts, etc.
    So show it, by writing functions then!
    A bloated main full of copy/pasted blocks (your menu for example) surely isn't demonstrating to us that you have any knowledge of these things.

    > It would be nice to know about these things before I try to code something.
    Q: How do I avoid mistakes
    A: By having experience.
    Q: How do I gain experience.
    A: By making mistakes.

    You seem to be stuck with the notion that any program is written bug-free in one sitting, and that simply isn't true. Any decent sized program will be written in small steps, will undergo some major rewrites, and may even be thrown in the bin and a fresh start made.

    It's not like you're cutting diamonds, where one wrong move will cost somebody $$$$, it's software (emphasis on soft). Enjoy the freedom to make mistakes and learn as you go.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2006
    Posts
    48
    Rep Power
    0
    Thank you both for your responses. I guess I was just getting tired of trying to write a program that I think logically should work, based on everything I have learned about the language, only to come up against some strange error because there is some rule or something I didn't know about. It's just very frustrating. Found another one today with using setw and fill. Finally was told that fill works for all following output, while setw works only on the next output then resets. But none of this was in the book I am working through. It's hard when you put something together that looks as if it should work, it seems to follow all the rules, but no, there is some small little fly in the ointment nobody bothered to tell you about.

    However I am beginning to understand that I am just going to have to deal with it. Plow ahead, keep learning the language, and someday I'll be able to think logically along within the bounds of C++ as I write programs.

    Anyhow enough complaining... You have all given excellent advice and I have saved this thread to refer back to. For the record I did try making this program work with functions but I hit more walls getting that to work, so that's why it's all in main, or else I would be even more frustrated. But that was my first attempt, to make functions for the various parts of the program. I just gave up when I ran into more invisible walls.

    Thanks again!
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Don't just rely on your book. Read the documentation, AKA "Read The Manual!" (RTFM!). You cannot depend on an author to tell you everything about a function or a feature, but you can depend on the documentation and on the language standard. The information is out there, but you need to look for it.

    And experiment with it. Even when you're working on a major project, write little test programs where you try out various features and techniques. You'll learn a lot just by doing and seeing what you need to do to make things work the way you want them to.

    And always remember the age-old programming maxim: Computers don't do what you want them to do, but rather only what you tell them to do. The trick is in making the two the same thing.

IMN logo majestic logo threadwatch logo seochat tools logo