基本问题,例如char* p="I Love you!",当我们试图通过p[i]进行改变时,编译会出错;但对于char p[]="I Love you!",当试图通过p[i]进行改变时,编译会顺利通过。为什么呢?接下来请看原因:
通过例程进行分析--
问题1:
#include "stdio.h"
char *getMemoryFirst()
{
char p[] = "I Love you!"; //
return p;
}
char *getMemorySecond()
{
char *p = "I Love you!"; //
return p;
}
int main(int argc,char* argv[])
{
char *strFirst, *strSecond;
strFirst= getMemoryFirst();
printf("getMemory:%s/n",strFirst);
strSecond= getMemorySecond();
printf("getMemorySecond:%s/n",strSecond);
return 0;
}
输出:
getMemoryFirst:(乱码或者没有输出),我于前面的博客已经讲述过,因为p为局部变量,当函数返回时,局部变量内存被撤销。
getMemorySecond:I Love you!
为什么会这样?
解析:
char *p与char p[] 两者都可用来声明一个字符串,但是表示的意义确是大不相同。
从其声明的对象来说:
char p[] 用来声明一个数组p
char *p 用来声明一个指针p,指向字符串起始位置。
从存储位置来说:
char p[] :其p数组作为局部变量被存储在栈区;
char *p="I Love you!":在这个声明中,"I Love you!"被存储在静态数据区,而且是全局的,p仅仅就是个指针.
从函数执行后的扫尾工作来看:
C函数执行完之后对栈区进行清除操作,对静态数据区和堆则没有,因此第一个问题也就不难解释了,getMemoryFirst()函数执行完就释放了栈区内存,所以根本就不存在存有"I Love you!"声明时的内存,也就不可能有所输出。
那么,写成char *p = "I Love you!";到底合不合法呢?能不能这样写呢?
这是一个历史问题,在const关键字被引入C语言之前,这样写是合法的,而且存在了很长的一段时间,大量的代码在此期间运用了这种写法,新版C语言为了兼容,故允许这样写,但最好不要这样,因为这种写法终会被淘汰,说不定哪天你的代码用了新版的编译器,然后莫名的出了问题,要找这个BUG估计不是一件容易的事。现在最好写成:
const char *p = "hello world!";
或者
char p[] = "hello world!";