Output of a c code like with call by reference [cl

2020-05-11 02:12发布

问题:

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 7 years ago.

Given this C code:

int x=12,y=10;

void tswap(int pa, int pb) {
   int tmp;
   tmp=pa;
   pa=pb;
   pb=tmp;
   x=x+pa;
   x=x-pb;
   y++;
   printf("%d %d %d %d\n",pa,pb,x,y);
}

int main() {
    int a=4;
    tswap(x,a);
    printf("%d %d %d\n",x,y,a);
    return 0;
}

I have to figure out what it would print if C used call-by-reference.

Here is my expectations.
First of all
x=12 y=10 and a=4

after tswap(12,4):
pa=x=12 pb=a=4

after tmp=pa:
tmp=pa=x=12
-----------
after pa=pb:
tmp=x=12
pa=pb=a=4
-------------
after pb=tmp:
pb=tmp=x=12
pa=a=4

after x=x+pa
x=16
------------
and after x=x-pb and y++
x=4,y=11

So I think x=4, pb=12, pa=4, y=11; but the answer says -4 12 -4 11. Where I am wrong?

回答1:

Since there's no recursion here, and all variables have distinct names, we can "cheat" a bit and change the local variables to globals (since this won't cause any name conflicts):

int x=12, y=10; /* original globals */
int tmp;        /* belongs to tswap */
int a;          /* belongs to main */

void tswap(int pa, int pb) {
   tmp=pa;
   pa=pb;
   pb=tmp;
   x=x+pa;
   x=x-pb;
   y++;
   printf("%d %d %d %d\n",pa,pb,x,y);
}

int main() {
    a=4;
    tswap(x,a);
    printf("%d %d %d\n",x,y,a);
    return 0;
}

Since tswap is only called once, we know that its pa parameter is always aliased to x, and its pb parameter is always aliased to a. So, we can just get rid of the parameters, replacing them with the variables that they alias:

int x=12, y=10;
int tmp;
int a;

void tswap() {
   tmp=x;
   x=a;
   a=tmp;
   x=x+x;
   x=x-a;
   y++;
   printf("%d %d %d %d\n",x,a,x,y);
}

int main() {
    a=4;
    tswap();
    printf("%d %d %d\n",x,y,a);
    return 0;
}

At this point, this is just regular C code; we no longer have any parameters, so "pass-by-reference" and "pass-by-value" are equivalent. Tracing through:

int x=12, y=10;
int tmp;
int a;

void tswap() {
   tmp=x;       /* x=12, y=10, tmp=12, a=4 */
   x=a;         /* x=4, y=10, tmp=12, a=4 */
   a=tmp;       /* x=4, y=10, tmp=12, a=12 */
   x=x+x;       /* x=8, y=10, tmp=12, a=12 */
   x=x-a;       /* x=-4, y=10, tmp=12, a=12 */
   y++;         /* x=-4, y=11, tmp=12, a=12 */
   printf("%d %d %d %d\n",x,a,x,y);    /* prints "-4 12 -4 11" */
}

int main() {
    a=4;        /* x=12, y=10, tmp is uninitialized, a=4 */
    tswap();    /* x=-4, y=11, tmp=12, a=4; prints "-4 12 -4 11" */
    printf("%d %d %d\n",x,y,a); /* prints "-4 11 4" */
    return 0;
}