char *p=abc 与 char p[]=abc 的区别
有这样一段代码:
view plaincopy
#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!
1.为什么输出结果是这样?
2.字符串"abc"是常量吗?
3.char *p = "abc";这样写到底合不合法,实际应用中能不能这样写?
解析:
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!"声明时的内存,也就不可能有所输出。
第二个问题:"abc"是常量吗?答案:有时是,有时不是
(1)不是常量的情况:
"abc"作为字符数组初始值的时候就不是,如
char str[] = "abc";
因为定义的是一个字符数组,所以就相当于定义了一些空间(注意!)来存放"abc",而又因为字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
char str[3] = {'a','b','c'};
以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,所以char str[] = "abc";的最终结果是
char str[4] = {'a','b','c','\0'};
做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里的"abc\0"因为不是常量,所以应该被放在栈上。
(2)是常量的情况:
把"abc"赋给一个字符指针变量时,如
char* ptr = "abc";
因为定义的是一个普通指针,并没有定义空间(注意!)来存放"abc",所以编译器得帮我们找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序常量区中的东西。
第三个问题,char *p = "hello world!";这样写到底合不合法?
记得哪本书中曾经说过char* ptr = "abc";这种写法原来在c++标准中是不允许的,但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,但是建议的写法应该是 const char* ptr = "abc";这样如果后面写ptr[0] = 'x'的话编译器就不会让它编译通过,也就避免了上面说的运行时异常。
再扩展一下:
1.如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc\0"被放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,只不过是它所指向的东西被放 在常量区罢了。
2.字符串常量的类型可以理解为相应字符常量数组的类型,如"abcdef"的类型就可以看成是const char[7] 。
3.如果真的需要使用"abcd"作为指针,建议写为const char * p="abcd";
4.如果是初始化字符串数组,建议写为char p[]="abcd";
5.如果p为指针,需要初始化,应该是char *p;p=malloc(STR_SIZE);strcpy(p,"abcd");
char *p=abc 与 char p[]=abc 的区别相关推荐
- char *c = abc和char c[]=abc
转自:http://blog.csdn.net/wallwind/article/details/7210474 char *c = "abc"和char c[]="ab ...
- char* str = abc ;跟char str[] = abc;的区别
突然发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="abc",前者改变其内容程序是会崩溃的,而后者完全正确. 程序演示: ...
- 面试题--字符串指针与字符串数组的区别char* st=abc;与char* str[]=abc;的异同
题1. 删除串中指定的字符(做此题时,千万不要开辟新空间,否则面试官可能认为你不适合做嵌入式开发) 参考代码: void delChar(char* str, char c) { int i, j ...
- java char 打印_Java中char[]输出不是内存地址的原因详解
前言 Java中共有八种基本数据类型:byte,int,short,long,float,double,char,boolean. 计算机中的基础数据单位是bit, 1byte=8bit. 数据类型 ...
- C++中 char* 、string、 char、char[]在各种情况下的输入与输出
之前在自己练手写代码的时候总是会在字符串,字符这一块卡住,今天写下这篇文章给自己长长记性! 其实在代码过程中会遇到很多很玄学的问题.刚刚在尝试的时候找到了之前写的测试字符串的程序,放到另外一个工程里跑 ...
- c语言char数组和short数组的区别,详解C语言中Char型指针数组与字符数组的区别
详解C语言中Char型指针数组与字符数组的区别 详解C语言中Char型指针数组与字符数组的区别 1.char 类型的指针数组:每个元素都指向一个字符串,指向可以改变 char *name[3] = { ...
- String a = “abc“ 和 new String(“abc“)的区别
String a = "abc":String b = "abc": JVM会使用常量池来管理字符串直接量.在执行这句话时,JVM会先检查常量池中是否已经存有& ...
- 报错笔记:cannot convert parameter 1 from 'char [1024]' to 'unsigned char *'
第一段:数组的类型是char,因此函数在引用const char 型的指针的时候,必须用char类型数组的首地址.如果是byte类型的指针的首地址,则会报cannot convert paramete ...
- 深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const
原文网址:http://www.cnblogs.com/rushuizhijing/archive/2011/08/26/2154737.html 深入理解const char*p,char cons ...
最新文章
- ubuntu 安装ImageMagic
- Training—Managing Audio Playback
- linux学习笔记:1.基础知识和命令行基本操作
- centos7 安装rabbitMQ3.6.6
- 相对完善的Java通过JDBC操纵mysql的例子
- 算法:递归-八皇后问题(回溯算法)
- Controller @Autowired注解 无法注入值为null的问题
- activeperl安装不成功_SWOOLE进阶-00环境安装
- 华人运通高合HiPhiX维修手册电路图技术培训用户手册资料
- CAD图纸转BMP格式图片时怎么设置输出色彩?
- 计算机无法 鼠标没反应,鼠标插电脑上没反应怎么回事_鼠标连接电脑没反应的解决步骤...
- Vmware虚拟机设置固定IP地址
- Vue el-upload插件上传批量文件
- python绘制包络线_包络线和包络谱计算程序
- 学会这招,远离年金险99%的坑
- 第147杆147分诞生!吉尔伯特冠军联赛创历史
- 云桌面与桌面云,到底有什么区别?
- J2SE-Java基础
- android 手机扔起来的高度,三防AGM X2评测:吴京硬汉本色扔海里也不怕
- Prometheus 服务发现
热门文章
- EMNLP 2022投稿要求
- 《海错图笔记》的笔记 |【介部】
- 如果你因为这个辞职,下一份工作也不会好
- com.google.protobuf.ServiceException: java.lang.NoClassDefFoundError: com/yammer/metrics/core/Gauge
- 火线精英服务器维护要多长时间,火线精英游戏退款过程 绝对实用不取巧
- Semi-Supervised Semantic Image Segmentation with Self-correcting Networks基于自校正网络的半监督图像语义分割
- Module not found: Error: Can‘t resolve
- Android辅助功能实现自动抢红包
- Java面向对象三大特征:封装、继承、多态
- CoCosCreator2.2.1 入门教程