有些变量其实可能是常量,修改将产生一些不预期的结果。
字符串修改
- C语言字符串char *变量本质是指针, 如果是字面量初始化,存放位置可能位于只读区,修改内容将产生崩溃。
- char s[] = "hello"与char *s = "hello"截然不同,前者一定可修改,而后者不一定。反汇编这两段代码,能看到区别在于后者会直接取指针赋值,前者会有拷贝或初始化动作。
- 编译器如果把字符串字面量放在.rodata区,程序运行后对应内存页面就是只读的,写此区域将发生内存异常。
- C修改字符串字面量的行为是未定义的。
- 另外上面数组s是常量,不能再被赋值。
- C++标准明确指出字符串字面量是const类型。C++修改字符串字面量的行为一定会出错。
- 对于string str = "abcd"赋值的变量允许修改,str构造时有申请空间保存"abcd".
- Java string是常量,StringBuilder和StringBuffer是可修改的,StringBuffer是线程安全,访问起来可能更慢。
- C# string和Java一样是常量,StringBuilder是可修改的。
- Java和C#把string默认当常量,其实是为了优化,常量可以提前优化在某个地址,这和C/C++字符串char *字面量可能被优化是类似的。
- C++ string不像C#和Java那样,它默认可修改。