使用花括号分隔我想在 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.\n\n";
cont = true;
}
}
}
return 0;
}
如您所见,我使用一组 {}
将代码分开,在这些大括号内为 cont
变量提供局部范围。我这样做是为了如果我想再次使用那个变量名,我可以重新声明它,当我用完它时,它就被销毁了。
这是可以接受的做法吗?或者有更好的方法来完成我所做的事情吗?我承认在这个特定的、基本的场景中,条件很简单,几乎没有必要,但我可能想在未来对更复杂的循环这样做。
一般情况下?是的。这个不错。
在这个具体案例中?不,没必要。您不会 再次使用该名称,并且在这个简单的代码中您不会这样做。所以这只是噪音。
看……这是平衡。
我发现自己在执行多个相关 SQL 语句的函数中经常这样做。每次我可能会用一个名为 ss
的 std::stringstream
来构建它。当然,我可以给每一个都起一个不同的名字,但它完全可以防止错误,将每个语句生成器保留在自己的范围内。
当你使用锁守卫之类的东西时,这也是一种非常常用的技术。
这是一种可以接受的做法,并且完全按照您说的去做。然而,它很少被使用,因为在小函数中,在函数顶级范围内使用 cont
变量是明确的,因此是可以接受的。如果您觉得需要在更大的函数中分离范围,通常首选创建另一个具有明确名称的函数。
您可以将这些大括号视为只调用一次的无名函数。如果您发现自己经常使用它,也许您应该给它起一个自己的名字。
另一种选择是重写循环以不需要 cont
变量,例如:
string teststring;
do
{
cout << "Enter a string less than 10 characters long: ";
getline(cin, teststring);
} while (teststring.length() >= 10);
cout << "Thank you.\n\n";
但这并不总是可行的,尤其是当您需要根据停止条件输出不同的消息时。
这显然是一个玩具箱,但这是一个很好的做法,'stand-alone' 积木就是为了这个目的。
我碰巧相信它们是构建长函数的更好方法,而不是将其分解为(在许多情况下)没有单独目的的成员。
在这种情况下,您可以提供更快、更清晰、更安全的程序,特别是如果有注释(可能是一行)介绍每个块。
但是在这种情况下,您可以考虑:
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.\n\n";
break; //<--- Escapes the loop.
}
}
脚注(回应评论):
您应该将 for
循环视为 while
循环上的 'syntactic sugar'。这在他们的表现等方面没有什么不同,只需选择阅读最好的那个。 for(;cond;)
看起来很有趣。
break
可能会有微小的(微小的)性能优势,但我碰巧认为它在许多情况下实际上更简单且更具可读性。
如果代码更复杂,可能会有更多 'loop end' 代码,因此它变成:
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
只会让 'swift exit' 更容易理解。
他们没有(广泛地)被认为拥有 goto
的 'bad karma',因为他们 'go to' 是一个非常明确定义的执行点。
是的,没关系,如果您有充分的理由重新使用变量。锁守卫是我自己代码中最常见的用法,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
}
在下面的代码中,我有一个 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.\n\n";
cont = true;
}
}
}
return 0;
}
如您所见,我使用一组 {}
将代码分开,在这些大括号内为 cont
变量提供局部范围。我这样做是为了如果我想再次使用那个变量名,我可以重新声明它,当我用完它时,它就被销毁了。
这是可以接受的做法吗?或者有更好的方法来完成我所做的事情吗?我承认在这个特定的、基本的场景中,条件很简单,几乎没有必要,但我可能想在未来对更复杂的循环这样做。
一般情况下?是的。这个不错。
在这个具体案例中?不,没必要。您不会 再次使用该名称,并且在这个简单的代码中您不会这样做。所以这只是噪音。
看……这是平衡。
我发现自己在执行多个相关 SQL 语句的函数中经常这样做。每次我可能会用一个名为 ss
的 std::stringstream
来构建它。当然,我可以给每一个都起一个不同的名字,但它完全可以防止错误,将每个语句生成器保留在自己的范围内。
当你使用锁守卫之类的东西时,这也是一种非常常用的技术。
这是一种可以接受的做法,并且完全按照您说的去做。然而,它很少被使用,因为在小函数中,在函数顶级范围内使用 cont
变量是明确的,因此是可以接受的。如果您觉得需要在更大的函数中分离范围,通常首选创建另一个具有明确名称的函数。
您可以将这些大括号视为只调用一次的无名函数。如果您发现自己经常使用它,也许您应该给它起一个自己的名字。
另一种选择是重写循环以不需要 cont
变量,例如:
string teststring;
do
{
cout << "Enter a string less than 10 characters long: ";
getline(cin, teststring);
} while (teststring.length() >= 10);
cout << "Thank you.\n\n";
但这并不总是可行的,尤其是当您需要根据停止条件输出不同的消息时。
这显然是一个玩具箱,但这是一个很好的做法,'stand-alone' 积木就是为了这个目的。 我碰巧相信它们是构建长函数的更好方法,而不是将其分解为(在许多情况下)没有单独目的的成员。
在这种情况下,您可以提供更快、更清晰、更安全的程序,特别是如果有注释(可能是一行)介绍每个块。
但是在这种情况下,您可以考虑:
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.\n\n";
break; //<--- Escapes the loop.
}
}
脚注(回应评论):
您应该将 for
循环视为 while
循环上的 'syntactic sugar'。这在他们的表现等方面没有什么不同,只需选择阅读最好的那个。 for(;cond;)
看起来很有趣。
break
可能会有微小的(微小的)性能优势,但我碰巧认为它在许多情况下实际上更简单且更具可读性。
如果代码更复杂,可能会有更多 'loop end' 代码,因此它变成:
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
只会让 'swift exit' 更容易理解。
他们没有(广泛地)被认为拥有 goto
的 'bad karma',因为他们 'go to' 是一个非常明确定义的执行点。
是的,没关系,如果您有充分的理由重新使用变量。锁守卫是我自己代码中最常见的用法,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
}