#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. 快速切题 sgu135. Drawing Lines

    135. Drawing Lines time limit per test: 0.25 sec. memory limit per test: 4096 KB Little Johnny likes ...

  2. linux centos 虚拟机新安装后没有网络

    ping的时候出现 name or service not known的时候 可以 修改/etc/sysconfig/network-scripts/ifcfg-ens33 文件 vi ifcfg-e ...

  3. GPU编程自学7 —— 常量内存与事件

    深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...

  4. ios系统降级

    1.使用PP助手/iTunes备份好文件资料,以防重要信息丢失: 2.设备连接iTunes,按住Shift键之后点击“恢复iPhone”,选择已下载好的iOS8.4.1固件,等待更新完成即可. 注意要 ...

  5. URL 生成带文字二维码

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="u ...

  6. Nginx(Windows)

    Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器. 反向代理方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将 ...

  7. 编写 Target 检测 MSBuild / dotnet build 此次编译是否是差量编译

    MSBuild 或 Roslyn 编译项目时均支持差量编译,毕竟为了性能.我在 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译 一文中介绍 ...

  8. 十四年风雨路 苹果iMac电脑进化论

    1998年起,在CEO乔布斯的带领下,苹果先后创造除了“软糖”iMac G3.“台灯”iMac G4和“像框”G5.iMac凭借其漂亮的外形和强大的性能,迅速赢得了消费者们的喜爱,甚至改变了整个人类社 ...

  9. ES6必知必会 (六)—— Class

    1.在之前的JS面向对象编程中,如果定义一个构造函数,一般来说是这样: function Person( name , age ) { this.name = name; this.age = age ...

  10. {转载}需要同时设置 noatime 和 nodiratime 吗?

    相信对性能.优化这些关键字有兴趣的朋友都知道在 Linux 下面挂载文件系统的时候设置 noatime 可以显著提高文件系统的性能.默认情况下,Linux ext2/ext3 文件系统在文件被访问.创 ...