解析char *p与char p[]

来源:互联网 发布:相机照片导入mac 编辑:程序博客网 时间:2024/05/18 04:58
 
 
       见论坛上有人讨论这个问题,感觉也是涉及面比较广,而且很多人犯过这个错误,比如声明char *p = "hello world!";却妄图用p指针改变字符串内容,所以就这个问题,我总结了一下。转载注明作者Logic0以及出处。

主要解析的问题:

问题1:
#include "stdio.h"
char *get_string_1()
{
    char p[] = "hello world!";
    return p;
}
char *get_string_2()
{
    char *p = "hello world!";
    return p;
}
int main()
{
    char *p;
    p = get_string_1();
    printf("get_string_1:%s\n",p);
    p = get_string_2();
    printf("get_string_2:%s\n",p);
    return 0;
}
输出:
get_string_1:(乱码或者没有输出),linux下没有任何输出
get_string_2:hello world!
为什么会这样?

问题2:
char *p = "hello world!";这样写到底合不合法,实际应用中能不能这样写。

问题3:
char *p = "hello world!";与char p[]="hello world!";有什么细节和操作上的差异。

解析:
       char *p = "hello world!";与char p[] = "hello world!"; 两者都用来声明一个字符串,并将其初始化为hello world!,但是表示的意义确是大不相同。
       从其声明的对象来说:
       char p[] = "hello world!";用来声明一个数组p,数组大小为12字节。
       char *p = "hello world!";用来声明一个指针p,指向“hello world!”字符串起始位置。
       从存储位置来说:
       char p[] = "hello world!";p数组作为局部变量被存储在栈区;
       char *p = "hello world!"; 在这个声明中,"hello world!"被存储在静态数据区,而且是全局的,p仅仅就是个指针,指向这个区域。不信的话你可以试试下边的代码,看是不是同一个地址:
       char *p1 = "hello world!";
       char *p2 = "hello world!";
       printf("p1:%x\np2:%x\n",p1,p2);
       从函数执行后的扫尾工作来看:
       C函数执行完之后对栈区进行清除操作,对静态数据区和堆则没有,因此第一个问题也就不难解释了,get_string_1()函数执行完就释放了栈区内存,所以根本就不存在存有"hello world!"声明时的内存,也就不可能有所输出。

        那么,写成char *p = "hello world!";到底合不合法呢?能不能这样写呢?
        这是一个历史问题,在const关键字被引入C语言之前,这样写是合法的,而且存在了很长的一段时间,大量的代码在此期间运用了这种写法,新版C语言为了兼容,故允许这样写,但最好不要这样,因为这种写法终会被淘汰,说不定哪天你的代码用了新版的编译器,然后莫名的出了问题,要找这个BUG估计不是一件容易的事。现在最好写成:
        const char *p = "hello world!";
        或者
        char p[] = "hello world!";
        那他们在操作和细节上有什么区别呢?
        区别很多,由于本人才疏学浅,只总结出以下几点,忘有知者补充:
        1. char *p = "hello world!"; 可以用p++操作,sizeof(p) == 4;
        2.char p[]="hello world!"; sizeof(p) == 12;

转载注明地址:
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大排量摩托芯片钥匙断了怎么办 夏天太热在宿舍没空调怎么办? 汽车钥匙掉了怎么办半路到不了家 当顾客说产品太贵的时候 怎么办 邮件还没有下载被发送者删除怎么办 绝地求生号被盗了怎么办邮箱没有用 暴雪忘了密码换了手机号怎么办 华为荣耀10看电视缓冲太慢怎么办 交易猫梦幻西游手游恶意仲裁怎么办 银色高跟鞋前面尖尖蹭掉色了怎么办 苹果账号邮箱和密码都忘了怎么办 网易云密码忘记了怎么办手机号换了 超市买过期东西但没有小票怎么办 网购退货商家已收货而不退款怎么办 手机号被别人注册了京东怎么办 中通快递把我发的货弄坏了了怎么办 在淘宝获取不了丰巢柜提货码怎么办 京东快递提货码数手机号错了怎么办 腾讯手游助手不能玩刺激战场怎么办 刚收的京东快递质量有问题怎么办 拼多多买家接受信息没有声音怎么办 苹果6s外放声音有杂音怎么办 华为手机不小心把视频删了怎么办 电脑做完系统不显示声卡了怎么办 苹果手机自带浏览器看视频卡怎么办 pr剪辑的时候视频太卡怎么办 小米手机忘记登录账号密码了怎么办 石膏线条软模硅胶模具气泡多怎么办 京东白条开通失败怎么办金牌用户 买家说我运费险没赔要投诉我怎么办 包邮有运费险的东西想退货怎么办 高锰酸钾沾到龟头上形成黑点怎么办 淘宝发货包邮买家退款运费怎么办 京东实名认证的手机号不用了怎么办 淘宝退货在自提柜 卖家不取怎么办 如果买家退货那卖家送的东西怎么办 陆金所注册手机号被占用要怎么办 重新登录而忘记密码和验证码怎么办 手机清理垃圾清掉的照片怎么办 收件人名字写错了拿不到快递怎么办 档案回原籍收件人写错了怎么办