Coding quality is a judgment call. There isn't one right way to do things. Every "rule" can potentially be broken under the right circumstances. So do not turn your brain off, but be constantly evaluating the code you write, and asking yourself what the right choice is, and whether you have a good reason to deviate from the guidelines given below.
In this course, we prescribe a "golden rule" for coding quality: write the kind of code you would like to see in someone else's code if you were asked to work on it.
We don't enforce a specific look and feel for your code, but we expect you to be consistent. Choose an appropriate indentation style for your code and stick with it. Choose an appropriate and visually pleasing policy for use of whitespace and stick with it. Choose an appropriate form of initialization syntax (the new uniform initialization syntax, the older forms, or a disciplined mixture of these) and stick with it.
The appearance of your code is one aspect of what we look for during handmarking, but it is only the tip of the iceberg. Read on ...
Your code must be readable, but this does not necessarily imply that you must write copious amounts of documentation. Well-written code is self-documenting. It is possible for code to be of excellent quality, and easy to follow, without any documentation at all, though in many circumstances, a few well-placed comments would be quite appropriate. On the other hand, needless inline documentation can be a distraction.
To make your code readable, choose meaningful names for variables, functions, classes, etc. Consider using additional parentheses in expressions, rather than relying on the user to remember the entire C++ operator precedence hierarchy. Consider using typedef to give a descriptive name to a complex type expression. Write functions that do a single thing, with an intuitive interface. Write classes that have a single responsibility. Split up complex tasks. Avoid "tricks".
Inline documentation should be used to explain those aspects of your code that would not be apparent to a casual observer. For example, if there is some subtlety that requires this statement to occur before that statement, you might wish to make this a comment. You should also use inline documentation to explain your reasons in those cases where you feel you should "break the rules".
Code that is "commented out" should be removed from your programs before you hand them in, as it may confuse the markers. Debugging statements controlled by preprocessor directives do not have to be removed.
Your first responsibility is to make your code readable. Efficiency is a secondary concern. Before you decide to optimize part of your code for efficiency, make sure the gain in efficiency is worth the effort and the potential loss in readability. For example, it does not matter what algorithm you use to sort a list if the list is guaranteed (or expected) to be short. You will not improve performance, but you will cost yourself time and readability.
Focus on efficiency for the parts of the program that truly matter: for inputs whose size could be very large, or for situations where the most intuitive solution (or your solution) would be especially slow. Programs that are unreasonably inefficient on unbounded inputs will be penalized.
There are habits you can develop that lead to more efficient code (even if only modestly so) without costing you in time or readability. For example, pass arguments by const ref whenever possible, if they are larger than an int. Use const as much as possible, as it helps the compiler generate better code, and helps you to avoid errors. Use the member initialization list (MIL), as it avoids double initialization. Use prefix ++ instead of postfix ++, as it avoids having to remember the previous value of the variable. Use stack-allocated objects, unless there is a good reason to use the heap. These are not premature optimizations. These are simply good habits that avoid needless inefficiency.
Let the compiler help you avoid errors. Write explicit constructors. Avoid casting. Use const as much as possible. Declare overriding methods override. If a class is not meant to be subclassed, declare it final. Use references instead of pointers, unless you'll need to change where they "point", or unless they could be null. Use assertions to help detect coding errors. Keep your code properly encapsulated. Prefer non-member functions over member functions. Minimize friendships.
Less is more: a simple problem should have a simple solution. If you find yourself writing a long program to solve what seems to be a simple problem, ask yourself if you are approaching the problem correctly. We do not expect that your solutions will be the same length as ours, but if they are significantly longer, without a good reason, this may be an indicator that you haven't solved the problem well, and your grade may reflect this.
Never write the same code twice. If you find yourself having to do the same thing more than once, or if you find yourself cutting and pasting code, you may be missing out on an opportunity to build an abstraction. Perhaps you need a helper function. Perhaps you can factor repeated code outside of an if statement. If two functions do similar things, maybe one function should be calling the other. If two classes have methods that do similar things, perhaps there should be a third class that does that thing, that the other two classes could then use.
Think about the structure of your algorithms. There are situations where goto is useful, but they are rare. Avoid "flag" variables. They are sometimes useful, but they are often an indication of poorly-structured control flow. They are hard to keep up-to-date, they create code that is hard to read, and they are an abundant source of bugs. Try to avoid deeply-nested control structures (though, obviously, the nature of the problem will, to some extent, dictate a certain minimum amount of needed nesting).
Think about your solution before you write your program, and come up with a good design. We will accept a variety of approaches to most problems, but if your approach is truly bad, even if it seems to work, we will deduct marks.
In principle, you should NOT be doing anything for this course that requires citing your sources. We require that all the work you submit is your own, original work (except for the portions of code that we provide to you as part of the assignment, which should obviously also be part of the submission). So, if you are looking for solutions or even just for "inspiration" to help you solve the problems we give you, you may be doing something that violates the academic integrity principles and it may put you in trouble even if you cite your sources.
Please note that there are different levels of how much originality is required from your work depending on the context. When you are programming to solve a problem, for example on a job, usually the main goal is to find a solution using the most efficient means possible. If someone else already published a solution to the same problem and said other people can use it, that's the most efficient way! So, in this situation, it is generally fine to use someone else's work with attribution if the author has authorized others to do so.
However, it is different in an academic situation. The main goal here is NOT to find a solution to a problem in the most efficient way (which could be copying a ready solution from somewhere else). No, the main goal is that you learn to create this type of solution independently. And as a secondary goal, we need to evaluate your work so we can assign you a grade that accurately reflects how much you have learned. Therefore, the expectation is that all the work submitted should be your own, independent work. In this situation, even if there are other solutions posted online to similar problems, you should not look at them before you create your own solution. This applies even to the group project; even if the members of the group will be collaborating, you should not be searching for solutions outside the group.
However, this does not prevent you from searching for general knowledge about the language or libraries you are using. You can certainly use websites such as cppreference.com or similar and in fact, we want you to do so because they will teach you how to use C++ and its libraries. You can also use the materials we provide you in this course or any other course you took before. You won't find the solutions to the problems in the assignments on these websites or materials, but you will certainly find information that will help you create a solution. If you use websites like these, you don't really need to cite the source as you're not actually copying the solution to the assignment, you're just checking the documentation. (Although it may be useful to still cite the source if you copy a snippet just in case another student also copied the same snippet. But in general, we know how to recognize if you just copied a snippet of a general way of using C++ from the web or if you copied a solution for the specific problem in the assignment.)
On the other hand, if you start to search for more specific solutions for the problems in the assignment, then you start to go into a situation that can be considered an academic integrity violation because you will be basing your solution on someone else's work, not only in your own work. You should not do this in an academic setting, even if you cite your work (even though this would be probably acceptable if you were solving a problem on a job and just needed to find the more efficient solution).Let's try to give you some concrete examples:
Based on this explanation, you should follow this procedure for this course:
We hope that this helps you avoid issues of academic integrity and puts your effort into learning how to create these solutions independently rather than copying ready solutions from online sources. These are some of the skills that differentiate a Computer Scientist from the average programmer, so we're here to help you develop them!