字符串文本中的字符递增
Incrementing character in string literal
#include<stdio.h>
int main(){
char *ptr="Helio";
ptr++;
printf("%sn",ptr);
//*ptr++;
printf("%cn",++*ptr);/*Segmentation fault on GCC*/
return 0;
}
问题 1(这在 Turbo C++ 中工作正常,但在 GCC 上它会产生分段错误。我不明白确切的原因。
可能是运算符优先级的原因之一。
问题 2(每个编译器是否具有不同的运算符优先级?
正如我在这里看到的,++ 的优先级高于取消引用运算符。可能是GCC和Turbo C++对待它们的方式不同。
不,运算符优先级由 C 标准定义,所有编译器都遵循相同的编译器。
在这种情况下,Turbo C++ 和 GCC 的结果差异的原因是您修改了字符串文本,这是未定义的行为。
将其更改为:
char arr[] = "Helio";
char *ptr = arr;
您现在可以修改字符串的内容。请注意,arr
本身就是数组名称,无法修改,因此我添加了一个新的指针变量ptr
并将其初始化为指向数组的第一个元素。
在最后printf()
行中,表达式 ++*ptr
等效于 ++ptr[0]
,而 又等效于 ptr[0] = ptr[0]+1
。自 ptr[0]=='H'
以来,您正在尝试将 ptr[0]
的值更改为 'I'
。
这是那里的关键问题。由于&ptr[0]
指向常数"Helio"
的第一个元素,试图改变第一个字符H
是有麻烦的,因为它是未定义的行为。
char* p = "some literal";
这之所以合法,只是因为C族人在标准的委员会谈判中争吵不休。您应该将其视为向后兼容的奇怪现象。
这是您通过 GCC 收到的消息:
警告:已弃用从字符串常量到"char*"的转换
下次请写以下内容:
char const* p = "some literal";
并让它成为你编码习惯的一种反射。那么你将无法编译你的错误行。
即:
++*ptr
在这里,您正在获取常量文字的第一个字符并尝试将其递增到H
之后的内容,因此I
。但是这个内存区域恰好在写保护页中,因为这是一个常量。这是标准所定义的,您应该将其视为非法。你的段错误来自这里。我建议您下次运行程序valgrind
以获取更详细的错误消息。
在余浩为你写的答案中,正在发生的事情是,所有字符都被编译器在初始化/声明站点编写的代码逐个复制到存储文本的常量字符串池,复制到堆栈分配的 char 数组,因此你可以取消引用它的内容。
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 如何在C++中确定文本文件中的元素是字符还是数字
- 如何从文本文件中读取数值,直到遇到字符类型?
- 如何在C++中反转文本文件中字符的顺序?
- 如何从代码本身向 wxwidgets 中的文本控件插入字符?
- 无法将整个文本文件复制到字符数组
- 在处理任何字符大小的模板中使用字符串文本
- 从我的 2DgridArray 中的文本文件中获取每个字符
- 从文本文件 (C++) 生成字符矩阵
- 如何在给定文本中用字符数组替换符号
- 如何在文本文件中间插入字符
- 将字符串文本分配给字符*:const_cast<字符 *> 与使用 char 数组
- 如何从文本文件中一次读取一个字符
- 字符* 文本消息[] 如何在内存中格式化?
- VS2013 字符文本不能作为 MSDN 的规范工作
- 为什么 C 中的字符文本大小与 C++ 中的字符文本大小不同
- 以本地化安全的方式比较C++中的字符串/字符和字符串/字符文本
- 在块中分配字符文本"if"
- C++编译时将字符串文本转换为多字符文本
- C++将字符串文本添加到字符文本