Reputation: 1428
I was doing some pointers and arrays practice in C and I noticed all my four methods returned the same answer.My question is are there disadvantages of using any one of my below methods? I am stunned at how all these four give me the same output. I just noticed you can use a pointer as if it was an array and you can also use an array as if it was a pointer?
char *name = "Madonah";
int i= 0;
for (i=0;i<7; i++){
printf("%c", *(name+i));
}
char name1 [7] = "Madonah";
printf("\n");
int j= 0;
for (j=0;j<7; j++){
printf("%c", name1[j]);
}
char *name2 = "Madonah";
printf("\n");
int k= 0;
for (k=0;k<7; k++){
printf("%c", name2[k]);
}
char name3 [7] = "Madonah";
printf("\n");
int m= 0;
for (m=0;m<7; m++){
printf("%c", *(name+m));
}
Results:
Madonah
Madonah
Madonah
Madonah
Upvotes: 15
Views: 1354
Reputation: 1
An array is just a variable that contains several values, each value has an index, you probably know that already.
Pointers are one of those things you dont need to know about until you realize you need to use them. Pointers are not variables themselves they are literally pointers to variables.
An example of how and why you might want to use a pointer.
You create a variable in one function which you want to use in another function.
You could pass your variable to the new function in the function header.
This effectively COPIES the values from the original variable to a new variable local to the new function. Changes made to it in the new function only change the new variable in the new function.
But what if you wanted changes made in the new function to change the original variable where it is in the first function ?
You use a pointer.
Instead of passing the actual variable to the new function, you pass a pointer to the variable. Now changes made to the variable in the new function are reflected in the original variable in the first function.
This is why in your own example using the pointer to the array and using the actual array while in the same function has identical results. Both of them are saying "change this array".
Upvotes: 0
Reputation: 28685
Just in addition to what others said, I will add an image for better illustration. If you have
char a[] = "hello";
char *p = "world";
What happens in first case enough memory is allocated for a
(6 characters) on the stack usually, and the string "hello" is copied to memory which starts at a
. Hence, you can modify this memory region.
In the second case "world" is allocated somewhere else(usually in read only region), and a pointer to that memory is returned which is simply stored in p
. You can't modify the string literal in this case via p
.
Here is how it looks:
But for your question stick to notation which is easier, I prefer []
.
More info on relationship between arrays and pointers is here.
Upvotes: 6
Reputation: 106122
It is true that pointers and arrays are equivalent in some context, "equivalent" means neither that they are identical nor even interchangeable. Arrays are not pointers.
It is pointer arithmetic and array indexing that are equivalent, pointers and arrays are different.
which one is preferable and the advantages/Disadvantages?
It depends how you want to use them. If you do not wanna modify string then you can use
char *name = "Madonah";
It is basically equivalent to
char const *name = "Madonah";
*(name + i)
and name[i]
both are same. I prefer name[i]
over *(name + i)
as it is neat and used most frequently by C and C++ programmers.
If you like to modify the string then you can go with
char name1[] = "Madonah";
Upvotes: 23
Reputation: 70981
can I know which one is easy to use [...]
Try sticking to use the indexing operator []
.
One time your code gets more complex and you then notice that things are "more easy" to code using pointer arithmetical expressions.
This typically will be the case when you also start to use the address-of operator: &
.
If for example you see your self in the need to code:
char s[] = "Modonah";
char * p = &s[2]; /* This gives you the address of the 'd'. */
you will soon notice that it's "easier" to write:
char * p = s + 2; /* This is the same as char * p = &s[2];. */
Upvotes: 1
Reputation: 30156
char name[] = "Madonah";
char* name = "Madonah";
When declared inside a function, the first option yields additional operations every time the function is called. This is because the contents of the string are copied from the RO data section into the stack every time the function is called.
In the second option, the compiler simply sets the variable to point to the address of that string in memory, which is constant throughout the execution of the program.
So unless you're planning to change the contents of the local array (not the original string - that one is read-only), you may opt for the second option.
Please note that all the details above are compiler-implementation dependent, and not dictated by the C-language standard.
Upvotes: 1
Reputation: 7812
it is convenient to use array syntax for random access
int getvalue(int *a, size_t x){return a[x];}
and pointer arithmetic syntax for sequential access
void copy_string(char *dest, const char *src){while((*dest++=*src++));}
Many compilers can optimize sequential accesses to pointers better than using array indices.
Upvotes: 2
Reputation: 227
For practicing pointer and array idioms in C, those are all valid code blocks and illustrative of the different ways of expressing the same thing.
For production code, you wouldn't use any of those; you would use something both easier for humans to read and more likely to be optimized by the compiler. You'd dispense with the loop entirely and just say:
printf("%s", name);
(Note that this requires name
include the \0
character at the end of the string, upon which printf
relies. Your name1
and name3
definitions, as written, do not allocate the necessary 8 bytes.)
If you were trying to do something tricky in your code that required one of the more verbose methods you posted, which method you chose would depend on exactly what tricky thing you were trying to do (which you would of course explain in code comments -- otherwise, you would look at your own code six months later and ask yourself, "What the heck was I doing here??"). In general, for plucking characters out of a string, name[i]
is a more common idiom than *(name+i)
.
Upvotes: 1
Reputation: 121427
In C, a[b]
, b[a]
, *(a+b)
are equivalent and there's no difference between these 3. So you only have 2 cases:
char *name = "Madonah"; /* case 1 */
and
char name3 [7] = "Madonah"; /* case 2 */
The former is a pointer which points to a string literal. The latter is an array of 7 characters.
which one is preferred depends on your usage of name3
.
If you don't intend to modify then the string then you can use (1) and I would also make it const char*
to make it clear and ensure the string literal is not modified accidentally. Modifying string literal is undefined behaviour in C
If you do need to modify it then (2) should be used as it's an array of characters that you can modify. One thing to note is that in case (2), you have explicitly specified the size of the array as 7
. That means the character array name3
doesn't have a null terminator (\0
) at the end. So it can't be used as a string. I would rather not specify the size of the array and let the compiler calculate it:
char name3 [] = "Madonah"; /* case 2 */
/* an array of 8 characters */
Upvotes: 11
Reputation: 19985
In all cases, in C pointer + index
is the same as pointer[index]
. Also, in C an array name used in an expression is treated as a pointer to the first element of the array. Things get a little more mystifying when you consider that addition is commutative, which makes index + pointer
and index[pointer]
legal also. Compilers will usually generate similar code no matter how you write it.
This allows cool things like "hello"[2] == 'l'
and 2["hello"] == 'l'
.
Upvotes: 2