#include<stdio.h>
#include<string.h> int main()
{
char a[] = "abcd"; //常指针a指向字符串常量"abcd"的首地址,a不能被改变(不可作为左值被重新赋值)
char *f = "abcd"; //f指向"abcd",上面a和这个f除了a是常指针之外没有区别,f可以作为左值 const char b[] = "safajshjf"; //常指针b指向"safajshjf"的首地址,且b指针不可更改,且数组内容不可更改
const char *c = "asdfdsgd"; //c指向"asdfdsgd"的首地址,且该内存段内容不可更改
char *const d = "safdsfgsdg"; //常指针d指向"safdsfgsdg"的首地址,且d本身不可更改
const char* const e = "adsgfsdg"; //常指针e指向"adsgfsdg"首地址,且e本身不可更改,且该内存段内容也不可更改 //上面c和d,e不同,c不是const的,c指向的内存区是const的,故c可以被重新赋值
c = "fasdffds"; //c被重新赋值为"fasdffds"的首地址
/*下面的三行都不行,因为数组名除了初始化时,再也不能作为左值了.而const类型的d和e也不能再作为左值.
a = "afds";
b = "asfdsfdgg";
d = "fasdgsdg";
e = "fasdfgg";
*/ //下面的可以,a和d指向的内存段内容都可以更改
strcpy(a,"sdfs");
strcpy(d,"sfsdgd");
/*下面的不通过,b,c,d指向的内容都不可更改
strcpy(b,"sfsdgf");
strcpy(c,"sfsgddg");
strcpy(e,"safsgdg");
*/ //下面把常指针赋值给非const指针,可以
f = a;
f = d;
/*以下赋值非法,编译出错.因b,c,e指向的内存区内容不可更改,如果进行下面的赋值,编译器不能保证别的地方不去使用f而改变内存区的内容
f = b;
f = c;
f = e;
*/ //下面的五个都是可以的,因为const和非const的变量都可以赋值给const类型的变量
const char *g = a;
g = b;
g = c;
g = d;
g = e; return ;
}

总结:

const指针的用法如上例所示,分别是限制指针和指针内存区域的,有这些限制,也仅是针对当前变量的限制,如果原本的内存地址已知,后来赋值给了const*类型的指针,那么利用原来的内存地址依然是可以修改该内存区域的.

数组名相当于*const类型的,因为数组名和*const在以后都不能再给数组名或指针赋值,而只能修改数组的内存区或指针指向的内存区.
const* typename const类型的是指针和内存区都不可以修改的.

特别注意上面的数组名a,这是个常指针.无论是整形数组还是字符数组,初始化的时候都是赋值初始化的,不要把字符数组的初始化理解成把一个常量字符串的指针赋值给了字符数组名.

看看下面的反汇编

    char a[] = "abcd";
mov eax,dword ptr [___xi_z+2Ch (4020E4h)]
mov dword ptr [ebp-0Ch],eax
mov cl,byte ptr [___xi_z+30h (4020E8h)]
0040174E mov byte ptr [ebp-],cl
const char b[] = "safader";
mov edx,dword ptr [___xi_z+34h (4020ECh)]
mov dword ptr [ebp-1Ch],edx
0040175A mov eax,dword ptr [___xi_z+38h (4020F0h)]
0040175F mov dword ptr [ebp-18h],eax
const char *c = "asdfdsgd";
mov dword ptr [ebp-24h],offset ___xi_z+3Ch (4020F4h)
char *const d = "safdsfgsdg";
mov dword ptr [ebp-20h],offset ___xi_z+48h (402100h)
const char* const e = "adsgfsdg";
mov dword ptr [ebp-28h],offset ___xi_z+54h (40210Ch)

可以看出来,这是上面的程序的前五行的代码的反汇编,前两行的是赋值,汇编代码可以看出来,先把静态区中的常量字符串赋值给了eax,然后后eax转给字符数组的内存区,但是后面的三个则是直接把静态区的常量字符串的地址赋值给了指针,如果只赋值给const*指针还好,但是连*const指针也是直接赋值,结果导致了后面的strcpy(d,"sfd")的静态区内存访问错误

本文转自:http://www.cppblog.com/FateNo13/archive/2009/07/29/91559.html

