#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. SGU 138. Games of Chess 构造 难度:2

    138. Games of Chess time limit per test: 0.25 sec. memory limit per test: 4096 KB N friends gathered ...

  2. 修改Intelij IDEA的maven依据下载为国内镜像(阿里)

    1.win7环境,默认情况下在用户目录的.m2下自己新建setting文件.QQ群交流:697028234 .m2\settings.xml 2.settings.xml文件内容为: <sett ...

  3. U盘安装linix

    首先制作u盘启动器. 然后在电脑上使用UltraISO将你的安装的linix系统刻录到u盘上 在放入一份linix系统在u盘更目录 boot页面u盘启动.选择 第二次没有放入系统在u盘根目录出现这个: ...

  4. 常用Mysql存储引擎--InnoDB和MyISAM简单总结

    常用Mysql存储引擎--InnoDB和MyISAM简单总结 2013-04-19 10:21:52|  分类: CCST|举报|字号 订阅     MySQL服务器采用了模块化风格,各部分之间保持相 ...

  5. WebGL编程指南案例解析之绘制三角形

    //案例3.绘制三角形,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //顶点着色器中去掉gl_PointSize = 10.0,绘制三角不能设 ...

  6. 使用peach工具进行fuzz测试

    本文简要介绍了Fuzz 工具Peach的使用,并通过文件格式 Fuzz举例阐述了 Peach Pit 文件的编写. 本文转自“绿盟科技博客”:http://blog.nsfocus.net/peach ...

  7. .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换

    .NET/C# 程序从 Main 函数开始执行,基本上各种书籍资料都是这么写的.不过,我们可以写多个 Main 函数,然后在项目文件中设置应该选择哪一个 Main 函数. 你可能会觉得这样没有什么用, ...

  8. 启动zookeeper时,jps显示有进程,但是status查看状态时就Error contacting service. It is probably not running

    转自:http://www.cnblogs.com/xiaohua92/p/5460515.html#undefined 安装zookeeper时候,可以查看进程启动,但是状态显示报错:Error c ...

  9. USACO 2016 February Contest, Gold解题报告

    1.Circular Barn   http://www.usaco.org/index.php?page=viewproblem2&cpid=621 贪心 #include <cstd ...

  10. (转)Flex开发工具Flex Builder 3 下载及注册码

    本文转载自:http://blog.csdn.net/wlxtaking/article/details/5779762 Flex是通过java或者.net等非Flash途径,解释.mxml文件组织c ...