![]() |
![]() |
#1 (permalink) |
/nɑndəsˈkrɪpt/
Location: LV-426
|
c++ newbie question
Been learning some very basic C++... My question concerns the following block of code:
Code:
//A program to count words in a sentence #include <iostream> #include <string> std::string sentence; int spaceCounter = 0; int current; int main() { std::cout << "Sentence: "; std::cin >> sentence; int lengthOf = sentence.length(); for(current = 0; current <= lengthOf; ++current) { if(sentence.at(current) == ' ') ++spaceCounter; } std::cout << spaceCounter + 1 << " words.\n"; return(0); } Code:
$ ./spaceCounter Sentence: a simple sentence 3 words. Code:
$ ./spaceCounter Sentence: a simple sentence Aborted ![]() |
![]() |
![]() |
#2 (permalink) |
Location: Waterloo, Ontario
|
I'm going to take a guess that it's your for() loop conditions. It's a newbie off-by-one error. Suppose there are n characters in the string. Your for() loop is accessing 0, 1, ... , n-1, n. But if you count the elements of this sequence, you'll see that there are n+1 of them! Something's amiss, no?
Rule of thumb is that if n is the number of elements you want to iterate over, you start at 0 and continue while you are strictly less than n. What you should really be doing is to understand what you're accessing. What your conditions are and why? This just requires you to think carefully about what you are doing and you will get better at it with practice... So, your for loop should look like this: Code:
for(int current = 0; current < lengthOf; ++current) { // strictly less than if(sentence.at(current) == ' ') ++spaceCounter; } Edit: mild addition to make my point more clear... Last edited by KnifeMissile; 02-08-2004 at 09:54 PM.. |
![]() |
![]() |
#3 (permalink) |
Fast'n'Bulbous
Location: Australia, Perth
|
Another rule of thumb: Don't do pre-incrementing!
![]() ![]() It's generally unintuitve for humans to think that way? isn't it. ie. none of this -> ++myValue instead do this -> myValue++ That way the value is changed afterwards, instead of before. Although, in a for loop i believe it stays the same, but it's a bad habit to get into! post increments!!!!! [EDIT] from Resource standard metrics Quality Notice No. 7 Emit a quality notice when a pre-increment operator '++' is identified within the code. Language: C and C++ for preprocessor anomalies and C, C++ and Java for understandability of the code. Rationale: The pre-increment of a variable occurs before the remainder of the processing in the statement. This can be difficult to comprehend or anticipate. There are documented cases where the mathematical results vary between the result of macros when different code preprocessors expand the macros into a normal form. List Of Quality Notices/Standards [/EDIT] Also, even though if or for statements (or other condition logic) is only one line long, make sure you still bound it with the curly braces{} It's got to do with readibility and integrity of the coding. Surely there are some good coding standards published on the web? They're important habits to learn, as you learn, otherwise they could be hard to break ![]() also, as knifemissle pointed out, try to keep variables local to what they're used for. Globals are bad news ![]() Sorry, but i am a little bit of a code quality/standards whore ![]() Last edited by Sleepyjack; 02-08-2004 at 11:16 PM.. |
![]() |
![]() |
#4 (permalink) |
Junkie
Location: San Francisco
|
I don't think preincrementing is unintuitive, and I don't think it's a bad coding practice either. In fact to me it's more intuitive. If you know the difference between the two and the rest of your code is clear and well-written it should make no difference which one you use on a regular basis. Combining either one with other operators (and combining ANY operators with macros) in the same statement is a bad idea in the first place because the intent can be unclear. Using macros is just a bad idea in general; the only reason they even exist in C++ is for backward compatibility with C.
On another note, I give my congratulations to Prince for being a new C++ coder who actually writes standard code. |
![]() |
![]() |
#5 (permalink) |
Location: Waterloo, Ontario
|
I disagree that coding standards are, at all, important. There is so much about writing software to concern yourself with and this is simply not one of them. Do what feels is natural to you (and those you work with) and it'll be fine.
Some people fight holy wars over what indentation style to use. I'm just happy if there's any indentation at all! For the record, I only indented my example code like that 'cause these code blocks are double spaced for some insane reason and I didn't want such a small and simple code snippet to look so sparse. I do wish Halx would fix that... I don't know what the issue against pre-increment is supposed to be. Macros can be used to screw anything up, pre-increment, post-increment, or no increment at all! I agree with n0nsensical in that I dislike using the increment operator in combination with anything else, so there's not much to be unintuitive about... |
![]() |
![]() |
#6 (permalink) | |
Fast'n'Bulbous
Location: Australia, Perth
|
Although i am a 4th year (although haven't started this actual year yet) Software engineer, with little real world experience (at the moment) i'd imagine that on large scale or massive scale software projects that you'd need some pretty tight configuration management in order to keep track of everything.
The main point of coding standards is for code quality; maintainability/readibility and uniformity. Basically, when others are going to be looking through your code, to either debug/review or maybe extended it (extending code beyond it's original function/purpose can be dodgy though ![]() ![]() Quote:
getting to preincrementing now, you're right in saying that you shouldn't use it in combination with anything anyway, but if someone does, it (well i think) it's unintuitive. Although as nonsensical said, if s/he's just writing the code for themselves, knowingly what's happening the maybe it's ok? It's hard to say what'd be (un)intuitive for others i guess... and sorry for the threadjack ![]() |
|
![]() |
![]() |
#7 (permalink) |
Location: Waterloo, Ontario
|
Now that we've already answered Prince's question, I don't think threadjacking is a problem, anymore. Jack away!
So, let's talk more about coding standards, since you feel that being a Nazi about it will help you. Perhaps I should mention that while I have little formal education in software engineering (I studied math in university), I have had a lot of experience as a software engineer while working on large projects for billion dollar multinational corporations... First, lets discuss the points you brought up for coding standards. Code quality is a catch all term. What do we mean when we talk about quality code? It's no more meaningful than to simply say it is good code. While this is not a useless statement, for we often see examples of good code and bad code, it's much too vague to be used as a supporting point, since we are talking about what's "good" about coding standards. It's just as meaningful as saying "it's good because it's good." Readibility is an aesthetic opinion. Like you've discovered with n0nsensical, what's readable to one person it not necessarily readable to another. Uniformity is a tautology, in this context. When we talk about coding standards we are, by definition, talking about uniformity. If you're following a standard then your code is uniform, right? Again, it's as useful as saying "you should follow a standard so that you will be following a standard." Now, while it may have look I've totally ripped apart everything good you've ever had to say about coding standards, let me say that they aren't toally baseless. If i had organized my source code so that it looks like a choo-choo train, or if I named all my variables _, __, ___, etc... (a perfectly legal thing to do in C/C++), there will be few people who will contest that this is unreadable and, thus, low quality code. It will still be uniform, however, 'cause that was a truly useless statement. So, what are we really talking about? If you put in some effort into making your code readable, like decent variable names and some indentation, then most people will agree that the code is human readable. What if different parts of the code were written using a different style. It's still indented and the variables will still have meaningful names (we'd hope). Will it really throw you off that much? Will you suddenly throw your arms up and say "I can't read this garbage, it's all different!" Really? What if you use third-party code? Or code licensed from someone else? Code bought from someone else? Or you're trying to work on a project for the first time? Maybe an open source project? What if you're a consultant helping some team with their project? If they follow a different standard than you, does that mean you're screwed? Will you say, "I'm sorry, I can't help you. I can refer you to someone who's familiar with your style, though!" Will you then say to yourself "I'm glad I accustomed myself to the One and true God given coding standard and that I've been a total Nazi about it all my life! It has sure helped my career!" Of course not. This is all silly and I hope you found it amusing but there is a real point in all this. Does it really matter that much? I question whether it matters at all. Here's something to actually concern yourself about, now that you had brought it up... Maintainability is essential to any programming project. Even if you are writing "throw away" code that you never expect to come back to again, you will be "maintaining" your project while you are writing it, so it's never a waste of time. But what does it take to write maintainable code? Surely, if I follow a coding standard, my code will be maintainable, right? I wish it were that simple. Let me offer you two simple ways of increasing the "maintainability" of your code that goes leaps and bounds beyond anything your choice in coding style will ever do for you. Code on a strict "need to know" basis. This includes ideas like implementation hiding and data abstraction. Avoid parallel information whenever possible. This includes ideas like code reuse, and principles like avoid premature caching. (code reuse just says it all, really) It's one thing to read about them in books (like I once did) but it really hits home when you've been saved or bitten in the ass by the presence or absense of these practices. I'd write more (like how these things actually make your code more maintainable) but I've written enough, I have things to do, and you already know, at least, half of this stuff... Last edited by KnifeMissile; 02-09-2004 at 11:59 PM.. |
![]() |
![]() |
#8 (permalink) | |
Fast'n'Bulbous
Location: Australia, Perth
|
Hehe, first off, i hope you don't school me too badly cause i am still just a 20 year old learning some of the ropes.
That said, i must say that i am not that much of a code Nazi ![]() ![]() Back to Coding Standards. Quality of the code is ultimately the quality of the whole software (as it's pretty much the code which is the software!). There are many factors in determining the quality of the code, in reducing it to "good" or "bad". Since software engineering is far from being a precise mathematical science like any other engineering discipline, the rules for governing a lot of measurements are generally heuristics or "good practice". Now, you covered a few issues of coding standards, namely the meaningful variables names and some other purely aesthetic stuff (indents etc). For the most part i agree with you about rather pedantic standards, but i feel that there are some which are just bad. Anyway i used RSM as a means of getting some quantifiable data about the quality of the code. As you can see, it can generate quality notices -> Quality Notices If you care to look through some of them, some are a little pedantic and unnecessary (probably just bloating the process) but there are quite a few, that i thought was thought to be good practice to write good or was inherent in good quality code (ie eliminating the probability of bugs and errors in general logic/implementation ) Here are a few specific examples of things i'd like people[bNOT[/b to do to any software project or code: no goto statements -> Quality Notice 9 switch statements have a default condition -> Quality notice 13 if, for, while etc conditions not bound by {} -> Quality notice -> 22 no multiple returns -> quality notice 27 no breaks outside of case statements -> quality notice 44 oh yeah and the preincrement one ![]() A real example of where that may have been unintuitive was my friend using last year in this software we were writing to identify particular shapes in images. Anway, he had an array in a while loop that he was accessing on some specific condition inside the while loop. Anyway he had the index increment as myArray[++index]; Anyway, the index was initialized as 0, so you can see the problem and how it can be a little unintuitive? To work then, the index would need to be set as -1 which i think is a little weird as an intilaisation value? I imagine that, that sort of confusion or whatever was what the quality notice was referring to. However i am glad that you said that it's a bad idea to use an increment or shortcut like that with other operators ![]() I mean, that could be another quality notice. The number of operators you have on a line, if they exceed some value, that could be a quality notice. Because obviously, the more operators that are on a line, the longer it takes to work out what's happening. There’s a lot of quality notices in that list which can have exceptions, although i feel that the things i listed above, shouldn't really have exceptions. To break them is going against that normally introduces "bad" code. Which basically means it's causes more problems or difficulties than normal. Also, as a logical linear flow, a few of those things will interfere with that, hence affecting readability or understandability. It could be like reading one of those adventure novels where it keeps saying go to page x, go to page y, stop here for a bit... etc. I thought it's universal that people like to read things as one nice continuous flowing work? Some other coding standards i think are generally important, although not vital, are just naming conventions for classes, variables and constants. That just makes it easy to identify what is what type. Other stuff like declaring numeric values as constants, instead of just putting in numbers (ie for test conditions normally) like if( x = 5)... instead if( x = NUMBEROFPEOPLE) ie no magic numbers Ok, i don't want to go on listing heaps of crappy examples like this but i hope you get a general idea of what i am getting at. In sorta summing up this part, i'd like to say that coding standards aren't life or death, however, i would have thought that the time and effort put into abiding by a few of them, even moreso that just meaningful names, the less time is spent on deciphering the code by other people. I don't want to come in and say one thing is more readable than the other, but from my little ![]() ![]() I am finding it hard to get across my point that not ALL aspects of readability are subjective; well moreso that i'd had thought that humans like to read things in a logical flow, with identifiers with meaningful names and in common styles to promote their type it's all about trying to make things more clear cut and simpler for the uses. I am making an assumption that the more things there are in a smaller area the harder it is to grasp them all, cause they interlock etc and it takes time to distinguish them. I daresay that the commenting of the code is as if not more important than the code itself. That's also a huge issue of readability, appropriately stating assertions. Anyway enough of me crapping on for a bit, you say you worked for a large corporation, did they use coding standards or any kind of quality control and configuration management? Quote:
![]() Anyway i hope you can see, even just mildly, where i am coming from. I am not that much of a close minded code nazi, and i can accept other styles. I am saying that resources are usually saved if a general standard is implemented which helps promote quality code or intuitive logical to the average human programmer... heh, this has been fun ![]() ![]() |
|
![]() |
Tags |
newbie, question |
|
|