数组/指针/const/字符串常量的使用传值问题的更多相关文章

  1. 字符数组,字符指针,字符串常量,以及sizeof的一些总结

    1.以字符串形式出现的,编译器都会为该字符串自动添加一个\0作为结尾 如在代码中写"abc",编译器帮你存储的是"abc\0". 2.数组的类型是由该数组所存放 ...

  2. C语言基础 (9) 数组指针

    复习 只要把地址拿到就能这么操作.. (这里是合法的地址,不是野指针) 只有定义变量后,此变量的地址才是合法的地址 野指针就是保存没有意义地址的指针变量 操作野指针变量本身不会有任何问题 操作野指针所 ...

  3. Java中,那些关于String和字符串常量池你不得不知道的东西

    老套的笔试题 在一些老套的笔试题中,会要你判断s1==s2为false还是true,s1.equals(s2)为false还是true. String s1 = new String("xy ...

  4. C语言中的数组和指针以及字符串

    数组名同时也是该数组首元素的地址,而指针提供了一种用来使用地址的符号方法,因此指针能够很有效地处理数组. 将一个整数加给指针,这个整数会和指针所指类型的字节数相乘,然后所得的结果会加到初始地址上 da ...

  5. 【转】const int *p和int * const p的区别(常量指针与指向常量的指针)

    [转]作者:xwdreamer   出处:http://www.cnblogs.com/xwdreamer 对于指针和常量,有以下三种形式都是正确的: const char * myPtr = &am ...

  6. 【C】字符串常量和字符数组

    此次博客是转载某位博主的文章,不过现在找不到了,所以先声明一下. 先贴一段代码: #include <stdio.h> int main(int argc, const char** ar ...

  7. C++ 字符串指针与字符串数组

    在做面试100题中第21题时,发现char *astr="abcdefghijk\0";和char astr[]={"abcdefghijk"};有点区别,以前 ...

  8. C 语言中指针初始化为字符串常量 不可通过该指针修改其内容

    char b[] = "hello"; 则“hello”存于栈中,因为定义的是一个数组. char *b = "hello"; 则"hello&quo ...

  9. c++引用和const 用法 数组 指针

    非const引用,只能用object为其赋值: <c++primer>P52 而const引用则可以用临时变量为其赋值: 如: const int &r = 32://可以 int ...

随机推荐

  1. 利用Sonar定制自定义JS扫描规则(一)——sonar环境搭建

    接触sonar已经有段时间了,最早是在一个项目组里面听到这个框架,后来在公司持续集成活动的推动下,也逐渐学习了sonar的具体功能.sonar集成了findbugs,pmd,checkstyle各种静 ...

  2. mybatis异常:Could not find result map Java.util.Map 问题分析及解决 定位不到具体的位置的错误

    mybatis异常:Could not find result map Java.util.Map 问题分析及解决 报这个错误呢,很难受的就是你定位不到具体的地方,找不到位置修改,你只知道有错误,但是 ...

  3. ringojs 的包管理

    ringojs 集成了包管理目前有几种方式 ringo-admin rp ringo-admin 安装包 我们使用ringo-admin 安装rp ringo-admin install grob/r ...

  4. 使用nomad && consul && fabio 创建简单的微服务系统

    具体每个组件的功能就不详细说明了 nomad 一个调度工具,consul 一个服务发现,健康检查多数据中心支持的工具 fabio 一个基于consul的负载均衡&&动态路由工具,对于集 ...

  5. emacs之配置自动安装脚本

    emacsConfig下建立install目录,结构大概这样 . ├── auto-complete-etags-setting.el ├── auto-complete-setting.el ├── ...

  6. Java-Runoob-高级教程-实例-字符串:05. Java 实例 - 字符串反转

    ylbtech-Java-Runoob-高级教程-实例-字符串:05. Java 实例 - 字符串反转 1.返回顶部 1. Java 实例 - 字符串反转  Java 实例 以下实例演示了如何使用 J ...

  7. 1021 docker初识

    docker与虚拟机相比,没有虚拟化内核,转而使用宿主机的内核.因此docker更轻更快 docker缺点:后端兼容性测试需求.把软件安装在不同的操作系统上进行测试,观察软件运行是否良好. 不能用do ...

  8. PY安装模块

    Python安装失败原因 0环境 , pip版本一般为 7.x , 所以一般需要先升级pip版本 , 也就是执行 ```shellpython -m pip install --upgrade pip ...

  9. pyCharm最新2018激活码(转)

    原文地址:https://blog.csdn.net/u014044812/article/details/78727496 社区版和专业版区别: 因公司的需求,需要做一个爬取最近上映的电影.列车号. ...

  10. 基于DB的编程

    现在我们大多数的开发都是基于数据库,虽然数据库为我们提供了事务机制,保证存储的数据的ACID,但是,当我们在完成一个业务操作时,涉及到对数据库的大量操作,如果把这些操作在一个事务中,肯定是安全的,但是 ...