前些日子,在QQ群裡面,發現一些朋友在討論函數返回後,為什麼值可以傳遞和地址傳遞的情況;我也感到很好奇,
於是就跟了一下。
int* sum(int x,int y)
{
int a;
a=x|y;
return &a;
} 很顯然這段代碼,存在一些問題;但是在VC2008中編譯一切正常,運行狀態也一切正常。
下面是我的測試代碼:
#include <stdio.h>
int* sum(int x,int y)
{
int a;
a=x+y;
return &a;
}
int getsum(int x,int y)
{
return x+y;
}
int main(void)
{
int *x;
int a;
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x);
a=getsum(1,2);
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x);
*x=100;
printf("*x=%d; x=%u\n",*x,x);
getchar();
return 0;
}運行結果如下所示:
這個就是運行的結果?但是為什麼呢? 而且兩次調用sum函數返回的地址完全一樣。
為了測試,我決定將代碼再進行異常改動。
#include <stdio.h>
int* sum(int x,int y)
{
int a;
a=x+y;
return &a;
}
int getsum(int x,int y)
{
int* p;
p=sum(10,2);
printf("*x=%d; x=%u\n",*p,p);
return *p;
}
int main(void)
{
int *x;
int a;
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x);
a=getsum(1,2);
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x);
*x=100;
printf("*x=%d; x=%u\n",*x,x);
getchar();
return 0;
} 代碼依然堅挺的活著,而且順利的運行,如下所示,只是在getsum裡面調用sum函數,得到的地址與main函數中得到的不一樣。
而且可以發現,無論怎麼調用,在main函數中調用sum,返回的地址一直是一樣的? 這是怎麼回事呢?
如果是這樣的話,那麼是否可以用這種方法動態分配地址呢? 是否可以我們free 一下看看。很不幸的是,失敗了?
提示:可能是heap——棧——異常中斷了程序。
為什麼會這樣呢?
原因可能是:
1、C程序在運行的過程中,其地址空間是固定的;雖然是可重定向的,但是在“他”自己的線性空間,其地址空間是固定的,
也就是所函數調用的壓棧的空間,其棧基址是固定的。
2、由於壓棧順序是一致的,而且每次壓棧時變量的offset是一定的。從左往右壓棧,或者從右往左壓棧都一樣會得到這個結果。
因此就出現了上面的情況。
那麼怎樣說明這個過程的不正常呢? 雖然他看起來能編譯、鏈接和運行,結果也很正常。
#include <stdio.h>
int *x;
int* sum(int x,int y)
{
int a;
a=x+y;
return &a;
}
void getsum()
{
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第二個輸出
}
int main(void)
{
int a;
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第一個輸出
getsum();
printf("*x=%d; x=%u\n",*x,x); //第三個輸出
*x=100;
printf("*x=%d; x=%u\n",*x,x); //第四個輸出
getchar();
return 0;
} 可以發現,第一個輸出,第二輸出的 *x的值一樣; 而第二個、第三個、第四個則是x的只一樣。這又是為什麼呢?
我們在改一下:
#include <stdio.h
int *x;
int* sum(int x,int y)
{
int a;
a=x+y;
return &a;
}
void getsum()
{
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第二個輸出
}
int main(void)
{
int a;
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第一個輸出
getsum();
printf("*x=%d; x=%u\n",*x,x); //第三個輸出
*x=100;
printf("*x=%d; x=%u\n",*x,x); //第四個輸出
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第五個輸出
getchar();
return 0;
}又或者這樣測試一下:
#include <stdio.h>
int *x;
int* sum(int x,int y)
{
int a;
a=x+y;
return &a;
}
int* sum1(int x,int y)
{
int a;
a=x+y;
return &a;
}
void getsum()
{
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第二個輸出
}
int main(void)
{
int a;
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第一個輸出
getsum();
printf("*x=%d; x=%u\n",*x,x); //第三個輸出
*x=100;
printf("*x=%d; x=%u\n",*x,x); //第四個輸出
x=sum1(10,2);
printf("*x=%d; x=%u\n",*x,x); //第五個輸出
getchar();
return 0;
}我們再改一下:
#include <stdio.h>
int *x;
int* sum(int x,int y)
{
int a;
a=x+y;
return &a;
}
int* sum1(int c,int d)
{
int a;
a=c+d;
*x=60;
return x;
}
void getsum()
{
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第二個輸出
}
int main(void)
{
int a;
x=sum(10,2);
printf("*x=%d; x=%u\n",*x,x); //第一個輸出
getsum();
printf("*x=%d; x=%u\n",*x,x); //第三個輸出
*x=100;
printf("*x=%d; x=%u\n",*x,x); //第四個輸出
x=sum1(10,2);
printf("*x=%d; x=%u\n",*x,x); //第五個輸出
getchar();
return 0;