对于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[] 的认识的更多相关文章

  1. char *c和char c[]区别

    char *c和char c[]区别 问题引入:在实习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="abc",前者 ...

  2. C语言中strcpy(char *strDest, const char *strScr)字符串复制库函数的理解与分析

    1.原版的strcpy()函数原型 char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) &am ...

  3. 数组字符串与指针字符串的区别 char s[]="***" 和char *s="***"的区别

    char s[] = "wangshihui"; char *s = "wangshihui"; 皆宣告了s字符串,在C-style string的函数皆可使用 ...

  4. char a[]和char *a的比较

    指针和数组存在着一些本质的区别.当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作 为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是 ...

  5. C++ code:char pointers and char arrays(字符指针与字符数组)

    C-串的正确赋值.复制.修改.比较.连接等方式. #include<iostream> #pragma warning(disable: 4996)//这一句是为了解决“strrev”出现 ...

  6. char *s 和 char s[] 的区别

    最近的项目中有不少c的程序,在与项目新成员的交流中发现,普遍对于char *s1 和 char s2[] 认识有误区(认为无区别),导致有时出现“难以理解”的错误.一时也不能说得很明白,网上也搜了一下 ...

  7. 深入理解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种组合 ...

  8. char *s 和char s[]的区别

    char *s 和 char s[] 的区别小结 博客分类: C语言 c教育 . 最近的项目中有不少c的程序,在与项目新成员的交流中发现,普遍对于char *s1 和 char s2[] 认识有误区( ...

  9. C++中 char *s 和 char s[] 的区别

    原因 刚好看到给main传递参数,书上(C++Primer)说“ int main(int argc, char *argv[])也可以写成 int main(int argc, char **arg ...

随机推荐

  1. Testlink 机器重启后Access denied for user 'admin '@'localhost' (using password: YES)解决

    问题表现: 装完Testlink,重启系统后,在testlink权限未分配会出现如下提示: 1045 - Access denied for user 'Testlink '@'localhost' ...

  2. MySQL对结果进行排序order by

    order by {col_name | expr | position} [ASC | DESC] 查询结果     排序条件的顺序  决定   排序条件   的优先级 如果同一条件下值相等,那么启 ...

  3. Robot Framework自动化测试三(selenium API)

    Robot  Framework  Selenium  API 说明: 此文档只是将最常用的UI 操作列出.更多方法请查找selenium2Library 关键字库. 一.浏览器驱动 通过不同的浏览器 ...

  4. selenium+Python(生成html测试报告)

    当自动化测试完成后,我们需要一份漂亮且通俗易懂的测试报告来展示自动化测试成果,仅仅一个简单的log文件是不够的 HTMLTestRunner是Python标准库unittest单元测试框架的一个扩展, ...

  5. CoreJava笔记之JavaBean、静态方法static和final

    记住两句话: 1.属性是静态绑定到变量类型: 2.方法是动态绑定,由最终对象的方法决定 =============================== 关于JavaBean: 1.不是语法规则,是习惯 ...

  6. 【Lua】Lua + LWT + ExtJS构建目录树

    Lua处理后台逻辑,Lua lwt搭建后台程序,ExtJS根据后台传来的json数据构建目录树. 前台html和ExtJS代码不用多讲,直接上代码: treePanel.html <html&g ...

  7. oracle timestamp转换date及date类型相减

    --timestamp转换为date(ts字段为timestamp类型) ; --timestamp转换为date(ts字段为timestamp类型) ; --date相减 )) FROM dual; ...

  8. Django级联删除的选项

    Django级联删除的选项 Django模型中的on_delete属性具有如下选项: CASCADE 级联删除,也就是被引用的实体被删除后,相关的记录信息都会被删除. PROTECT 阻止删除被引用的 ...

  9. FocusBI: 使用Python爬虫为BI准备数据源(原创)

    关注微信公众号:FocusBI 查看更多文章:加QQ群:808774277 获取学习资料和一起探讨问题. <商业智能教程>pdf下载地址 链接:https://pan.baidu.com/ ...

  10. no jpeg in java.library.path;java.lang.NoClassDefFoundError: Could not initialize class sun.awt.image.codec.JPEGImageEncoderImpl

    no jpeg in java.library.path;java.lang.NoClassDefFoundError: Could not initialize class sun.awt.imag ...