在 C++ 的条件或控制语句中声明和初始化变量

2024-01-25

在斯特鲁斯特鲁普的C++ 编程语言:特别版(第 3 版)Stroustrup 写道,在控制语句的条件中声明和初始化变量不仅是允许的,而且是鼓励的。他写道,他鼓励这样做,因为它将变量的范围缩小到仅需要它们的范围。所以像这样的事情...

if ((int i = read(socket)) < 0) {
    // handle error
}
else if (i > 0) {
    // handle input
}
else {
    return true;
}

...是良好的编程风格和实践。变量i只存在于块if需要它但随后超出范围的语句。

然而,g++(版本4.3.3 Ubuntu特定编译)似乎不支持编程语言的这个功能,这让我感到惊讶。也许我只是用一个标志来调用 g++ 将其关闭(我调用的标志是-g and -Wall)。当使用这些标志进行编译时,我的 g++ 版本返回以下编译错误:

socket.cpp:130: error: expected primary-expression before ‘int’
socket.cpp:130: error: expected `)' before ‘int’

经过进一步的研究,我发现我似乎不是唯一一个编译器不支持这一点的人。似乎有一些混乱这个问题 https://stackoverflow.com/questions/136548/pro-con-initializing-a-variable-in-a-conditional-statement-c至于到底什么语法被认为是该语言的标准以及编译器用它进行编译。

所以问题是,哪些编译器支持此功能以及需要设置哪些标志才能编译?是否存在符合某些标准而不符合其他标准的问题?

另外,出于好奇,人们是否普遍同意 Stroustrup 的观点,即这是一种很好的风格?或者这是一种语言的创建者头脑中产生的想法不一定得到该语言社区支持的情况?


允许在嵌套块的控制部分声明变量,但在以下情况下if and while,变量必须初始化为将被解释为条件的数字或布尔值。它cannot包含在更复杂的表达式中!

在您展示的特定情况下,不幸的是您似乎无法找到遵守的方法。

我个人认为,保持局部变量尽可能接近其在代码中的实际生命周期是一个很好的做法,即使当您从 C 切换到 C++ 或从 Pascal 切换到 C++ 时这听起来令人震惊 - 我们习惯于在以下位置查看所有变量一个地方。有了一些习惯,您会发现它更具可读性,并且您不必在其他地方寻找声明。而且,您知道在那之前它没有被使用过。


Edit:

话虽这么说,我认为在一个声明中混合太多内容并不是一个好的做法,而且我认为这是一个共同的观点。如果您影响变量的值,然后在另一个表达式中使用它,则通过将两个部分分开,代码将更具可读性并且更少混乱。

所以不要使用这个:

int i;
if((i = read(socket)) < 0) {
    // handle error
}
else if(i > 0) {
    // handle input
}
else {
    return true;
}

我更喜欢这样:

int i = read(socket);
if(i < 0) {
    // handle error
}
else if(i > 0) {
    // handle input
}
else {
    return true;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C++ 的条件或控制语句中声明和初始化变量 的相关文章

  • 尚未注册类型“IServiceProviderFactory[Autofac.ContainerBuilder]”的服务

    当运行以下命令添加数据库迁移脚本时 出现以下错误 dotnet ef migrations add InitialCreate v o Migrations context MyContext 访问 Microsoft Extensions
  • 通过 SocketCAN 进行 boost::asio

    我正在考虑利用升压阿西奥 http www boost org doc libs 1 49 0 doc html boost asio html从a读取数据套接字CAN http en wikipedia org wiki SocketCA
  • 如何在 C# / .NET 中创建内存泄漏[重复]

    这个问题在这里已经有答案了 可能的重复 托管代码中是否可能存在内存泄漏 特别是 C 3 0 https stackoverflow com questions 6436620 is it possible to have a memory
  • 平滑滚动.net 表单

    您好 我正在 net 中使用表单 并且在运行时动态添加大量链接标签 我将这些链接标签添加到面板并将该面板添加到 winform 当链接标签的数量增加时 表单会显示一个自动滚动条 垂直 现在 当我使用自动滚动向下滚动时 表单在滚动时不会更新其
  • ASP.NET Web API 客户端 ProgressMessageHandler Post 任务卡在 WinForm 应用程序中

    我在用着HttpClient and ProgressMessageHandler来自MS ASP NET Web API 客户端库 http nuget org packages Microsoft AspNet WebApi Clien
  • 防止 boost::asio::io_context 在空轮询调用时停止

    此代码调用发布的句柄 boost asio io context ioc boost asio post ioc std cout lt lt lol lt lt std endl ioc poll 而这并没有 boost asio io
  • GCC 和 ld 找不到导出的符号...但它们在那里

    我有一个 C 库和一个 C 应用程序 尝试使用从该库导出的函数和类 该库构建良好 应用程序可以编译 但无法链接 我得到的错误遵循以下形式 app source file cpp text 0x2fdb 对 lib namespace Get
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • 单例模式和 std::unique_ptr

    std unique ptr唯一地控制它指向的对象 因此不使用引用计数 单例确保利用引用计数只能创建一个对象 那么会std unique ptr与单例执行相同 单例确保只有一个实例属于一种类型 A unique ptr确保只有一个智能指针到
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 每个租户的唯一用户名和电子邮件

    我正在使用以下代码编写多租户应用程序ASP NET Core 2 1 我想覆盖默认的与用户创建相关的验证机制 目前我无法创建多个具有相同的用户UserName My ApplicationUser模型有一个名为TenantID 我想要实现的
  • 是否有相当于 Clang/LLVM 的 .spec 文件,在哪里可以找到参考?

    The gcc驱动程序可以配置为使用特定的链接器 特定的选项和其他细节 例如覆盖系统头 specs files 当前 截至撰写本文时 GCC 版本 4 9 0 的手册此处描述了规范文件 https gcc gnu org onlinedoc
  • ASP.NET MailMessage.BodyEncoding 和 MailMessage.SubjectEncoding 默认值

    很简单的问题 但我在 MSDN 上找不到答案 查找 ASP NET 将用于的默认值 MailMessage BodyEncoding and MailMessage SubjectEncoding 如果你不在代码中设置它们 Thanks F
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • xsi:type 属性搞乱了 C# XML 反序列化

    我使用 XSD exe 根据 XML 架构 xsd 文件 自动生成 C 对象 我正在反序列化 OpenCover 输出 但其中一个部分类未正确生成 这是导致异常的行

随机推荐

  • Matlab 中的相关可观测属性。有效吗?

    在 Matlab 类中 声明在语法上似乎是正确的property那是依赖者 计算未存储 和可观察的在同一时间 考虑代码 properties Access private instanceOfAnotherClass end propert
  • Android 上有时会忽略 LD_LIBRARY_PATH

    我有一个 Android 应用程序 它会生成许多与我随包分发的库动态链接的本机可执行文件 为了启动这些二进制文件 我使用 LD LIBRARY PATH 环境变量让它们知道从中加载库的位置 但在某些设备上这根本不起作用 LD LIBRARY
  • 如何将无头铬模块与AWS Lambda捆绑在一起?

    我尝试将 Puppeteer 与 Lambda 结合使用 但是 在无服务器部署中 由于超过 250mb 未捆绑包大小限制 Lambda 会出错 因此 为了突破限制 我改用了 Puppeteer 核心 它不包含铬 这需要引用可执行文件的路径来
  • 是否有库或其他方法可以进行 128 位数学运算?

    我正在编写一个加密应用程序 需要使用 128 位整数 除了标准的加 减 乘 除和比较之外 我还需要幂和模函数 有谁知道可以做到这一点的库或其他实现 如果不是 128 位 是否有 64 位选项可用 查看GNU 多精度算术库 http gmpl
  • 如何在react中为状态分配prop值

    我有一个覆盖层 它是从另一个 React 组件启动的 该组件有一个也会自行更改的按钮 当用户单击按钮时 更改就会发生 然后按钮会更改其类名 它还向作为覆盖层的子组件发送一个 prop 值 叠加层会根据属性以及是否单击添加一个类 一切都进展顺
  • 哪个 openid / oauth 库可将 django 项目连接到 Google Apps 帐户?

    我正在为一家使用 Google Apps 登录的公司开发一个 Intranet django 项目 不使用 GAE 所以我希望我的用户能够使用他们的 google 帐户登录来登录我的 django 项目 OpenID 似乎很合适 尽管也许
  • 在ggplot2中自定义“scale_color_gradient2”

    我想在我的图像图中使用我自己的特定颜色 我对 ggplot2 很陌生 所以看了它的手册here http docs ggplot2 org current scale gradient2 html 旧链接不存在 现在是here https
  • TFS 2005下永久删除

    如何永久删除 TFS 2005 源代码管理下的文件夹 文件 我知道关于tf destroy命令 但这仅适用于 TFS 2008 我也知道关于CodePlex 上的 TFS PowerPack http tfspowerpack codepl
  • 用于验证 Active Directory 对象 SID 的正则表达式

    我正在寻找一种方法来验证从 Active Directory 插入的对象 SID 是否有效 是否可以使用preg match or preg match all 我在网上查找了用于此验证的正则表达式 但我找不到任何东西 Example si
  • Swift UIAlertController,文本中带有 url

    我有这个代码 func alertBox txt String let ac UIAlertController title MyTtle message More information in my website preferredSt
  • Select2 占位符问题

    我有一个 Select2 多选 html 元素 渲染时不显示占位符 但如果我选择并删除该项目 则会显示占位符 我不知道如何让它发挥作用 请指教 最初 选择时 移除物品后 Code Html DropDownListFor m gt m Ve
  • sizeof(array) 在运行时如何工作?

    我读过 C 中的 sizeof 运算符是在编译时解释的 并且由于在编译时编译器知道数组大小及其类型 因此 sizeof 能够计算数组占用的字节数 但是 sizeof 如何适用于以下代码 include
  • 在 SQL 中聚合

    我有一个看起来像这样的表 Conversion Date User Name Last Date Touch Touch Count 7 15 2017 A 6 17 2017 1 7 16 2017 B 6 24 2017 2 7 19
  • GCDAsyncSocket 服务器仅在第一次接收数据

    每次当我按下发送按钮时客户端都会发送消息 但服务器仅在第一次接收消息 服务器有什么问题 Server void viewDidLoad super viewDidLoad asyncSocket GCDAsyncSocket alloc i
  • AngularJS 在工厂和控制器之间跨模块共享数据

    我有一个 angularjs 应用程序 它有几个模块 主要模块如下所示 var app angular module mainMod apiService app controller MainCtrl function Socket sc
  • 如何使用 Terraform 的文件配置程序从本地计算机复制到虚拟机?

    我是 Terraform 的新手 到目前为止 我已成功在 Azure 上启动并运行了基本的 VM 加上资源管理器修剪 我想到的下一个任务是让 Terraform 将文件从本地计算机复制到新创建的实例中 理想情况下 我正在寻找一种解决方案 每
  • 无法连接到 localhost/127.0.0.1 android

    我是 android 开发的新手 并尝试通过改造库调用 android 中的本地 NET Web api 服务 在 IIS 上启动我的 Web api 后 我收到此错误无法连接到 localhost 127 0 0 1 android 当我
  • 使用 JavaScript 获取用户代理

    我想要一个可以获取用户的用户代理并将其支持到属性的脚本 我正在制作网站问题联系表 我通常需要知道用户使用的浏览器 如何检测用户代理字符串并将其支持为输入元素的值 我的 html 看起来像这样
  • 混合运行时是可行的解决方案吗?

    在我的公司 我们最近从 VC9 切换到 VC10 我们迁移了我们的项目 但是负责人告诉我们 我们必须在我们的生产机器上保留一些用 VC9 编译的基本通用 DLL 一段时间 这些 DLL 使用自定义结构 其中一些包含std vector st
  • 在 C++ 的条件或控制语句中声明和初始化变量

    在斯特鲁斯特鲁普的C 编程语言 特别版 第 3 版 Stroustrup 写道 在控制语句的条件中声明和初始化变量不仅是允许的 而且是鼓励的 他写道 他鼓励这样做 因为它将变量的范围缩小到仅需要它们的范围 所以像这样的事情 if int i