解析char *p与char p[]

news/2025/2/25 19:10:06
 解析char *p与char p[]


转自:http://yuhuafx.blog.hexun.com/35683001_d.html


 


见论坛上有人讨论这个问题,感觉也是涉及面比较广,而且很多人犯过这个错误,比如声明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;

http://www.niftyadmin.cn/n/3978514.html

相关文章

消息队列和管道的区别(转载)

消息队列和管道的区别(转载) 转载自:http://bbs.chinaunix.net/viewthread.php?tid265266作者:beginner-bj请问管道和消息队列有什么不同管道通信(PIPE)管道通信方式的中间介质是文件,通常称这种文件为管道文件。两个…

[转]太网帧结构详解

常见以太网帧结构详解1 以太网相关背景 以太网这个术语通常是指由DEC,Intel和Xerox公司在1982年联合公布的一个标准,它是当今TCP/IP采用的主要的局域网技术,它采用一种称作CSMA/CD的媒体接入方法。几年后,IEEE802委员会公布了一个…

【转】基于C语言的内存池的设计与实现

此文档转至于: http://blog.csdn.net/ugg/archive/2007/03/27/1543290.aspx 介绍: 设计内存池的目标是为了保证服务器长时间高效的运行,通过对申请空间小而申请频繁的对象进行有效管理,减少内存碎片的产生,合理分配管理…

big-endian little-endian

http://wxxweb.blog.163.com/blog/static/135126900201022133740759/ 大端模式与小端模式一、概念及详解   在各种体系的计算机中通常采用的字节存储机制主要有两种: big-endian和little-endian,即大端模式和小端模式。   先回顾两个关键词&#xff…

char 和 varchar的区别

1、char, nchar 是定长的varchar, nvarchar 是变长的 2、char 长度固定,长度不够,用空格替代varchar 长度可变,长度不够,不用空格替代char比varchar所消耗的系统资源要多。 3、LEN函数返回给定字符串表达式的字符(而不…

vmware上安装vxworks(xp环境)

搞了两天,终于ok了,哈皮! 我是按这篇文章一步一步去做的,但是还是有很多让你痛不欲生的错误出现,可能与电脑环境相当大的关系吧。由于网上各种解决方案我都用了,最后成功了都不知道到底哪几种才是我问题的解…

RTOS优先权反转问题

RTOS优先权反转问题定义: 高优先级的任务由于要等待被低优先级任务占有的临界资源而被中优先级任务阻塞,而此时具有中优先级的任务抢占了低优先级任务的CPU时间,导致具有中优先级的任务先于高优先级任务而执行。 举例:3个任务优先…

VxWorks编程常用函数说明

VxWorks编程常用函数说明 一、官方的Program Guide 位于安装目录下:\docs\vxworks\guide\index.html 二、常用的库: #include "taskLib.h" /* 任务 */ #include "msgQLib.h" /* 消息队列 */ #include "semLib.h" /* 信号…