- 浏览: 38038 次
- 性别:
- 来自: 上海
最近访客 更多访客>>
最新评论
-
shi5jin:
呵呵,我看的是Effective C++第三版,第一个item ...
站在巨人肩上的思考[连载] (5) -
bigpanda:
欢迎讨论远程数据库和rpc的编程。
“《Effective ...
站在巨人肩上的思考[连载] (5) -
spinach:
读完这两节,我基本就一个字,“基本帅呆了”。
站在巨人肩上的思考 [连载] (3) -
spinach:
终于等到了,慢慢看。
站在巨人肩上的思考 [连载] (2) -
spinach:
期待下文
站在巨人肩上的思考 [连载] (1)
5.2 数组
5.2.2 字符串文字量
类似”this is a string.”这样一个字符串文字量,它是一个常量。正如代码中一个显式的数字0xff08一样,其值不可以被更改。如想修改,可以通过复制给一个变量来实现:
<v:shapetype id="_x0000_t202" path="m,l,21600r21600,l21600,xe" o:spt="202" coordsize="21600,21600"><v:stroke joinstyle="miter"></v:stroke><v:path o:connecttype="rect" gradientshapeok="t"></v:path></v:shapetype><v:shape id="_x0000_s1034" style="WIDTH: 374.2pt; HEIGHT: 36.05pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin" strokeweight="1pt" strokecolor="#95b3d7" type="#_x0000_t202"><v:fill type="gradient" focus="100%" focussize="" focusposition="1" color2="#b8cce4"></v:fill><v:shadow opacity=".5" type="perspective" offset2="-3pt" offset="1pt" color="#243f60" on="t"></v:shadow><v:textbox>
int a = 0xff08; a = 0xff18; |
对于字符串文字量则有一点要注意:
<v:shape id="_x0000_s1033" style="WIDTH: 374.2pt; HEIGHT: 72.85pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin" strokeweight="1pt" strokecolor="#95b3d7" type="#_x0000_t202"><v:fill type="gradient" focus="100%" focussize="" focusposition="1" color2="#b8cce4"></v:fill><v:shadow opacity=".5" type="perspective" offset2="-3pt" offset="1pt" color="#243f60" on="t"></v:shadow><v:textbox>
char* cp = “this is a string”; //危险!赋值给一个普通字符指针; cp[4] = ‘e’; //未定义行为!不能给常量赋值; char p[] = “this is a string”; //可以; p[4] = ‘e’; //正确执行; |
可以看出,用char *来引用字符串文字量是一个十分危险的地方。在上例中cp[4]=’e’;可以通过编译,但是在执行期间产生了一个Segmentation Fault。也就是说编译器并不能帮助程序员发现这类错误。
我个人是这样认为的:字符串文字量是一中很底层的数据,编译器把他放进汇编语言中的数据段;普通的char*指针也是一种很底层的指针,他可以指向内存空间中的任何地址;char* cp = “this is a string”;仅仅在栈空间生成一个指针,然后把他指向位于数据段的”this is a string”,初始化并不会导致错误。但是利用cp[4]更改数据段中的数据内容将会导致段错误,数据段是只读的。而利用char p[]形式的时候,意味着将在栈空间中生成一个字符数组,然后用”this is a string”来进行初始化,而后p指向这个栈空间中字符数组的首地址。此时p[4]=’e’;修改的是栈空间中的值,而不是数据段中的值。
但是p是什么类型呢?是char*么?他的大小是多少?是1么?为了使指针和数组首地址之间的区别更具普遍意义,我们用int类型来测试一下:
<v:shape id="_x0000_s1032" style="WIDTH: 374.2pt; HEIGHT: 104.65pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin" strokeweight="1pt" strokecolor="#95b3d7" type="#_x0000_t202"><v:fill type="gradient" focus="100%" focussize="" focusposition="1" color2="#b8cce4"></v:fill><v:shadow opacity=".5" type="perspective" offset2="-3pt" offset="1pt" color="#243f60" on="t"></v:shadow><v:textbox>
char p[] = "hello"; char* ptr = p; cout << sizeof(p) << ":" << sizeof(*p) << endl; cout << p << ":" << *p << endl; cout << sizeof(ptr) << ":" << sizeof(*ptr) << endl; cout << ptr << ":" << *ptr << endl; |
这段代码在我的电脑上的输出是:
<v:shape id="_x0000_s1031" style="WIDTH: 374.2pt; HEIGHT: 87.2pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin" strokeweight="3pt" strokecolor="#f2f2f2 [3041]" type="#_x0000_t202" fillcolor="black [3200]"><v:shadow opacity=".5" type="perspective" offset2="-1pt" offset="1pt" color="#7f7f7f [1601]" on="t"></v:shadow><v:textbox style="mso-next-textbox: #_x0000_s1031">
[/home/gavin/test]# ./test 6:1 hello:h 4:1 hello:h |
ptr是真正的char*类型,其sizeof是4,但是p的sizeof却是6,也就是”hello”加一个‘\0’的长度。除此之外,ptr和p表现都一样。但我们最好认为p是字符数组类型,而ptr才是字符指针类型,因为他们的行为上存在差异。很多教师、教材都说:“数组名就是指向数组首地址的指针。”这其实并不完全正确。
再仔细看看,我们cout<<p和cout<<ptr的期望输出应该是p和ptr分别表示的地址。但事实上却是数组的内容。为了明显区分,再看下面这段代码:
<v:shape id="_x0000_s1030" style="WIDTH: 374.2pt; HEIGHT: 104.65pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin" strokeweight="1pt" strokecolor="#95b3d7" type="#_x0000_t202"><v:fill type="gradient" focus="100%" focussize="" focusposition="1" color2="#b8cce4"></v:fill><v:shadow opacity=".5" type="perspective" offset2="-3pt" offset="1pt" color="#243f60" on="t"></v:shadow><v:textbox>
int arr[4] = {0}; int* pa = arr; cout << sizeof(arr) << ":" << sizeof(*arr) << endl; cout << arr << ":" << *arr << endl; cout << sizeof(pa) << ":" << sizeof(*pa) << endl; cout << pa << ":" << *pa << endl; |
在我的电脑上输出为:
<v:shape id="_x0000_s1029" style="WIDTH: 374.2pt; HEIGHT: 87.2pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin" strokeweight="3pt" strokecolor="#f2f2f2" type="#_x0000_t202" fillcolor="black"><v:shadow opacity=".5" type="perspective" offset2="-1pt" offset="1pt" color="#7f7f7f" on="t"></v:shadow><v:textbox style="mso-next-textbox: #_x0000_s1029">
[/home/gavin/test]# ./test 16:4 0xbfc26e5c:0 4:4 0xbfc26e5c:0 |
sizeof的输出刚才已经说过。这里可以看出,int数组名和char数组名的行为也不一样。事实上,cha数组名与标准类型数组名的行为都不一样。这也就是为什么C风格字符串为许多人诟病的地方。
C++在这方面提供了很好的改进:用一种更上层的类型string来代替C风格字符串。并强烈建议程序员在程序中尽量使用string来代替char *。这里是你需要做出选择的地方:
<v:shape id="_x0000_s1028" style="WIDTH: 374.2pt; HEIGHT: 180.35pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin" strokeweight="1pt" strokecolor="#95b3d7" type="#_x0000_t202"><v:fill type="gradient" focus="100%" focussize="" focusposition="1" color2="#b8cce4"></v:fill><v:shadow opacity=".5" type="perspective" offset2="-3pt" offset="1pt" color="#243f60" on="t"></v:shadow><v:textbox>
string str1("1"); string str2("1234567"); string str3("1234567890123456789012345678901234567890"); /* char str1[] = "1"; char str2[] = "1234567"; char str3[] = "1234567890123456789012345678901234567890"; */ cout << sizeof(str1) << endl; cout << sizeof(str2) << endl; cout << sizeof(str3) << endl; |
当利用C风格字符串的输出为:
<v:shape id="_x0000_s1027" style="WIDTH: 374.2pt; HEIGHT: 123pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin; mso-left-percent: -10001; mso-top-percent: -10001; mso-position-horizontal: absolute; mso-position-vertical: absolute" strokeweight="3pt" strokecolor="#f2f2f2" type="#_x0000_t202" fillcolor="black"><v:shadow opacity=".5" type="perspective" offset2="-1pt" offset="1pt" color="#7f7f7f" on="t"></v:shadow><v:textbox style="mso-next-textbox: #_x0000_s1027">
[/home/gavin/test]# ./test 2 8 41 [/home/gavin/test]# ls -l -rwxrwxr-x 1 863 863 6559 Dec 3 14:29 test -rw-rw-r-- 1 863 863 391 Dec 3 14:29 test.cpp |
而当使用string时:
<v:shape id="_x0000_s1026" style="WIDTH: 374.2pt; HEIGHT: 123pt; mso-position-horizontal-relative: char; mso-position-vertical-relative: line; mso-width-relative: margin; mso-height-relative: margin; mso-left-percent: -10001; mso-top-percent: -10001; mso-position-horizontal: absolute; mso-position-vertical: absolute" strokeweight="3pt" strokecolor="#f2f2f2" type="#_x0000_t202" fillcolor="black"><v:shadow opacity=".5" type="perspective" offset2="-1pt" offset="1pt" color="#7f7f7f" on="t"></v:shadow><v:textbox style="mso-next-textbox: #_x0000_s1026">
[/home/gavin/test]# ./test 4 4 4 [/home/gavin/test]# ls -l -rwxrwxr-x 1 863 863 7578 Dec 3 14:30 test -rw-rw-r-- 1 863 863 390 Dec 3 14:30 test.cpp |
我们也许可以得到如下结论:sting比char[]需要更少的运行时内存空间,但是char[]却比string占用更少的磁盘空间。你可以自己选择向左还是向右走。不过相比string的易用性、安全性、以及诸多的成员函数带来的实用功能来说,我个人并不认为char[]节省的磁盘空间是很突出的优点。
发表评论
-
站在巨人肩上的思考[连载] (7)
2007-12-03 14:56 11334.8 枚举 枚举是表示具有共同属性的整 ... -
一种“标准”的虚函数机制简介
2007-11-09 11:07 1295编译器是如何针对虚函数产生可以再运行时刻确定被调用函数 ... -
A Generic Ostream Iterator
2007-09-07 08:37 1379by Christopher Diggins November ... -
我能从构造函数调用虚函数吗?
2007-09-06 11:18 2788可以。不过你得悠着点 ... -
为何我的构造函数不太对劲?
2007-09-06 10:57 1179类似这样的问题千奇百怪。例如: ... -
如何在类中定义常量?
2007-09-06 10:51 2531如果你想得到一个可用 ... -
为何空类的大小不是零?
2007-09-06 10:46 1922为了确保两个不同对象的地址不同,必须如此。也正因为如此,new ... -
我应该怎样处理内存泄漏?
2007-09-06 10:43 974很 简单,只要写“不漏 ... -
您可以推荐一种编写代码的标准吗?
2007-09-06 10:36 1334C++ 代码编写标准的要点是:根据使用 C++ 的具体的 ... -
如何使用异常?
2007-09-05 09:34 1019请参考 TC++PL 章节 8.3、第十四章,以及附录 E。附 ... -
为何C++既有指针也有引用?
2007-09-05 09:28 893C++ 的指针继承于 C,若要移除指针,势必造成严重的兼容性 ... -
可以在构造函数里抛出异常吗?析构函数里呢?
2007-09-05 09:24 2359可以:当你不能正常地初始化(构造)对象时,你应该在 ... -
站在巨人肩上的思考[连载] (6)
2007-05-04 09:31 1960第4章 类型和声明 4.3 字符类型 “由8 ... -
站在巨人肩上的思考[连载] (5)
2007-04-23 19:40 2386最近做个小项目,有点忙。事情倒是不难,就是有点杂, ... -
站在巨人肩上的思考[连载] (4)
2007-04-10 11:13 1831首先感谢 spinach 的鼓励与支持。你给了我很大的动力, ... -
站在巨人肩上的思考 [连载] (3)
2007-04-09 08:36 2188上一篇中,主要是对C++类设计的一个概览。如果 ... -
站在巨人肩上的思考 [连载] (2)
2007-04-07 11:23 2145<st1:chmetcnv tcsc=" ... -
站在巨人肩上的思考 [连载] (1)
2007-04-06 08:20 2165[原创。欢迎复制。转载请您注明出处 -- Gavin] Tip ...
相关推荐
八年级物理全册1.3站在巨人的肩膀上我国的四大发明素材新版沪科.doc
综上所述,卓越商企服务在商务物业管理领域具有一定的竞争优势,其业务模式、区域扩张策略、增值服务发展以及母公司支持都为其未来的发展提供了良好的基础。然而,投资者在做出投资决策时还需考虑市场风险和行业动态...
绿洲APP产品分析报告:站在巨人肩膀上能否看得更远?.pdf
站在巨人的肩膀上,_迁移学习_Transfer_Learning
站在巨人的肩上——XX借势营销策划.doc
站在巨人的肩上泛德林恩借势营销策划.docx
站在巨人的肩上--泛德林恩借势营销策划.doc
本教程资源"ios-站在巨人的肩膀上-scrollView联动.zip"可能包含了一个名为"XYSlideMenu"的示例项目,旨在帮助开发者理解并实现ScrollView的联动效果。 ScrollView联动的核心是通过监听ScrollView的滚动事件,将滚动...
小米集团作为一家以生产家用电器起家并迅速发展的科技公司,其商业模式和市场策略为家用电器行业带来了新的思考。小米集团的成功可以归结为几个关键因素:硬件产品作为核心,极致性价比的产品特点,以及基于物联网的...
本项目“站在巨人肩膀上制作的异步非阻塞IM”是一个基于Java语言实现的高效通信平台,它巧妙地利用了现有的开源技术和工具,以解决大规模并发下的高性能通信问题。以下将详细阐述这个项目中的关键知识点。 首先,...
站在巨人的肩膀上:分层设计在 Nervos 生态系统中的 layer 2区块链上的实际应用-SACC2021年中国系统架构师大会
本项目“站在巨人肩膀上制作了异步非阻塞的IM”充分利用了Java的优势,构建了一个高效、灵活的多协议通讯解决方案。 首先,异步非阻塞编程模型是现代高性能网络应用的核心。传统的同步阻塞模型在处理高并发时容易...
资源描述让你站在HTML巨人的肩膀上,制作非常酷炫的HTML前端web幻灯片。通过使用资源描述,你可以轻松地添加各种动画效果,使你的网页更加生动有趣。无论是淡入淡出、滑动、旋转还是缩放,你都可以通过资源描述实现...
【标题】中的“站在巨人的肩膀上的项目,感谢zhile大佬的Pandora-Next项目”表明这是一个基于他人开源项目进行开发或改进的项目。这里的“Pandora-Next”可能是一个由用户“zhile”创建的开源项目,它很可能在Python...
只有善于观察市场动态,深挖平台潜力,灵活应对变化,才能在互联网大潮中把握住机遇,站在巨人的肩膀上取得成功。在这个过程中,对开放平台的深刻理解和巧妙运用,将成为企业在互联网时代变革中立足的关键。
【知识点详解】 1. 指南针:指南针是我国古代...这些发明展示了中国古代科技的卓越成就,它们不仅在国内发挥了重要作用,而且对全球科技发展产生了深远的影响,是站在这些巨人肩膀上,人类社会得以不断进步的基础。
在C++编程中,错误处理是一项至关重要的任务,因为它们能帮助我们发现并修复程序中的问题,从而提高软件的质量和稳定性。...记住,每一次错误都是学习的机会,站在前人的经验上,我们可以走得更远。
14. 文件中还提到了宝胜国际的公司背景,包括其在中国消费行业中的位置,以及它在当前市场环境下如何站在“巨人的肩膀上”即利用与Nike和adidas等国际品牌的合作关系实现自身的增长。 通过上述知识点的整理,可以...