数组/指针/const/字符串常量的使用传值问题
#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/字符串常量的使用传值问题的更多相关文章
- 字符数组,字符指针,字符串常量,以及sizeof的一些总结
1.以字符串形式出现的,编译器都会为该字符串自动添加一个\0作为结尾 如在代码中写"abc",编译器帮你存储的是"abc\0". 2.数组的类型是由该数组所存放 ...
- C语言基础 (9) 数组指针
复习 只要把地址拿到就能这么操作.. (这里是合法的地址,不是野指针) 只有定义变量后,此变量的地址才是合法的地址 野指针就是保存没有意义地址的指针变量 操作野指针变量本身不会有任何问题 操作野指针所 ...
- Java中,那些关于String和字符串常量池你不得不知道的东西
老套的笔试题 在一些老套的笔试题中,会要你判断s1==s2为false还是true,s1.equals(s2)为false还是true. String s1 = new String("xy ...
- C语言中的数组和指针以及字符串
数组名同时也是该数组首元素的地址,而指针提供了一种用来使用地址的符号方法,因此指针能够很有效地处理数组. 将一个整数加给指针,这个整数会和指针所指类型的字节数相乘,然后所得的结果会加到初始地址上 da ...
- 【转】const int *p和int * const p的区别(常量指针与指向常量的指针)
[转]作者:xwdreamer 出处:http://www.cnblogs.com/xwdreamer 对于指针和常量,有以下三种形式都是正确的: const char * myPtr = &am ...
- 【C】字符串常量和字符数组
此次博客是转载某位博主的文章,不过现在找不到了,所以先声明一下. 先贴一段代码: #include <stdio.h> int main(int argc, const char** ar ...
- C++ 字符串指针与字符串数组
在做面试100题中第21题时,发现char *astr="abcdefghijk\0";和char astr[]={"abcdefghijk"};有点区别,以前 ...
- C 语言中指针初始化为字符串常量 不可通过该指针修改其内容
char b[] = "hello"; 则“hello”存于栈中,因为定义的是一个数组. char *b = "hello"; 则"hello&quo ...
- c++引用和const 用法 数组 指针
非const引用,只能用object为其赋值: <c++primer>P52 而const引用则可以用临时变量为其赋值: 如: const int &r = 32://可以 int ...
随机推荐
- MapReduce中文翻译
MapReduce:超大机群上的简单数据处理 摘要 MapReduce是一个编程模型,和处理,产生大数据集的相关实现.用户指定一个map函数处理一个key/value对,从而产生中间的key/va ...
- json.dumps与json.dump的区别 json.loads与json.load的区别(简洁易懂)
json.dumps是将一个Python数据类型列表进行json格式的编码解析, 示例如下: >>> import json #导入python 中的json模块 >>& ...
- Haproxy的负载均衡和高可用配置
一.Haproxy的理解 Haproxy是一个使用c语言编写的自由开发源代码软件,它提供高可用性.负载均衡.以及基于http和tcp的应用程序代理. Haproxy特别使用于那些负载特别大 ...
- IOS NSCharacterSet 去除NSString中的空格
去除 username中的空格,table newline,nextline 代码如下: NSCharacterSet *whitespace = [NSCharacterSet whitespac ...
- CtaAlgo vs PyAlgoTrade
转自知乎:https://zhuanlan.zhihu.com/p/21971854 在Python量化领域,PyAlgoTrade和zipline并列两大策略回测框架的先驱,其中PyAlgoTrad ...
- LNMP环境下独立安装Mysql5.7.18 并对数据库文件进行本地物理迁移 (需暂停数据库服务方式)
前几天读研时候的同学要我帮忙给解决一个问题,就是Redhat服务器下面安装了LNMP,并且由于分区的划分不当导致MySQL数据库中存放数据库的盘区内空间被急剧消耗,由于该应用主要是数据分析及备份所用, ...
- maven安装之后,或者升级之后遇到的问题:could not find or load main class org.codehaus.plexus.class.....
从maven2升级到maven3或者从maven3降级到maven2,M2_HOME环境变量改变后,在终端执行mvn -v,出现如下错误: Exception in thread "main ...
- iis6 , URL重写HTM文件名后,出现真实的HTM文件不能访问的解决
服务器环境是windows 2003 IIS6 在web.config文件中加入 1.在<compilation debug="true"> 节点加入 <buil ...
- SpookyOTP
https://pypi.python.org/pypi/SpookyOTP/1.1.1 SpookyOTP 1.1.1 Downloads ↓ A lightweight Python 2/3 pa ...
- Linux下利用Shell使PHP并发采集淘宝产品
上次项目中用到<<PHP采集淘宝商品>> 此方法有一个缺点,就是执行效率问题.一个商品采集平均需要0.8秒.那10000个商品采集完需要2个半小时. 首先想到的解决办法是并发. ...