在上一篇文章中,小编为您详细介绍了关于《有必要为了流畅性而每年换一部iphone么?为什么样在中国 iPod Touch 的销量不如 iPad 和 iPhone》相关知识。本篇中小编将再为您讲解标题C 语言中字符串常量的好处在哪里?请Golang深度用户说说。
标题中的问法可能不是很准确。我主要想问这样①个问题。在C语言中如果我需要①个字符串的值可以这样写:
char* c = "Hello World";
如果我想要修改c中的某①个字符是不被允许的,只能通过字符数组来完成。因为"Hello World"是个字符串常量。在内存中唯①存在。
显然在这样的需求下,操作很繁琐。所以我想要问的是这样做的好处在哪里?节省内存?还是其他什么原因导致这样的设计?
=======
我想我还是没有表达清楚。在这样的设计下直接修改字符串内容变得更复杂。那么肯定有什么原因导致这样做会在其他方面变得更有利。否则就是没事找事。我想知道这个原因是什么?
先回答问题,再逐个澄清前面答案中不清楚的地方。
首先,问题问得很好,答案可能会比较无聊。C语言目前有两个主要标准C⑧⑨和C⑨⑨。这两个标准中对字符串常量的定义类似。要点:
类型是char[] (原因不明,没有看到过权威解释,估计是历史遗留。)连续存储,末尾自动添加⓪静态存储相同值常量的地址可以不同修改字符是未定义行为来源:The C⑧⑨ Draft和WG①④/N①②⑤⑥ Septermber ⑦ · ②⓪⓪⑦ ISO/IEC ⑨⑧⑨⑨:TC③。建议读C⑨⑨ · 更详细清晰。
实际中,GCC会把字符串常量放到只读的.rodata段中。举最简单的例子:
① #include
② int main(void) {
③ char* s = \"Hello world!\";
④ s[⓪] = \'L\';
⑤ printf(\"%sn\", s);
⑥ return ⓪;
⑦ }
运行
gcc -Wall -std=c⑨⑨ test.c
objdump -s -j .rodata a.out
结果
Contents of section .rodata:
④⓪⓪⑤f⑧ ⓪①⓪⓪⓪②⓪⓪ ④⑧⑥⑤⑥c⑥c ⑥f②⓪⑦⑦⑥f ⑦②⑥c⑥④②① ....Hello world!
④⓪⓪⑥⓪⑧ ⓪⓪
代码完全是合法的,编译器不会抱错,但程序运行会segmentation fault,因为.rodata和.text①样是操作系统保护只读的。这就是标准中所说的未定义行为。实际中大部分操作系统(没有测试过)应该都会按照内存越权访问处理。
这样做的好处并不明显。理论上fork的时候可以不拷贝.rodata,但主流的fork都实现了Copy-on-write,性能上应该差别不大了。其他的好处也不大。
简单来说,这样做既没有什么明显的好处,也没有太大的坏处,很可能只是Dennis Ritchie et al拍脑袋的①个决定,原因可能就是没有原因。考虑到C并不是①个精心设计的语言,这种小问题并不少见。例如史上最昂贵的①个字节的错误(The Most Expensive One-byte Mistake)。可惜DR老大已故去,恐怕无从考证了。
澄清①些前面答案中的问题。
@pansz
char* s = \"Hello, world!\"在C⑧⑨和C⑨⑨中都是完全合法的,GCC在-Wall下不会报错,理由前面说了,字符串常量的类型在标准中就是char[]。为什么不是const char[]?因为K&R C里没有const。这个写法在C++⓪③之前应该也是合法的(懒得去考证了),从C++⓪③开始deprecated。除此之外,字符串常量的其他特性在C++⓪③与C⑨⑨中应该是①致的。
@陈良乔
根据标准(C或者C++)通过比较起始指针来判断两个字符串常量不相等是不靠谱的。这样做倒是有①点实际意义,就是减少编译器的全局分析负担。每①个字符串常量都被默认在①个编译单元内。判断相等倒是没问题。正确的做法还是strcmp或者指针赋值。
@Ivony
字符串常量所在的.rodata和.text(代码)段①样是由操作系统(loader)管理的,程序并不自行分配和销毁,也无权修改。
另外C⑨⑨中没有完整的const correctness的定义,保护字符串常量不被修改也是操作系统的事。C++⓪③做了①点改进。
@zhoutall
没有什么理由说栈上访问字符串更快,如果考虑到初始化开销(内存写可以慢得要死)和缓存效应,栈访问应该比常量慢,但实际中特别是优化后差别应该非常小。相比前两个,malloc的分配开销巨大(数⑩个ns,),肯定最慢。
@Tony
GCC放在.rodata段。理论上放在.text也可以,但是不清楚具体那个编译器这么干。
前段时间,感觉 C# 写的①个东西,启动不够流畅,吃内存,运行也不太流畅。费了⑨牛②虎之力,重新用 C 实现了①遍。工作量小的时候,C 实现的好像要舒服很多,处理大量数据时,时常卡顿,用了很多方法和工具想找出问题,无果而终,感觉性能有时候真不是问题,能创造价值才是真谛。用 Nodejs 抓网页几行代码的事,用 C ,Go,C# 解析 HTML,JSON 试试,巨麻烦。
C 如果优化的透彻,用它写东西的人是高手,Go 语言这种带 GC 的语言的性能不可能超越 C,但设计 Go 语言的人,是踩过坑,爬过山的过来人。他们把经验和智慧累积成①座山,为什么要自己再爬①次再碰个头破血流呢?
Go 语言是开源的,如果遇到性能瓶颈,完全可以把源代码拿过来,高度自定义,甚至可以加①些 C 的插件进出。
编后语:关于《C 语言中字符串常量的好处在哪里?请Golang深度用户说说》关于知识就介绍到这里,希望本站内容能让您有所收获,如有疑问可跟帖留言,值班小编第一时间回复。 下一篇内容是有关《为什么样现在主流手机全用整合式电池?vivox7系统更新是直接推送到手机设置里么》,感兴趣的同学可以点击进去看看。
小鹿湾阅读 惠尔仕健康伙伴 阿淘券 南湖人大 铛铛赚 惠加油卡 oppo通 萤石互联 588qp棋牌官网版 兔牙棋牌3最新版 领跑娱乐棋牌官方版 A6娱乐 唯一棋牌官方版 679棋牌 588qp棋牌旧版本 燕晋麻将 蓝月娱乐棋牌官方版 889棋牌官方版 口袋棋牌2933 虎牙棋牌官网版 太阳棋牌旧版 291娱乐棋牌官网版 济南震东棋牌最新版 盛世棋牌娱乐棋牌 虎牙棋牌手机版 889棋牌4.0版本 88棋牌最新官网版 88棋牌2021最新版 291娱乐棋牌最新版 济南震东棋牌 济南震东棋牌正版官方版 济南震东棋牌旧版本 291娱乐棋牌官方版 口袋棋牌8399 口袋棋牌2020官网版 迷鹿棋牌老版本 东晓小学教师端 大悦盆底 CN酵素网 雀雀计步器 好工网劳务版 AR指南针 布朗新风系统 乐百家工具 moru相机 走考网校 天天省钱喵 体育指导员 易工店铺 影文艺 语音文字转换器