This page contains a list of recommended "best practices" and "idioms" that deal, for the most part, with program development and coding activities using Java or C++. Some of the items are language-independent and some pertain more directly to one or the other of these two languages.

For Java or C++ (and probably lots of other languages)

  1. Pay attention to detail. Remember that "Carelessness Costs!". This can be a life-and-death thing in certain situations, as we all know. In a programming context, no one should have to remind you not to be careless with your code, so we won't. But there is another area in which students, unfortunately, need continual reminding, and it's this: documentation. Documentation should be given the same care and attention as every other aspect of your program development. This means more than just having complete and correct information in your documentation. In addition, it means paying attention to English grammar, spelling, punctuation, subject/verb agreement, proper use of singular and plural, and the like. In an academic context, carelessness in this area can simply cost you points on a homework submission. In the real world, it can give those reading what you have written a lack of confidence in your abilities. The implicit question that may be in the mind of the viewer is this one: If this person has not paid attention to those details, what other details have also been ignored? [Google "Van Halen and brown m & m's" for an interesting, and related, story.]
  2. Use a single Test project. When using and IDE (Integrated Development Environment) such as NetBeans, Eclipse, JCreator, or Visual Studio for testing sample programs that have been supplied by your instructor, or for developing short sample programs of your own, it's simpler and more convenient to use a single project called "Test" (for example). You can then move the individual sample programs in and out of this one project as you test them. This is "better" than creating a separate project for each sample program, which will quickly lead to serious "clutter" in your account. You can also follow this general principle even if you are just using and editor and compiling at the command line.
  3. Make sure your source code contains no TAB characters. Source code that contains TAB characters may print differently on different printers, or may display differently when viewed in a console window from how it displays when viewed in an IDE editor (NetBeans or Visual Studio, for example). In particular, it may not come out on a hard copy formatted as you had intended, or as it looked on the screen. Any of these situations may arise when you have TAB characters in your source code files. Each such situation will probably make your code much harder to read, and may well cause you lost points.
  4. Make sure your source code lines are not too long. What does this mean? For our purposes it means this: Source code that will be evaluated in any way will be either printed out, or observed on a screen that may not be wider than 80 characters, and you should therefore make sure your that your source code lines are all strictly less than 80 characters long (a maximum of 72 characters is recommended). Failure to do this will likely mean that your code will contain "wrapped" lines, making it much harder to read, and thus costing you lost points.
  5. Submit early and often. When you are developing an assignment to be handed in via the Web, it is a good idea to "submit in stages". That is, you should be developing your solution in such a way that, at several times during the development, you are a stage where your program is working, exhibits a good programming style, and the working parts are fully documented. If so, submit it at that stage. Why? Well, doing so will help guide your development process and get you familiar with the submission procedure, for one thing. For another, should—God forbid—something go wrong, or should you run out of time at the end and not be able to submit your final version, you would have at least something already submitted.
  6. Terminate most console programs with a pause. Make sure that most console programs you write that are designed to interact directly with a human user have a "pause" at the very end, so that if such a program is run by double clicking on it in Windows, the console window that opens to run it will have the pause at the end. This will avoid the potential problem of the user "missing" some or all of the output from your program when that console window closes abruptly as your program ends. When testing programs within an IDE that supplies a pause automatically after a program finishes running, this point is often overlooked. On the other hand, if the console program is designed to be simply a "utility" program that takes some input from a file or the command line and writes some output to a file (for example) this "best practice" may not need to be followed.
  7. Make sure any textfile has a newline character at its end. Some operating systems, or at least some editors on some operating systems, make sure that there is a newline character at the end of a textfile when the file is saved. This is an excellent idea, and simplifies the processing of such files. So, as a "best practice", it is a good idea to make sure that any text file being processed by one of your programs has a newline character at the end. One way to do this is to load the file into an editor and move the cursor to the end of the file, at which point the cursor should be on a line by itself, and at the beginning of that line. The alternative, of course, is to write more complicated code to deal with the possibility that there might not be a newline character at the end of a file that you have to process.
  8. Use "setters" and "getters" in your classes. For class member functions that either set or get the value of a data member (i.e. that either assign a value to, or return a value from, a class data member), use a consistent naming scheme that begins with "set" or "get", as the case may be, and is followed by the name of the thing being set. For example, in a Time class you might have both a setHours() member function and a getHours() member function. This convention is consistent with widespread current practice, and is independent of any other naming or capitalization conventions that may be in place.
  9. Format prompts properly. If a console program prompts the user for input which is to be entered on the same line as the prompt, ensure there is a blank space between the end of the prompt and the start of the entered input. Such a prompt should normally end with a colon, or possibly a question mark, depending on the nature of the prompt.
  10. Make use of canonical input/output algorithms. It is almost always a good idea to use input and output algorithms that implement the following pseudocode:
    For input
    ---------
    Open the stream from which input data is to come
    If unsuccessful report the problem and return (or exit)
    Try to read the first input data item from the input stream
    while successful
        Process the data item
        Try to read another data item
    endwhile
    Close/clear the input stream
    
    For output
    ----------
    Open the stream to which output data is to go
    If unsuccessful report the problem and return (or exit)
    while there is more output data
        Write next data item to the output stream
    endwhile
    Close/clear the output stream
    
    Note that if the input stream is standard input and/or the output stream is standard output, the opening and/or closing of the stream may not be necessary or desirable. Furthermore, the pseudocode does not include any error checking, which is always a good idea and should normally be part of the actual code.
  11. Position variable declarations to enhance readability When declaring a variable, place its declaration as close as possible to where the variable is used, particularly if the variable is only used once. Variables used many times may have their declarations grouped and placed as near as possible to the first use of any variable from that group. Whenever possible, declare a for-loop control variable in the for-loop itself, which limits the scope of the variable to the loop in which it is declared.
  12. Clear an input stream after reading from it. This is just good programming practice, after all. But it also means that your program will not suffer from hard-to-track-down bugs caused by a subsequent read that is actually reading one or more "left-over" characters from previous input, rather than what you think it is reading. Failing to do this is one of the most frequent causes of the "bug" that shows up when you try to make the output from your program "pause" for the user to read it, and it does not pause when it should. This advice applies whether you are reading input from standard input or from a textfile.

