Can you find what is wrong with the following code?
int main(){
char *p="hai friends",*p1;
p1=p;
while(*p!='\0') ++*p++;
printf("%s %s",p,p1);
}
I expected it will print space followed by a string!
Can you find what is wrong with the following code?
int main(){
char *p="hai friends",*p1;
p1=p;
while(*p!='\0') ++*p++;
printf("%s %s",p,p1);
}
I expected it will print space followed by a string!
The expression ++*p++
; is equivalent to;
++*p;
p++;
++*p;
means
*p = *p + 1;
Because postfix ++
has higher precedence than the dereference operator *
, it's applied on *p
.
And p
points to a constant string literal. In the above operation you are trying to "write on read only memory" — that is illegal — hence error.
Suggestions:
First — declare your an array that can be modified, you can't change string literals.
declare (read comments):
char string_array[] ="hai friends"; // notice `[]` in this declaration
// that makes `string_array` array
// to keep save original string do:
char p1[20]; // sufficient length // notice here `p1` is not pointer.
strcpy(p1, string_array) ;
char *p = string_array;
Now you can modify pointer p
and string_array[]
array content.
Although the answer by Grijesh Chauhan is correct in saying that:
++*p++;
and
++*p;
p++;
have the same effect, the compiler does not interpret the first expression as if it was written like the second. The parenthesized version of the first expression is:
++(*(p++));
This means that logically — though the compiler can resequence the details as long as the result is the same — the post-increment of p
occurs before the result is dereferenced, and the pre-increment operates on the data pointed at by the original value of p
. Let's go through that step by step:
p++
— returns the original value of p
and increments p
to point to the next character.*(p++)
— dereferences the original value of p
.++(*(p++)
— increments the object pointed at by the original value of p
and returns the incremented value of that object.Thus, given this code (which avoids modifying string literals — that is undefined behaviour):
#include <stdio.h>
int main(void)
{
char array[] = "ayqm";
char *p = array;
char c;
c = ++*p++;
printf("%c\n", c);
printf("%s\n", array); // Print the string
c = ++*p++; // Repeat the process
printf("%c\n", c);
printf("%s\n", array);
return 0;
}
The output is:
b
byqm
z
bzqm
Nothing in this answer should be construed as encouraging the use of expressions as complex as ++*p++
. It is not easy C to understand or maintain, and therefore it is not good C. However, it is legitimate C. If the variable p
points to initialized modifiable memory, the behaviour of ++*p++
is completely defined.
Here is a way to use ++*p++
:
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
char *p = "My test string", p1[15];
strncpy(p1, p, 14);
p1[14] = 0;
p = p1;
while (*p != 0) {
printf("%c", ++*p++);
}
}
Note that p1
is an array of memory (usually) allocated on the stack, whereas p
is (usually) a pointer to read only memory, which the above code moves to point to p1
instead of the (usually) read only location where the string resides. Some operating systems and/or compilers will exhibit other behavior, but this is one of the protection mechanisms built into modern OSs to prevent certain classes of viruses.