在c++中使用花括号来隔离我想多次使用的变量
Using curly braces to segregate a variable that I want to use multiple times in C++
在下面的代码中,我有一个while语句用于确保输入字符串小于10个字符。我已经声明了一个叫做cont
的bool
,我用它来告诉while循环在我的条件满足后停止。
#include "stdafx.h"
#include <iostream>
#include <string>
int main()
{
using namespace std;
cout << "Enter a string less than 10 characters long: ";
string teststring;
{
bool cont(false);
//if input is 10 or more characters, ask for input again until it is less
while (!cont)
{
getline(cin, teststring);
if (teststring.length() >= 10)
{
cout << "Too long, try again: ";
}
else
{
cout << "Thank you.nn";
cont = true;
}
}
}
return 0;
}
正如您在那里看到的,我使用了一组{}
s来分离代码,在这些大括号内给cont
变量一个局部作用域。我这样做是为了,如果我想再次使用那个变量名,我可以重新声明它,当我用完它的时候,它就被销毁了。
这是可以接受的做法吗?或者有更好的方法来完成我所做的?我承认,在这个特定的基本场景中,条件非常简单,几乎没有必要,但我可能希望将来在更复杂的循环中这样做。
总的来说?是的。这很好。
在这种特殊情况下?不。不必要的。您没有再次使用这个名称,并且在这个简单的代码中您不会这样做。所以这只是噪音。
See…这是一个平衡。
我发现自己在执行几个相关SQL语句的函数中经常这样做。每次我可能会用std::stringstream
和ss
来构建它。当然,我可以给每个语句构建器起一个不同的名字,但是将每个语句构建器保持在自己的作用域内完全可以防止错误。
这是一种可接受的做法,并且完全符合您的要求。然而,很少使用它,因为在小函数中,cont
变量在函数顶层作用域中是明确的,因此是可以接受的。如果你觉得你需要在一个较大的函数中分离作用域,那么用一个显式的名字创建另一个函数通常是最好的。
你可以把这些大括号看作只被调用一次的无名函数。如果你发现自己经常使用它,也许你应该给它起一个自己的名字。
另一个选项是重写循环,使其不需要cont
变量,例如:
string teststring;
do
{
cout << "Enter a string less than 10 characters long: ";
getline(cin, teststring);
} while (teststring.length() >= 10);
cout << "Thank you.nn";
但这并不总是可能的,特别是如果您需要根据停止条件输出不同的消息
是的,如果您有充分的理由重用一个变量,这很好。锁保护在我自己的代码中是最常见的用法,在Lightness的std::stringstream ss
回答中给出了这个例子。基本上,只要选择不同的变量名感觉比较尴尬,就可以这样做。例如,如果你写lock1
, lock2
, lock3
,…
然而,更可接受的做法是将长函数体视为代码气味,并将其重构为自己的函数。例如
...
string teststring;
{
bool cont(false);
//10 lines of code to handle the foo scenario
}
{
bool cont(false);
//15 lines of code to handle the bar scenario
}
...
这可以通过重构来更好地处理:
...
string teststring;
foo(teststring);
bar(teststring);
...
void foo(string &teststring){
bool cont(false);
//10 lines of code
}
void bar(string &teststring){
bool cont(false);
//15 lines of code
}
这显然是一个玩具案例,但这是一个很好的实践,"独立"块就是为了这个目的而存在的。我相信它们是构建长函数的更好方法,而不是将其分解成(在许多情况下)没有单独用途的成员。
在这种情况下,你可以提供一个更快,更清晰,更安全的程序,特别是如果有一个注释(可能是一行)介绍每个块。
但是在这种情况下你可以考虑:
for ( bool cont(false);!cont;)
具有相同的效果。在for(.;.;.)
语句中声明的变量被限制在该语句的范围内。
在这种情况下,你可以用:
回避整个变量: for(;;) //<--- Canonical formulation for 'infinite' loop.
{
getline(cin, teststring);
if (teststring.length() >= 10)
{
cout << "Too long, try again: ";
}
else
{
cout << "Thank you.nn";
break; //<--- Escapes the loop.
}
}
脚注(回应评论):
您应该将for
循环视为while
循环上的"语法糖"。他们的表现没有什么不同,等等,只要挑一个读起来最好的。for(;cond;)
看起来很有趣。
break
可能有一个很小(很小)的性能优势,但我碰巧认为它在许多情况下实际上更简单,更可读。
如果代码更复杂,可能会有更多的"循环结束"代码,所以它变成:
for(bool cont(false);!cont;) {
//Complex code with multiple 'exit' conditions...
if(!cont) {
//Go round again code that won't fit nicely in last term of for loop...
}
}
而使用break
只是使"快速退出"更容易理解。他们没有(广泛)被认为有goto
的"坏业力",因为他们"去"一个非常明确的执行点。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- C++多线程程序:变量定义为类成员的隔离错误
- 在c++中使用花括号来隔离我想多次使用的变量