(转)c指针问题
字符串常量问题:
http://blog.csdn.net/zhongyili_sohu/article/details/8084188
1、 常量字符串
在代码里直接出现的”abcdef”这种字符串,在程序执行的时候,系统会将它们放在常量区,所谓常量区就是一直存在的,只读的,不可更改的数据区域,并且一个字符串只会有一份。假设你在程序里有两行代码
char* p1 = “agcd”;
char* p2 = “agcd”;
无论你这两个行代码隔了多远,如果你想知道p1和p2所指向的字符串在内存中是不是同一个,那答案是肯定的,p1和p2的值完全一样。”agcd”这是一个存在于内存中的常量字符串,它从程序一开始就在那里,一直到程序结束都不会改变。在内存中,”agcd”是以如下方式存储的
|
‘a’ |
’g’ |
‘c’ |
‘d’ |
‘\0’ |
它的最后肯定有一个字符串结束标志’\0’。这种字符串的名字叫“以空字符为结束标志的字符串”。
char* p1 = “agcd”;
如果你这时候想改变第一个字符的值,用p[0] =’b’,系统会报一个错,常量字符不能更改。(这里为什么指针可以当数组用,下面再解释)。
2、 字符数组
如果你定义一个char a[10],那么系统会“只分配”10个char这么长的内存区域,一个char是一个字节,那么系统会分配十个字节的内存空间,并且将这一片连续的内存空间的首地址赋值给a。也就是说“数组名的值是数组所在内存区域的首地址”换句话说“数组名是一个指针,指向数组第一个值的地址”。
如果你定义一个char a[] = “abcdefg”;这句代码就复杂点了。定义一个数组,数组长度未知,那么系统会根据等号后面的值来“初始化”这个数组,等号后面是什么?前面说过,它是一个常量字符串。在内存中占8个字节,7个字符加上一个结束标志。这时候在内存中就有两个”abcdefg”的字符串了,一个是常量区域的,另一个是根据前者复制了一份的。这句代码的意思就是复制一个常量区域的字符串,将复制后的字符串的首字母的地址赋值给a。
也就是说,最后a所指向的内存区域,已经不是常量里的”abcdefg”了,这里为什么要复制一份呢?原因是因为常量是不允许更改的,而数组一般都意味着需要修改,所以就复制了一份数据,放在非常量区域,就可以更改了。下面的测试程序可证明上述结论:
char* p1 = "abcdef";
char* p2 = "abcdef" ;
char a[]= "abcdef" ;
unsigned long dwP1 = (unsignedlong)p1 ;
//32位系统里的指针就是4个字节的整数,这样可以具体查看指针的值。
unsigned long dwP2 = (unsignedlong)p2 ;
unsigned long dwA = (unsignedlong)a ;
printf("p1的值(32位地址)= 0x%X\n",dwP1);
//%X是打印十六进制,X是大写,x是小写
printf("p2的值(32位地址)= 0x%X\n",dwP2);
printf("a的值(32位地址) = 0x%X\n",dwA);
(转)c指针问题的更多相关文章
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- enote笔记法使用范例(2)——指针(1)智能指针
要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- C++11 shared_ptr 智能指针 的使用,避免内存泄露
多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...
- c 数组与指针的使用注意事项
数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...
- Marshal.Copy将指针拷贝给数组
lpStatuss是一个UNITSTATUS*的指针类型实例,并包含SensorDust字段 //定义一个数组类型 byte[] SensorDust = new byte[30] //将指针类型拷贝 ...
- C++智能指针
引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...
- EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针
一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...
- 智能指针shared_ptr的用法
为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...
- 智能指针unique_ptr的用法
unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...
随机推荐
- webpack 通用模块(每个页面都用到的js)编译
1.项目目录 2.配置文件:webpack.config.js var htmlWebpackPlugin = require('html-webpack-plugin'); var webpack ...
- 17、Cocos2dx 3.0游戏开发找小三之内置的经常使用层:三剑客LayerColor、LayerGradient、Menu
重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30477587 为了方便游戏开发人员.Cocos2d- ...
- 编码gbk ajax的提交
客户端
- DataTable转List,转对象
DataTable转List public static List<T> ToListModel<T>(this DataTable table) where T : new( ...
- mosquitto配置文件详解
安装完成之后,所有配置文件会被放置于/etc/mosquitto/目录下,其中最重要的就是Mosquitto的配置文件,即mosquitto.conf,以下是详细的配置参数说明. # Config f ...
- 温度测量【RTD】
原理 温度是表征物体冷热程度的物理量,它可以通过物体随温度变化的某些特性(如电阻.电压变化等特性)来间接测量,通过研究发现,金属铂(Pt) 的阻值跟温度的变化成正比,并且具有很好的重现性和稳定性,利用 ...
- unity, SkinnedMeshRenderer.bones[i]不能直接赋值
SkinnedMeshRenderer.bones[i]=xxx,这样写不报错,但也不起作用. 正确的方法是: List<Transform> boneList=new List<T ...
- [svc]ip routing和no ip routing
ip routing: 查路由表, 如果ping的目的在RT中没有,不发出任何包(arp也不会发出) 如果RT中存在,则arp 下一跳,相当于no ip routing+配置网关 注: 静态路由: 指 ...
- 等边三角形---dfs
蒜头君手上有一些小木棍,它们长短不一,蒜头君想用这些木棍拼出一个等边三角形,并且每根木棍都要用到. 例如,蒜头君手上有长度为 11,22,33,33 的4根木棍,他可以让长度为11,22 的木棍组成一 ...
- Unity3D学习(十):使用VideoPlayer在UI上播放视频
前言 每一款游戏往往启动的第一次都会播放CG动画之类的,Unity本身对于移动平台也提供了一个接口. Handheld.PlayFullScreenMovie("path") 过场 ...