CS253: Software Development with C++

Spring 2018

Pet Peeves

See this page as a slide show

CS253 Pet Peeves

void main()

made at imgflip.com

endl vs. '\n'

cout << "just" << endl;
cout << "kill" << endl;
cout << "me"   << endl;
cout << "now"  << endl;
just
kill
me
now

endl vs. '\n'

Here’s a better way:

cout << "just" << '\n'
     << "kill" << '\n'
     << "me"   << '\n'
     << "now"  << '\n';
just
kill
me
now

Or, perhaps:

cout << "just\n"
     << "kill\n"
     << "me\n"
     << "now\n";
just
kill
me
now

ASCII constants

There is no benefit to memorizing the ASCII table, at the cost of program readability.

char c1 = 65;     // Sure, this works.
char c2 = 'A';    // But so does this.
cout << c1 << c2;
AA

Doing work for the computer

Doing work for the computer is like cleaning up for the maid. I see code like this:

    inches = miles * 63360;  // 63,360 inches in a mile

When I ask the student, “How’d you come up with that number?”, I often hear “I multiplied 5280 by 12 on a calculator.” Gosh—that sounds like something that the computer should be doing:

    inches = miles * 5280 * 12; // 5280 feet/mile, 12 inches/foot

The compiler will fold the constant multiplication for you.

Indentation

Indentation is often regarded as useless. As long as the program works, that’s all that matters!

Those of us who have to read and maintain your code disagree.

Casting

Casting is not magic.

char buf[] = "123";
long n = (long) buf;
cout << n << '\n';
140734441652740

If you use casting, then something is wrong. Think again.

vector/string methods

Java programmers love .at(), and refuse to learn about [].
.at() does error checking, [] usually doesn’t.

vector<int> v = {11,22,33};
for (size_t i=0; i<v.size(); i++)
    cout << v.at(i) << ' ';
for (size_t i=0; i<v.size(); i++)
    cout << v[i] << ' ';
11 22 33 11 22 33 

Do we really need error checking in that code? Do we suspect that i may get out of range?

Similarly, for strings:

string s = "Jack Applin";
cout << "My initials are " << s[0] << s[5] << '\n';
My initials are JA

Not everything is a reference

You do not have to use new to create an object:

string s;
s.push_back('C');
s += 'S';
s += "U";
cout << s << '\n';
CSU

eof() does not predict

$ wc -l /etc/resolv.conf
4 /etc/resolv.conf

eof() does not mean “Will the next read fail?”.

ifstream in("/etc/resolv.conf");
while (!in.eof()) {
    string s;
    getline(in, s);
    cout << "** " << s << '\n';
}
** search cs.colostate edu colostate.edu
** nameserver 129.82.45.181
** nameserver 129.82.103.78
** nameserver 129.82.103.79
** 

eof() means “Did the previous read fail?”.

ifstream in("/etc/resolv.conf");
string s;
while (getline(in, s))
    cout << "** " << s << '\n';
** search cs.colostate edu colostate.edu
** nameserver 129.82.45.181
** nameserver 129.82.103.78
** nameserver 129.82.103.79

Boolean is hard!

It’s ok to use boolean values as values, not just in if and while:

char c = 'a';
bool vowel;
if (c=='a' || c=='e' || c=='i' || c=='o' || c=='u')
    vowel=true;
else
    vowel=false;
cout << boolalpha << vowel << '\n';
true
char c = 'a';
bool vowel = (c=='a' || c=='e' || c=='i' || c=='o' || c=='u');
cout << boolalpha << vowel << '\n';
true

Return is easy

return is not a function, so parentheses are not required:

int main() {
    cout << "Hello\n";
    return 0;  // Note lack of parens
}
Hello

throw

string s = "bonehead";
cout << s.at(12);
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at: __n (which is 12) >= this->size() (which is 8)
SIGABRT: Aborted

User: Guest

Check: HTML CSS
Edit History Source

Modified: 2018-04-24T16:55

Apply to CSU | Contact CSU | Disclaimer | Equal Opportunity
Colorado State University, Fort Collins, CO 80523 USA
© 2018 Colorado State University
CS Building