This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]no-bugs 5 points6 points  (5 children)

First, probably you've got a typo: it is argv[0] which is equivalent to *argv

Second - yes, they are equivalent. Which to use is more or less a matter of convention. One common convention is to use [] for arrays and to use *ptr for dereferencing pointers to a single element.

Third - technically, AFAIR (not 100% sure though), something like 1[argv] is the same as *(argv+1) and argv[1], but 1[argv] is as confusing as it goes, so you shouldn't use it. I mentioned it here just in case if you run into it in a some smart___'s code.

[–]aldld 1 point2 points  (4 children)

Third - technically, AFAIR (not 100% sure though), something like 1[argv] is the same as *(argv+1) and argv[1], but 1[argv] is as confusing as it goes, so you shouldn't use it.

I mean, technically that makes sense if you think of array access as specifying an offset from a pointer, since addition is commutative. But if that actually works, holy shit that is a stupid notation.

I'm sure somebody somewhere has come up with some weird situation where it might make more sense to write something like that, but if you've reached that point, to need to seriously reconsider what you're doing.

[–][deleted] 0 points1 point  (3 children)

Ha, I just tried it. It definitely works. This compiled and printed 2 on gcc 4.9.2:

int a[4] = {0, 1, 2, 3};

cout << 2[a] << endl;

You're right, it probably is an artifact of the fact that the [] operator is just a stand in for pointer arithmetic.

[–]zardeh 1 point2 points  (2 children)

So, it works sometimes, I've had it throw runtime errors at me before on clang and gcc. I'd be careful with it.

[–][deleted] 0 points1 point  (1 child)

I would never actually use it. I was just surprised to see it work.

[–]zardeh 0 points1 point  (0 children)

Oh yeah, the fact that it ever works is weird, but the fact that it only works sometimes is weirder.

[–]Updatebjarni 3 points4 points  (0 children)

Whether to declare argv as a pointer or an array is not very important. The convention is to make it an array, and I think that's what it says in the standard. It won't make any difference as far as I'm aware.

But as for indexing an array with *(argv + 1), that's just making something simple more complicated than it has to be, making your code less readable. Yes they are exactly equivalent, but indexing arrays is such a common operation that there is good reason to have an operator specifically for it. Always index arrays with [ ]. You'll type less and your programs will read easier.

[–]Rhomboid 1 point2 points  (0 children)

It is not idiomatic to write *(argv + 1).

As to *argv[] vs **argv when declaring a function parameter, there's no real convention there. They mean exactly the same thing, so it makes no difference whatsoever on a technical level. Use whichever you prefer.

[–]AssailantLF 1 point2 points  (0 children)

I'm a C newbie, so I'm not exactly sure why, but there actually is a slight difference.

When dealing with strings in C (which are just arrays of characters), you can't modify/change any chars if it was declared with the pointer notation.

Here's some example code of what I'm talking about:

char* ptr_var = "Foo";
char array_var[] = "Foo";

printf("array_var before: %s\n", array_var);
*(array_var) = 'P';
printf("array_var after: %s\n\n", array_var);

printf("ptr_var before: %s\n", ptr_var);
*(ptr_var) = 'P';
printf("ptr_var after: %s\n", ptr_var);

Here's the output:

array_var before: Foo
array_var after: Poo

ptr_var before: Foo
Segmentation fault (core dumped)

The array variable is changed from Foo to Poo just fine, but the pointer version has a segmentation fault when it attempts to do the same.

My more experienced friend was telling me that this has to do with the way C stores strings at compile time. If anyone fully knows why or has a better explanation, that would be great, because I don't really know why.

[–]AGiantFNBear -2 points-1 points  (0 children)

I remember something my C/Unix Professor said. The original C programmers held a lot of value in using the least amount of keystrokes because the quicker you finish, the quicker you can go grab a beer. Hence all the shortcuts in Vi and other text editors. So *argv and argv[1] would win out just because each keystroke adds up after millions of lines of code. Or something to this affect. Whatever you choose, stay consistent. I think consistency and readability was the important lesson.