char* p与char p[]的不同

来源:互联网 发布:office 2013 mac 编辑:程序博客网 时间:2024/04/30 18:15

基本问题,例如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!";

原创粉丝点击