C++ 而内循环为循环
我在一本书中读到了这个示例代码。我不明白为什么以下示例代码的函数声明的这一部分是必要的:C++ 而内循环为循环,c++,for-loop,while-loop,C++,For Loop,While Loop,我在一本书中读到了这个示例代码。我不明白为什么以下示例代码的函数声明的这一部分是必要的: while (i <= n) p[i++] = '\0'; // set rest of string to '\0' while(i循环是不必要的。以Null结尾的字符串在第一个Null字节处结束。如果分配的内存超过实际字符串需要的内存,则这些额外字节中的内容无关紧要。所有未中断的C字符串处理代码都会在第一个Null结尾处停止。只需一个 p[i] = '\0'; 在for循环之后。但是,
while (i <= n)
p[i++] = '\0'; // set rest of string to '\0'
while(i循环是不必要的。以Null结尾的字符串在第一个Null字节处结束。如果分配的内存超过实际字符串需要的内存,则这些额外字节中的内容无关紧要。所有未中断的C字符串处理代码都会在第一个Null结尾处停止。只需一个
p[i] = '\0';
在for
循环之后。但是,一个空字节是必需的。C字符串函数依赖于它,如果缺少它,它会很高兴地溢出分配的内存。基本上,它们会(尝试)继续,直到他们在内存中偶然发现下一个空字节。如果超过分配的内存,则会导致未定义的行为,如果幸运的话会导致崩溃;如果幸运的话,则会导致数据损坏
< > >强> >将该书扔掉。<强>代码是从第一行到最后一行的灾难。它几乎不符合C++的要求。大部分是纯C,甚至作为C代码,这也是非常可疑的。
- @vol7ron在评论中指出,主要的抱怨是反对在头文件中使用命名空间std
。这里它被用在.cpp文件的函数中,这大大减少了影响。虽然在我看来这仍然值得避免。如果你不深入了解标准库的实现,你就不知道了“我真的不知道您将哪些符号引入范围。如果为了可读性需要,请引入特定符号(例如,使用std::cout;
)是一个更好的选择。此外,我相信我不是唯一一个期待std::
前缀的人。例如,std::string
就是我期待看到的。string
看起来有点不对劲。人们总是怀疑它可能不是std库字符串,而是自定义字符串类型。因此,包含前缀可以也有利于可读性
std::strcpy()
的用途new
和delete
无处不在:容易出错,因为您必须手动跟踪new/delete对以避免内存泄漏left()
分配并返回一个指针;调用者有责任删除它。没有比这更容易出错的了#include <iostream>
#include <string>
std::string left(const std::string& str, std::size_t len = 1);
int main()
{
// getline can fail. If that happens we get an empty string.
std::string sample;
std::getline(std::cin, sample);
auto ps = left(sample, 4);
std::cout << ps << '\n';
ps = left(sample);
std::cout << ps << '\n';
return 0;
}
// `len` may be longer than the string. In that case a copy
// of the complete input string is returned.
std::string left(const std::string& str, std::size_t len)
{
return str.substr(0, len);
}
#包括
#包括
std::string left(常量std::string&str,std::size\u t len=1);
int main()
{
//getline可能会失败。如果发生这种情况,我们将得到一个空字符串。
std::字符串样本;
std::getline(std::cin,样本);
自动ps=左侧(样本,4);
不需要循环,但是p[i++]如果要将p
视为以null结尾的字节字符串,则需要使用='\0'
。此外,请学习如何缩进代码。它很可能是在书中缩进的,虽然编译器不需要缩进,但它确实有助于人们阅读代码。而且while循环没有嵌套在for循环中-没有打开的大括号i紧跟在for语句的结尾之后),因此它只循环p[i]=str[i];
这种混乱/不清晰是某些编码标准要求所有for/while/if/else语句在语句后面加上{}的原因即使只涉及一条语句,它们也会进行控制。阅读起来要简单得多。你可以用p[i]='\0';
替换它,一个终止null应该是充分的。while循环是荒谬的。在for
循环之后需要做的就是p[i]=0;
以正确终止字符串。如果输入字符串str
的长度小于n
,则为p
分配的内存量也会过多。这是哪本书?无意冒犯,但他在main中设置了名称空间,这对于本示例来说似乎已经足够好了。虽然我喜欢提到的是cautious,特别是如果这是一本旧书,我不认为在函数中设置名称空间是一个糟糕的决定。是的,冲突的风险是现实,但代码的可读性也很重要。这本书是“C++初级读物Plus”斯蒂芬·普拉塔的第六版。@vol7ron Hm,也许抱怨使用名称空间std
变得有点太自动化了。我仍然认为这是值得避免的。但这是一个小问题,我应该更新答案。
#include <iostream>
#include <string>
std::string left(const std::string& str, std::size_t len = 1);
int main()
{
// getline can fail. If that happens we get an empty string.
std::string sample;
std::getline(std::cin, sample);
auto ps = left(sample, 4);
std::cout << ps << '\n';
ps = left(sample);
std::cout << ps << '\n';
return 0;
}
// `len` may be longer than the string. In that case a copy
// of the complete input string is returned.
std::string left(const std::string& str, std::size_t len)
{
return str.substr(0, len);
}