开发者

C: Pointer confusion

I understand this is part of the basic stuff, but i am stuck :-( Can someone please help me?

Program 1:

#include <stdio.h>
#include <stdlib.h> 

int main()
{
 int a=1,开发者_如何学Cb=2,c;
 c=(a+b)++;
}

Why is the output an error? lvalue required?

Program 2:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
 char *p1="name";
 char *p2;

 p2=(char*)malloc(20);
 memset(p2,0,20);

 while(*p2++=*p1++);
 printf("%s\n",p2);

}

Why is the output, an empty string? And if i reverse the order of increment, that is: while(++*p2=++*p1);, why the lvalue error comes?


For the first question,(a+b)++ means "increment the value of a+b by 1".

You cannot increment a+b, though, for it's not a variable. What would you expect to happen in the following code?

int a = 1, b = 2;
printf("a = %d, b = %d, a+b = %d\n", a, b, a+b);
(a+b)++;
printf("a = %d, b = %d, a+b = %d\n", a, b, a+b);

Clearly the first printf should print

a = 1, b = 2, a+b = 3

But what about the second one?

a = ?, b = ?, a+b = 4

It's not clear what a or b should be if we increment the sum.

As for the second question, remember that you're changing p2 when you copy over the data, so when you ask to print out what it's pointing at, it's pointing at the end of the string, not the beginning.

An easier way to do the string copy would be to use strcpy, like so:

strcpy(p2, p1);

Note, this is only safe because you know that the size of the string in p1 isn't greater than the size of p2. If you're not sure about the size of the string (for instance, if you get the string from user input), you'll need to be careful, as is outlined on Wikipedia.

As for why while(++*p2=++*p1); doesn't work, while while(*p2++=*p1++); does:

Postfix-++ has higher precedence than *. This means, *p2++ means *(p2++). So

*(p2++) = something;

is the same as

*p2 = something;
p2 += 1;

Meanwhile, ++*p2 means ++(*p2), or "whatever p2 points to, incremented by one".

Again, you get the problem, if you say:

 int a = 5, *p2 = &a;
 ++*p2 = 10;
 printf("a = %d\n", a);

What would you expect this to print? If anything, it should print 9, because you're telling the compiler that *p2+1 = 10.

You can't expect a C-compiler to solve that equation, however, so in order to keep the language simple and efficient, this sort of thing is forbidden.


c=(a+b)++;

a+b is not a lvalue - how would you want to assign something to the result of an addition (a rvalue) - and the ++/-- operators do assign the new value.

while(*p2++=*p1++);

You p2 points at the \0 at the end of the string. You need to store the original address p2 points to before your loop:

char *p3 = p2;
while(*p2++=*p1++)
    ;
printf("%s\n",p3);


c=(a+b)++;

The ++operator doesn't work with temporary variables. (a+b) forms a temporary.

while(*p2++=*p1++);

You're incrementing p2 here. After the loop, p2 no longer points to the beginning of the memory block returned by last malloc() call.


If you look at the while loop:

while(*p2++ = *p1++);

remember that an expression is "True" in C if it is non-zero, and false if it is zero. Even though the loop has no body, the flow of control is still:

check condition -> execute statement in body --> check condition

and here, "check condition" means "evaluate the statement and see if it is non-zero".

The while loop continues to operate until p1 points to zero, at which point control passes to printf.

e.g.

int main() 
{
    int array1[] = {2, 3, 1, 0, 3, 5};
    int array2[20];
    int * p2 = (int *)memset(array2, 0, 20*sizeof(int));
    int * p1 = array1;

    while(*p2++ = *p1++) {
        printf("In while: p1 is %d\n", *p1);
    }
    printf("Out of while: %d\n",*p2);
    return 0;

}

yields:

In while: p1 is 3
In while: p1 is 1
In while: p1 is 0
Out of while: 0
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