I'm learning C++ and here I've written a little toy program that is supposed to list all the arguments passed to it through the command line.
#include <iostream>;
using namespace std;
int main (int argc, char *argv[]) {
for (int number = 1; number < argc; ++number) {
cout << argv[number] << endl;
}
return 0;
}
It is possible to use indexing instead and rewrite it in the following way:
#include <iostream>
using namespace std;
int main (int argc, char *argv[]) {
int i;
for (int j = 1; j < argc; ++j) {
i = 0;
while (argv[j][i]) {
cout << argv[j][i];
++i;
}
cout << endl;
}
return 0;
}
I personally like the first version more. It doesn't need one more variable and it doesn't need one more cycle, so making use of pointers here seems like a good idea: it helps improve readability and as far as I know performance.
Is this actually a good alternative to the second version that uses indexing? And if so, how could it be improved?
2 Answers 2
Is this actually a good alternative to the second version that uses indexing? And if so, how could it be improved?
I'm not sure what you're asking here. Obviously the first version is fine; obviously the second version is pretty silly (because it does the same thing as the first version but in a more confusing and verbose way).
As for "using indexing", doesn't the first version also use indexing? What do you think argv[i]
is, if not "indexing"? It sure seems like you've got the hang of "indexing" well enough. :)
Your second program is also silly in that it uses a while
loop instead of a for
loop, even though you have all three pieces of a for-loop (initialization, condition, and increment) in close proximity. Why didn't you use a for
loop? Just for practice with different kinds of loops? In that case, I'd dock you points for not using a do
-while
loop! ;)
To nitpick as long as I'm here:
Everyone will tell you (so you might as well start listening now) that
using namespace std
is a bad habit. Writestd::cout
andstd::endl
explicitly.You have a stray
;
on line 1 — a transcription error, since the compiler wouldn't accept it if you actually tried to compile that.Your second program uses saner loop index names:
i
andj
. Naming a loop control variablenumber
is more likely to confuse the reader than help them.Explicit
return 0
frommain
is unnecessary in C++ (and also in C, as of 18 years ago). Omitting it from simple programs like this can help the reader focus on the important stuff instead of the boilerplate.
Putting it all together:
#include <iostream>
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
std::cout << argv[i] << std::endl;
}
}
-
\$\begingroup\$ Wow thank you a lot for the very informative reply! Well actually the first program was written by myself and the second one I copy-pasted from the textbook I'm reading...I consider myself an advanced programmer in Python and some other script languages but I'm new to C++, so yeah
std::cout
andstd::endl
are likefrom MODULE import FUNCTION
in Python, but again it's what is written in the textbook which seems to be quite old...Thank you for all the tips. \$\endgroup\$CodeFish– CodeFish2017年03月21日 10:29:05 +00:00Commented Mar 21, 2017 at 10:29 -
\$\begingroup\$ Oh just noticed it, I meant to say
using std::FUNCTION;
in C++ is akin tofrom MODULE import FUNCTION
in Python. If I'm not mistaken. \$\endgroup\$CodeFish– CodeFish2017年03月21日 10:44:56 +00:00Commented Mar 21, 2017 at 10:44 -
\$\begingroup\$ @CodeFish: C++'s name-lookup rules are fundamentally different from Python's, but yeah that's a good way to think about it. (1)
using namespace std; cout << m;
is likefrom std import *; cout(m)
. (2)using std::cout; cout << m
is likefrom std import cout; cout(m)
. (3)std::cout << m
is likeimport std; std.cout(m)
. My impression is that in Python: (1) is bad, (2) is okay/good, and (3) is good. In C++, especially for namespacestd
: (1) is bad, (2) is okay, and (3) is best. \$\endgroup\$Quuxplusone– Quuxplusone2017年03月21日 18:21:05 +00:00Commented Mar 21, 2017 at 18:21 -
\$\begingroup\$ @CodeFish: C++ never does "runtime imports" at all, so the short answer is "NO." I left out something from my parallels: (1)
#include <iostream> using namespace std;
..cout << m;
is likefrom std import *
..cout(m)
. (2)#include <iostream> using std::cout;
..cout << m;
is likefrom std import cout
..cout(m)
. (3)#include <iostream>
..std::cout << m;
is likeimport std
..std.cout(m)
. The "import" (parsing of thestd
module) still happens only once at the top of the file. The only difference is how you're allowed to refer to thestd.cout
variable later. Does that help? \$\endgroup\$Quuxplusone– Quuxplusone2017年03月21日 22:41:42 +00:00Commented Mar 21, 2017 at 22:41 -
\$\begingroup\$ oh silly me...that was a stupid question of mine...yeah indeed...the lib is called iostream and it is loaded only once. Thank you! \$\endgroup\$CodeFish– CodeFish2017年03月21日 22:58:05 +00:00Commented Mar 21, 2017 at 22:58
Everythin Quuxplusone said:
Let's give you a couple of other concepts to look up.
#include <iostream>
#include <algorithm>
#include <iterator>
int main (int argc, char *argv[]) {
std::copy(argv + 1, argv + argc, std::ostream_iterator<std::string>(std::cout, "\n"));
}
- Tip 1: Use algorithms rather than loops.
Here:std::copy()
- Tip 2: Algorithms use iterators that mark the beginning and end of stuff.
Here:argv + 1
is the beginning
andargv + argc
points at the end. - Tip 3: Don't worry about
std::ostream_iterator<std::string>
yet.
Just accept it prints your stuff.
-
\$\begingroup\$ Thank you a lot for the useful tips but they are too advanced for me at the moment hehe I first want to finish the textbook I'm reading to grasp the most basic things..but from Quuxplusone's answer I'm forced to draw the conclusion that the book is quite old and teaches some bad habits. \$\endgroup\$CodeFish– CodeFish2017年03月21日 10:36:02 +00:00Commented Mar 21, 2017 at 10:36
-
\$\begingroup\$ but yeah I think it would be the right thing to teach myself good habits from the beginning...thank you one more time. \$\endgroup\$CodeFish– CodeFish2017年03月21日 12:14:41 +00:00Commented Mar 21, 2017 at 12:14
-
\$\begingroup\$ I think describing this answer as "concepts to look up" is much more accurate than describing it as "tips". ;) Writing a simple program like this in terms of
ostream_iterator
is IMHO on the same level as writing "hello world" asfor (auto&& ch : "hello world!\n") std::cout.put(ch);
. In both cases, @CodeFish would do well to study these examples until he understands them thoroughly; but also in both cases, if anyone seriously writes code like this for hello world, I wouldn't work with them. ;) \$\endgroup\$Quuxplusone– Quuxplusone2017年04月02日 18:07:46 +00:00Commented Apr 2, 2017 at 18:07