对于char *s1 和 char s2[] 的认识
对于char *s1 和 char s2[] 认识有误区(认为无区别),导致有时出现“难以理解”的错误。
char *s1 = "hello"; char s2[] = "hello";
【区别所在】
char *s1 的s1,而指针是指向一块内存区域,它指向的内存区域的大小可以随时改变,而且当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错。 char s2[]的s2 是数组对应着一块内存区域,其地址和容量在生命期里不会改变,只有数组的内容可以改变
【内存模型】 +-----+ +---+---+---+---+---+---+ s1: | *======> | h | e | l | l | o |\0 | +-----+ +---+---+---+---+---+---+ +---+---+---+---+---+---+ s2: | h | e | l | l | o |\0 | +---+---+---+---+---+---+
场景一) char *s1 = "hello"; char s2[] = "hello"; s2=s1; //编译ERROR s1=s2; //OK
分析:s2其地址和容量在生命期里不能改变
场景二) char s2[] = "hello"; char *s1 = s2; //编译器做了隐式的转换 实际为&s2 或 char *s1 = &s2;
分析:以上两个指针复值完全等价,由于编译器会做这个隐式转换也容易导致初学者误认为 char *s 与char s[]是一回事。 另用第二种在一些编译器甚至会报警告信息。
场景三) char *s1 = "hello"; char s2[] = "hello"; s1[0]='a'; //×运行ERROR( 这一句好像在一些的编译器不会出错,原因待查) s2[0]='a'; //OK
分析:运行时会报错,原因在于企图改变s1的内容,由于s1指向的是常量字符串,其内容是不可修改的,因此在运行时不会通过。而s2指向的是变量区字符串,可以修改。
场景四) 让我们来给一个指针的指针赋值,在使用某些含char**参数的函数时会用到,场景二的增强版。 char *s1="hello"; char s2[]="hello"; char *s3=s2; //★注意这句必须要★ char **s4=&s3; //s2(char[])要用两步才能完成赋值 char **s5=&s1; //s1(char*) 只需一步 printf("s4=[%s]\n",*s4);//打印结果:s4=[hello] printf("s5=[%s]\n",*s5);//打印结果:s5=[hello]
分析:这个例子应当说最能反映出char *与char []的差异,但是由于使用场合不多,新人尤其需要注意。
下面是一些char *s1 和 char s2[]相同的地方(同样编译器对char[]做了隐式变化): 1)作为形参完全相同 如: void function(char *s1); void function(char s1[]);
2)只读取不修改的时候 如: char *s1="hello"; char s2[]="hello"; printf("s1[1]=[%c]\n",s1[1]); //s1[1]=[e] printf("s2[1]=[%c]\n",s2[1]); //s2[1]=[e] printf("s1=[%s]\n",s1); //s1=[hello] printf("s2=[%s]\n",s2); //s2=[hello]
对于char *s1 和 char s2[] 的认识的更多相关文章
- char *c和char c[]区别
char *c和char c[]区别 问题引入:在实习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="abc",前者 ...
- C语言中strcpy(char *strDest, const char *strScr)字符串复制库函数的理解与分析
1.原版的strcpy()函数原型 char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) &am ...
- 数组字符串与指针字符串的区别 char s[]="***" 和char *s="***"的区别
char s[] = "wangshihui"; char *s = "wangshihui"; 皆宣告了s字符串,在C-style string的函数皆可使用 ...
- char a[]和char *a的比较
指针和数组存在着一些本质的区别.当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作 为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是 ...
- C++ code:char pointers and char arrays(字符指针与字符数组)
C-串的正确赋值.复制.修改.比较.连接等方式. #include<iostream> #pragma warning(disable: 4996)//这一句是为了解决“strrev”出现 ...
- char *s 和 char s[] 的区别
最近的项目中有不少c的程序,在与项目新成员的交流中发现,普遍对于char *s1 和 char s2[] 认识有误区(认为无区别),导致有时出现“难以理解”的错误.一时也不能说得很明白,网上也搜了一下 ...
- 深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p
由于没有const*运算,const实际上修饰的是前面的char*,但不能在定义时转换写成 const(char *)*p,因为在定义是"()"是表示函数. 三.深入理解7种组合 ...
- char *s 和char s[]的区别
char *s 和 char s[] 的区别小结 博客分类: C语言 c教育 . 最近的项目中有不少c的程序,在与项目新成员的交流中发现,普遍对于char *s1 和 char s2[] 认识有误区( ...
- C++中 char *s 和 char s[] 的区别
原因 刚好看到给main传递参数,书上(C++Primer)说“ int main(int argc, char *argv[])也可以写成 int main(int argc, char **arg ...
随机推荐
- (转)Cobbler自动化部署最佳实践
原文:http://www.xuliangwei.com/xubusi/446.html 运维自动化在生产环境中占据着举足轻重的地位,尤其是面对几百台,几千台甚至几万台的服务器时,仅仅是安装操作系统, ...
- 使用express创建node服务器的两种方法及区别
使用express创建node服务器有两种方法,如下所示: 方法一: var express = require('express'); var app = express(); app.listen ...
- 自动化测试之旅--selenium+python--001
在学习selenium之前,首先感谢网络上的虫师和乙醇老师,或许他们并不知道我这个菜鸟的存在,但是我仍然要感谢他们,因为在学习的路上拜读了许多他们的博客和文章,对于我来说有着很重要的意义,因此在学习之 ...
- web项目 log4j2 指定配置文件路径
pom.xml需要额外引入的jar: <dependency> <groupId>org.apache.logging.log4j</groupId> <ar ...
- Apache 反向代理 丢失Authorization
我后端API的服务器是Tomcat,而后端API验证是通过存放在头部Authorization的token值进行验证的. 我在测试Apache作为前端html解析的服务器时, 利用反向代理,把Api请 ...
- ajax上传数据
---恢复内容开始--- ajax上传数据,(简洁版) 1.上传普通同表单标签内容. 1.获取表单的内容 1. var file=$('#file').val();(放在点击事件后面) 2. var ...
- python4
列表的常用操作 创建列表 1.创建空列表 列表变量 = [] 2.创建单个数据的列表 列表变量 = [值] ...
- JS埋点 小结
今天在看<大型网站性能监测.分析与优化>一书,提到性能监测方式,才知道有这个名词 “JS埋点”. 大概作用:通过在web页面中,添加js脚本,实现对页面性能监测(如加载时间.服务器响应时间 ...
- DOM节点常见的属性及操作
(1)常见节点属性 childNodes 子节点 nodeList children 子节点(元素节点) HTMLCollection parentNode 父节点 p ...
- java 从Excel 输出和输入
本文实现了使用java 从数据库中获得对象,并存入集合中, 然后输出到Excel,并设置样式 package com.webwork; import java.io.File; import java ...