'accessing pointed value with pointer without *
I am reading Head First C book and in pointers chapter(and pointer arithmetic) i couldnt understand something.
I have to write arrays like this to print its 3rd element:
main(){
int drinks[] = {4, 2, 3};
printf("3rd order: %i drinks\n", *(drinks + 2));
}
But when using pointer i need to write like this
void skip(char*);
int main() {
char *msg_from_amy="dont call me";
skip(msg_from_amy);
}
void skip(char *msg){
puts(msg+6);
}
Shouldnt i need to write *(msg+6) to access 7th element? msg holds an address and msg+6 means ahead of 6 bytes from begining. so it is still an address, i need to write *(msg+6) to access stored value in that address from my perspective but it doesnt work. But why quoted one right answer, why i cant figure out.
Edit: Actually i asked wrongly my question. And edited code snippets. Here is output of:
puts(msg+6);
printf("%c\n", *(msg+6));
printf("%s\n", *(msg+6));
all me
a
I expected get "all me" output from 2nd printf like 1st one. But i think i understand the reason. its difference of puts and printf argument list. Thx for answers.
Btw why 3rd printf prints just a blank character?
Solution 1:[1]
I have to write arrays like this to print its 3rd element:
main(){ int drinks[] = {4, 2, 3}; printf("3rd order: %i drinks\n", *(drinks + 2)); }
No, you don't have to do that, and it is very non-idiomatic. Most people would use
printf("3rd order: %i drinks\n", drinks[2]);
Moving on ...
void skip(char *msg){ puts(msg+6); }Shouldnt i need to write *(msg+6) to access 7th element?
Yes, *(msg+6) to access 7th element or, better, msg[6]. But you're not trying to access the 7th element. You are providing to puts the substring that starts at the 7th element. msg+6 is just fine for that.
Here is output of:
puts(msg+6); printf("%c\n", *(msg+6)); printf("%s\n", *(msg+6));
all me aI expected get "all me" output from 2nd printf like 1st one
I don't see why. The %c formatting directive converts and prints one character, which is good because that's what you pass as the corresponding argument. It's not about a difference between puts and printf. Rather, it's mostly about the deep difference between msg+6 and *(msg+6).
Btw why 3rd printf prints just a blank character?
No one can say. The behavior of your third printf call is undefined because the formatting directive %s, which expects a char * argument, is not correctly type matched with the corresponding argument *(msg+6), which is a char. Anything could happen. And this underscores my previous point: there is no deep difference in this regard between puts and printf. You appear to want:
printf("%s\n", msg+6);
Solution 2:[2]
I expected get "all me" output from 2nd printf like 1st one.
The %c specifier is intended to print exactly one character. Furthermore, it's impossible to go to msg+7 from *(msg+6).
Btw why 3rd printf prints just a blank character?
Because %s expects a pointer. *(msg+6) is not a pointer.
You should compile with -Wall -Wextra. That will make the compiler warn you about a lot of stuff.
Solution 3:[3]
If you need the value that msg points to, you need to deference it using the * operator. So, if you want to get the sixth element pointed by msg, you need to advance by 6 and then deference it. The problem with printf("%s\n", *(msg+6)); is that %s expects a string, but *(msg+6) is a character. You can try to change %s with %c.
Remember that a string in c is a collection of characters ended by the null character '\0'.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | klutt |
| Solution 3 | Nicolò Polazzi |
