【FROM: http://zhidao.baidu.com/question/327940855.html】
char str[]="hello"; 和 char *str="hello"; 不一樣。
char str[]="hello";
是在動態變量區中開闢了可以容納6個字符的數組,數組名叫str。同時將字符串"hello"(原存放於常數空間)拷貝到這個數組空間中去作爲數組的初始化值。
此時若執行return str; 其中的str是數組名。C語言規定,表達式中如果是數組名,則該表達式的值就等於這個數組的地址。所以返回的是這個數組的地址,請注意:並不是字符串常量"hello"的地址!而函數結束時,雖然常數空間並不破壞,但這個數組空間是破壞了的,而你返回的卻不是常數空間裏的地址而正是已經破壞了的數組的地址。
而char *str="hello";
是在動態變量區中開闢了一個可以存放一個指針值的變量,名叫str。同時將原存放於常數空間的字符串"hello"的地址賦給這個指針變量作爲初始值。
此時若執行return str; 其中的str是指針變量名。C語言規定,表達式中如果是變量名,則該表達式的值就等於這個變量的值。所以返回的是變量str的值,而變量str的值就等於字符串常量"hello"的地址。而函數結束時,變量str破壞了的,但常數空間中的字符串並不破壞。主程序根據返回的地址就可以找到該字符串。
DEMO:
//#define FIVTH_DEMO
//#define SIXTH_DEMO
//#define SEVENTH_DEMO
#define EIGHTH_DEMO
/*
函數返回指針,要使主程序可以使用這個指針來訪問有意義的數據,關鍵就是要保證在使用這個指針值的時候,
該指針所指向的地方的數據仍然有意義。
如果指針是指向函數的指針,那麼這個指針就是指向程序代碼區的。
【總結】
常規程序中,函數返回的指針通常應該是:
(1)指向靜態(static)變量;
(2)指向專門申請分配的(如用malloc)空間;
(3)指向常量區(如指向字符串"hello");
(4)指向全局變量;
(5)指向程序代碼區(如指向函數的指針)。
除這5項以外,其它怪技巧不提倡。
*/
#if defined FIVTH_DEMO
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
int *fun(void);
int main(void)
{
int *p;
int i;
int *fun(void);
p=fun();
for (i=0;i<3;i++)
{
printf("%d\n",*p);
p++;
}
getch();
return 0;
}
/*
函數內的變量,沒有關鍵字static修飾的變量的生命週期只在本函數內,函數結束後變量自動銷燬。
當返回爲指針的時候需要特別注意,因爲函數結束後指針所指向的地址依然存在,但是該地址可以被其他程序修改,
裏面的內容就不確定了,有可能後面的操作會繼續用到這塊地址,有可能不會用到,所以會出現時對時錯的情況,
如果需要返回一個指針而又不出錯的話只能調用內存申請函數。
*/
int *fun(void)
{
/*static*/ int str[]={1,2,3,4,5}; //不是靜態存儲區,在函數返回之後,釋放了str的空間,輸出的值是不確定的。
int *q=str;
return q;
}
#elif defined SIXTH_DEMO
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
char *fun(void);
int main(void)
{
char *p;
char *fun(void);
p=fun();
printf("%s\n",p);
getch();
return 0;
}
char *fun(void)
{
char *str="hello,world"; //不用申請爲static也可以正確輸出,str指向常數空間(始終存在),其空間不會被破壞。
return str; //就是一個指向這種常量區的指針
}
#elif defined SEVENTH_DEMO
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
char *fun(void);
int main(void)
{
char *p;
int i;
char *fun(void);
p=fun();
for (i=0;i<3;i++)
{
printf("%s\n",p[i]);
}
getch();
return 0;
}
char *fun(void)
{
char str[]={'a','b','c'}; //系統自動分配存儲空間,但是函數返回的時候釋放掉,無法正常輸出
return str;
}
#elif defined EIGHTH_DEMO
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
char *fun(void);
int main(void)
{
char *p;
int i;
char *fun(void);
p=fun();
printf("%x\n",p);
printf("%s\n",p);
getch();
return 0;
}
char *fun(void)
{
char str[]="hello"; //函數返回後釋放地址,無法正常輸出
printf("%x\n",str);
return str;
}
#endif