char *p="abc" 与 char p[]="abc" 的区别
本文来源于网络 出处:点我
有这样一段代码:
#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 ;
}
输出:
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!"声明时的内存,也就不可能有所输出。
(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"因为不是常量,所以应该被放在栈上。
把"abc"赋给一个字符指针变量时,如
char* ptr = "abc";
因为定义的是一个普通指针,并没有定义空间(注意!)来存放"abc",所以编译器得帮我们找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序常量区中的东西。
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" 的区别的更多相关文章
- unicode下各种类型转换,CString,string,char*,int,char[]
把最近用到的各种unicode下类型转换总结了一下,今后遇到其他的再补充: 1.string转CString string a=”abc”; CString str=CString(a.c_str() ...
- char *s="string"和char s[]="string"的区别
char *s="string"的内容是不可以改的 void main() { char* pStr1 = "Hello!"; char pSt ...
- Oracle CHAR,VARCHAR,VARCHAR2,nvarchar类型的区别与使用(转载)
一 varchar,varchar2,nvarchar,nvarchar2 四个类型都属于变长字符类型, varchar和varchar2的区别在与后者把所有字符都占两字节,前者只对汉字和全角等字符占 ...
- Sql Server char、varchar、nchar、nvarchar的区别
(1) 定义: char: 固定长度,存储ANSI字符,不足的补英文半角空格. nchar: 固定长度,存储Unicode字符,不足的补英文半角空格 varchar: 可变长度,存储ANSI字符,根据 ...
- 【转】深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p
一.可能的组合: (1)const char*p (2)char const*p (3)char *const p(4)const char **p (5)char const**p (6)char ...
- C# byte[]与char[]、string与char[]、byte[] 与 string 互转
1. byte array -> char array Byte[] b=new byte[5]{0x01,0x02,0x03,0x04,0x05}; Char[] c=Encoding.AS ...
- C语言中为什么不能把char**赋给const char**
这是我在知乎回答的一个问题. 这个问题是C中的一个深坑,首先说结论: char ** 和 const char ** 是两个不相容(incompatible)的类型,能够理解为不能直接赋值 在C11的 ...
- 将字符串“abc”全排列成:abc、acb、bac、bca、cab、cba
[STAThread] static void Main() { string s = "abcd"; ...
- error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> >
1,VS2013: 错误 1 error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_trai ...
随机推荐
- DNS 解析流程
DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工 ...
- 关系数据库域关系演算语言QBE
QBE: Query By Example 基于屏幕表格的查询语言 查询要求:以填写表格的方式构造查询 用示例元素(域变量)来表示查询结果可能的情况 查询结果:以表格形式显示 QBE操作框架 ...
- 转:Python正则表达式指南
本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例.本文的内容不包括如何编写高效的正则表达式.如何优化正则表达式,这些主题请查看其他教程 ...
- JS,JQUERY 常用笔记
JSON.parse() 转成数组对象 JSON.stringify() 转成JSON字符串
- 简单的方法实现仿微信底部的Tab选项卡界面
在网上看了比较多的关于Tab的教程,发现都很杂乱.比较多的用法是用TitlePagerTabStrip和ViewPaper.不过TitlePagerTabStrip有个很大的缺陷,Tab里面的内容刚进 ...
- 最长上升子序列(LIS)
最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS.排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了. 假设存在一个序列d[1..9] = ...
- 【283】ArcMap 中河流字体设置
左斜字体的设置 1. 右键属性设置如下,将字体角度如下设置,并点击改变样式的按钮 2. 首先设置颜色如下,然后设置加粗斜体,最后勾选 CJK character orientation 的复选框 C ...
- Linux ALSA声卡驱动之一:ALS…
声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢! 一. 概述 ALSA是Advanced Linux Sound Architecture ...
- arm-linux-gcc-4.5.1的安装…
原文地址:arm-linux-gcc-4.5.1的安装方法作者:游牧 说明:我使用的是在虚拟机下的红帽linux5 ,通过终端工具SecureCRT操作,使用虚拟机等其他工具的过程大致相同 1.使用r ...
- swift之弹出一个背景半透明的UIViewController
坑爹的背景半透明,按网上给出oc的方法,动画结束之后,半透明效果消失.通过各种折腾,各种试验,终于搞定了. let viewController=storyboard.instantiateViewC ...