字符串常量问题:

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指针问题的更多相关文章

  1. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  2. enote笔记法使用范例(2)——指针(1)智能指针

    要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...

  3. C++虚函数和函数指针一起使用

    C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...

  4. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

  5. c 数组与指针的使用注意事项

    数组变量和指针变量有一点小小的区别 所以把数组指针赋值给指针变量的时候千万要小心 加入把数组赋值给指针变量,指针变量只会包含数组的地址信息 而对数组的长度一无所知 相当于指针丢失了一部分信息,我们把这 ...

  6. Marshal.Copy将指针拷贝给数组

    lpStatuss是一个UNITSTATUS*的指针类型实例,并包含SensorDust字段 //定义一个数组类型 byte[] SensorDust = new byte[30] //将指针类型拷贝 ...

  7. C++智能指针

    引用计数技术及智能指针的简单实现 基础对象类 class Point { public: Point(int xVal = 0, int yVal = 0) : x(xVal), y(yVal) { ...

  8. EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针

    一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...

  9. 智能指针shared_ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  10. 智能指针unique_ptr的用法

    unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...

随机推荐

  1. 使用SimHash进行海量文本去重

    阅读目录 1. SimHash与传统hash函数的区别 2. SimHash算法思想 3. SimHash流程实现 4. SimHash签名距离计算 5. SimHash存储和索引 6. SimHas ...

  2. 解决github push错误The requested URL returned error: 403 Forbidden while accessing(转)

    github push错误: git push error: The requested URL returned error: 403 Forbidden while accessing https ...

  3. windows bat文件运行中文乱码

      windows bat文件运行中文乱码 CreationTime--2018年7月17日08点51分 Author:Marydon 1.情景展示 运行bat文件,里面的中文提示显示乱码 2.问题剖 ...

  4. How vacuum template0

    [pg@h1 ~]$ vacuumdb --freeze template0 vacuumdb: could not connect to database template0: FATAL: dat ...

  5. 卡特兰数(Catalan数)

    首先奉上高中的排列组合公式,防止某些人忘记了 卡特兰数: 规定h(0)=1,而h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,h(6)=132,h(7)=C(14,7)-C( ...

  6. 获取含有class为某个值的a标签或img标签

    <a\s+[^>]*class='fjLink'[^>]*>[^<]*</a>|<img\s+[^>]*class='fjLink'[^>] ...

  7. 如何修改浏览器默认的alert样式?

    window.alert = function(str) { var shield = document.createElement("DIV"); shield.id = &qu ...

  8. Uva 10815-Andy&#39;s First Dictionary(串)

    Problem B: Andy's First Dictionary Time limit: 3 seconds Andy, 8, has a dream - he wants to produce ...

  9. pip install 安装提示unknown 包

    pip install setuptools --upgrade should fix the issue

  10. [svc]jq神器使用

    jq神器 处理json数据 支持过滤某字段 支持数学运算(对字段处理) 安装 yum install -y jq 使用 参考: http://blog.just4fun.site/command-to ...