我正在解决老师给我的一个问题并且遇到了一些问题。 我应该给出以下代码的输出:(用Turbo C ++编写)
#include<iostream.h>
void main()
{
char *p = "School";
char c;
c=++(*(p++));
cout<<c<<","<<p<<endl;
cout<<p<<","<<++(*(p--))<<","<<++(*(p++))<<endl;
}
程序提供的输出是:
T,chool
ijool,j,i
我得到指针本身递增的部分,然后递增指针指向的值。但我没有得到字符串打印出来的部分 ijool
有人能帮助我吗?
答案 0 :(得分:5)
您展示的程序是非标准且格式错误(并且不应该编译)。
“小”问题:
<iostream>
,而不是<iostream.h>
main()
返回int
,而不是void
。cout
或更好,则无法使用endl
和using namespace std;
:使用std::cout
和std::endl
。“核心”问题:
char* p = "School";
是指向字符串litteral的指针。此转换在C ++ 03中有效,在C ++ 11中已弃用。除此之外,通常字符串litterals是只读的,并且尝试修改它们通常会导致段错误(并且修改字符串litteral是标准的未定义的行为)。因此,每次使用p
时都会有未定义的行为,因为您修改了它指向的内容,即字符串文字。p
行中多次修改std::cout<<p<<","<<++(*(p--))<<","<<++(*(p++))<<std::endl;
。这是未定义的行为。未定义用于p
上的操作的顺序,此处似乎编译器从右侧开始。您可以查看sequence points, sequence before/after以获得更好的解释。您可能对live code here感兴趣,这更像您对计划的期望。
答案 1 :(得分:4)
我们假设你是正确的:
<iostream>
- 没有iostream.h
标题cout
和endl
分别与std::cout
和std::endl
的使用main
到int
好,
char *p = "School";
字符串文字"School"
的类型为“7 const
char
的数组。”在C ++ 03中不推荐转换为char*
。在C ++ 11中,这是无效的。
c=++(*(p++));
这里我们点击未定义的行为。正如我之前所说,字符串文字中的char
是const
。你根本无法修改它们。这里的前缀++
将尝试修改字符串文字中的S
字符。
所以从这一点开始,对于应该发生什么进行猜测是没有用的。你有未定义的行为。任何事情都可能发生。
答案 2 :(得分:3)
即使前面的行是合法的,这一行也是未定义的行为,这意味着你无法准确预测输出的内容:
cout<<p<<","<<++(*(p--))<<","<<++(*(p++))<<endl;
注意它是如何在该行上多次修改p
的值(实际上是在序列点之间)?这是不允许的。充其量你可以说“在这个运行时库的这个编译器和这个环境的执行时我观察到了以下行为”,但因为它是未定义的行为你不能指望它每次都做同样的事情您运行该程序,或者即使在同一程序运行中多次遇到相同的代码。
答案 3 :(得分:1)
此代码至少存在三个问题(可能更多;我不是C ++专家)。
第一个问题是不应该修改字符串常量,因为它们可以放在程序存储器的只读部分中,OS直接映射到磁盘上的exe文件(操作系统可以在几个运行的实例之间共享它们)例如,相同的程序,或者当RAM很低时,避免需要将这些内存部分写入交换文件,因为它知道它可以从exe获取原始文件。例如,该示例在我的编译器上崩溃。要修改字符串,您应该为字符串分配一个可修改的副本,例如使用strdup。
第二个问题是它在cout
命名空间中使用endl
和std
而没有声明。您应该在访问前加std::
或添加using namespace std;
声明。
第三个问题是第二个cout
行上的操作发生的顺序是未定义的行为,导致字符串在第一行结束时显示的时间之间明显神秘的变化{ {1}}行和下一行。
由于此代码不打算特别做任何事情,因此您可以使用不同的有效方法进行修复。这可能会运行:
cout
(在我的编译器上输出:#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
int main()
{
char *string = strdup("School");
char *p = string;
char c;
c=++(*(p++));
cout<<c<<","<<p<<endl;
cout<<p<<","<<++(*(p--))<<","<<++(*(p++))<<endl;
free(string);
}
,T,chool
。)
但它仍有未定义的行为。要解决此问题,请按如下方式重新修改第二个diool,i,d
行:
cout
这应该给cout << p << ",";
cout << ++(*(p--)) << ",";
cout << ++(*(p++)) << endl;
,T,chool
(假设一个字符集按顺序包含A到Z)。
答案 4 :(得分:0)