For Java

  1. Put a main() in every class Get into the habit of writing a main() test driver for each of your classes. This allows you to test your class "in isolation" and make sure it's working properly before including it within a larger context.
  2. Close any file when your program has finished reading from it or writing to it Though the operating system may do this for you when your program ends, you should not rely on this happening, and you may run into trouble if you neglect to do so and then try to use the same file (or the same file variable) for another purpose later in your program.
  3. Understand jar files Make sure you know how to create executable jar files to "package" your programs into a single executable file. [Note: The term "package" as used here does not refer to the Java package statement.]
  4. More to come ...

For C++

  1. Give your source code files informative extensions Use the following extensions for your source code files:
  2. Use automatic string concatenation. When sending multiple lines to the standard output with a C++ cout statement, use "automatic string concatenation" combined with one or more trial runs to find the position(s) within the text where \n needs to be inserted to produce line breaks. So, for example to output the previous sentence, begin by writing
    cout << "When sending multiple lines to the standard output "
        "with the C++ cout statement, use \"automatic string "
        "concatenation\" combined with one or more trial runs "
        "to find the position(s) within the text where \\n needs "
        "to be inserted to produce line breaks.";
    
    which makes use of "automatic string concatenation". (That is, you do not need to place an insertion operator << in front of the second to fifth lines in the above code segment.) Then compile, link and run the program containing this code, observe and note where the displayed lines "wrap around", and then revise the code so that it contains \n in the appropriate places to produce a sufficient number of line breaks in the output to give a pleasing display.
  3. Close a file when finished with it and clear a file after closing it. It is a good idea to "clear" a file variable after closing it. Much of the time this may be unnecessary, since (for example) the operating system may close a file for you after your program exits. But, for those times when it may be very necessary to do so (like the case where you want to use the file variable again later in the same program, perhaps), getting into the habit will save you some agony and possibly some embarrassment. So, think of this as a potentially face-saving "idiom":
    someFile.close();  someFile.clear();
    
    Note that the two statements are shown written on the same line. Normally it is a better idea to have one statement per line in your source code. However, in a case like this where the two statements are "intimately connected" and form an "idiom", writing them both on the same line (since both are very short as well) emphasizes the connection between them, and hence may be excused (if an excuse is necessary) on those grounds.
  4. Consider writing error messages to cerr, not to cout. This may be a good idea for the simple reason that cout is more likely to be "redirected" (to a file, say), which may cause the user to miss an important error message. Writing errors to cerr is a better way to ensure that they appear on the user's console, where they are more likely to be observed in a timely manner, even if after the program has actually run. On the other hand, if the program is designed to be used exclusively in interactive mode with the user at a console entering input and observing ouput as the program is running, writing errors to cout is fine. The bottom line is to make sure the user does not "miss" anything that the user should see, whatever may be the destination of any part of the output.
  5. Explicitly include any required header files. You might think you're required to do this anyway. But no. For example, many C++ programmers are accustomed to rely upon the inclusion of <iostream> to provide facilities from the ios, istream, and ostream classes. But the C++ Standard does not require this, and in any case it is just good programming practice to include explicitly each header file you need, even if it might be automatically included or included by another header you are using. This is one of the more difficult "best practices" to follow rigorously, for the simple reason that it takes a bit of effort to find out exactly where things are located in the class hierarchy and which header files include what. But this effort can also be good learning experiencej, and it will most certainly make your code more portable.
  6. Protect your own header files from "double inclusion" Whenever you write a .h or .hpp header file that may be included in one or more other files in your project, be sure to protect it from "double inclusion" with the following three lines:
    #ifndef FILENAME_H
    #define FILENAME_H
    ...file contents except for initial comment here...
    #endif
    
  7. Use the idiom for processing C-strings. The simplest way to process every character in a C-string s is to use the idiom suggested by
    for (int i=0; s[i]; i++) Process(s[i]);
    
    since this loop will terminate when s[i] is the '\0' (null) character, as it eventually must become, in a C-string.
  8. Use the "get a value and move along" idiom where appropriate. This is the idiom that returns a value in an array or a container and then moves to the next value in that array or container, as in these examples:
    cout << a[i++];
    cout << *p++;
    
    In the first line, the value of the array a at index i is displayed, after which the index i is incremented. In the second line, the pointer (or iterator) p is dereferenced and the resulting value displayed, after which the pointer (or iterator) p is incremented. Note that, for this idiom to work, the postfix form of the increment operator ++ is required. A similar idiom applies, of course, to analogous expressions involving the postfix decrement operator --.