作者cppOrz (cppOrz)
看板C_and_CPP
标题Re: [问题] char *str="test"是const字串的问题
时间Fri Nov 18 02:31:27 2005
※ 引述《firose (guest)》之铭言:
: ※ 引述《Aligu1009 (=.=)》之铭言:
: : 谢谢你的回覆 :)
: : 可是我还是不懂
: : C干麽要这样子做呢?
: : 直接用个关键字const来限制
: : 阅读上会更清楚啊?
: char *str="test"; //指标
: char str[] = "test"; //阵列
: 首先 "test" 是 const char[] 的一个常数值, 会被放到唯读区域
这可能请对标准比较熟的人解释一下,常数或字串常数,在 C/C++ 中
的实作是编译器自行决定的。一般为了效率考量,通常是放在 const
data 区段;某些编译器可能将它放在 overlapping objects 里,做
为一种选择性的优化机制。企图修改它们,会导致未定义的後果;所
以虽然允许你拿个 char * 指着,但改了就爆。
会 ASM 的人当然可以研究一下自己手上的 C/C++ 编译器究竟是怎麽
处理某些细节的。不过很多问题,真的是「先弄清楚定义」,自己有
个底,可以节省很多盲目摸索的时间。
: 至於 C 为什麽让 char *str 可以指向 "test", 可能有某种原因, 但就是不能改值
: 不过第二行就不一样, 会在 stack 分配空间给 str 阵列并把 "test" 的值拷贝过去
: 所以你改的话是改 str 这个阵列的记忆体, 不是 "test" 的记忆体位置
为什麽 C 让 char * 可以指向字串常数?这是由於 C 着重效率多过
严谨。找一本比较新的 C/C++ 课本,通常会告诉你,正确的写法是:
char const *s = "test";
如果希望能改动,就自己指定一块记忆体(避免编译器的优化实现,
把它放到 const data 区域),例如:
char s[] = "test"; // 放在 stack 区域(这其实是下面的简写)
或
char s[] = { 't', 'e', 's', 't', '\0' }; // 原本的写法
或
static char s[] = "test"; // 放在 global/static 区域
至於可以通融 non-const char * 版本的写法,那是因为已经有成万
上亿行的旧程式码这样做了,标准不得不向现实妥协;但当然三令五
申告诉大家旧的写法是不好的(depreciated),请不要再用。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.120.214.120
1F:推 renderer:推 11/18 08:43
2F:推 Aligu1009:嗯 好像有比较清楚了 不过放的位置会对效率有这麽大的 11/18 13:08
3F:→ Aligu1009:影响 大到甚至需要创造这种令人混淆的语法吗? 11/18 13:09