C:嵌套的 If 或 Goto

2024-04-02

管理资源的最佳方式是什么C程序。我应该使用嵌套的 if 结构还是应该使用 goto 语句?

我知道有很多taboo about goto声明。不过,我认为本地资源清理是合理的。我提供了两个样品。一种比较嵌套的 if 结构,另一种使用 goto 语句。我个人发现 goto 语句使代码更易于阅读。对于那些可能认为嵌套如果提示更好的结构,想象一下数据类型是否不是 char*,比如 Windows 句柄。我觉得嵌套如果结构会因一系列的失控创建文件 http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx函数或任何其他需要大量参数的函数。

This article http://vilimpoc.org/research/raii-in-c/演示本地 goto 语句为 C 代码创建 RAII。代码简洁且易于理解。想象一下,作为一系列嵌套如果声明。

我明白那个goto在许多其他语言中这是禁忌,因为它们存在其他控制机制,例如 try/catch 等,但是在 C 中似乎是合适的。

#include <stdlib.h>

#define STRING_MAX 10

void gotoExample()
{
    char *string1, *string2, *string3, *string4, *string5;

    if ( !(string1 = (char*) calloc(STRING_MAX, sizeof(char))) )
        goto gotoExample_string1;
    if ( !(string2 = (char*) calloc(STRING_MAX, sizeof(char))) )
        goto gotoExample_string2;
    if ( !(string3 = (char*) calloc(STRING_MAX, sizeof(char))) )
        goto gotoExample_string3;
    if ( !(string4 = (char*) calloc(STRING_MAX, sizeof(char))) )
        goto gotoExample_string4;
    if ( !(string5 = (char*) calloc(STRING_MAX, sizeof(char))) )
        goto gotoExample_string5;

    //important code goes here

gotoExample_string5:
    free(string4);
gotoExample_string4:
    free(string3);
gotoExample_string3:
    free(string2);
gotoExample_string2:
    free(string1);
gotoExample_string1:
}

void nestedIfExample()
{
    char *string1, *string2, *string3, *string4, *string5;

    if (string1 = (char*) calloc(STRING_MAX, sizeof(char))) 
    {
        if (string2 = (char*) calloc(STRING_MAX, sizeof(char)))
        {
            if (string3 = (char*) calloc(STRING_MAX, sizeof(char)))
            {
                if (string4 = (char*) calloc(STRING_MAX, sizeof(char)))
                {
                    if (string5 = (char*) calloc(STRING_MAX, sizeof(char)))
                    {
                        //important code here
                        free(string5);
                    }
                    free(string4);
                }
                free(string3);
            }
            free(string2);
        }
        free(string1);
    }
}


int main(int argc, char* argv[])
{
    nestedIfExample();
    gotoExample();
    return 0;
}

我还想引用 Linus Torvalds 的话gotoLinux 内部的语句Kernel http://kerneltrap.org/node/553/2131.

有时结构是bad, 和 妨碍,并使用“goto” 更清楚了。

例如,这是很常见的 有不嵌套的条件。

在这种情况下你有两个 可能性

  • 使用 goto,并且很高兴,因为它不强制嵌套

    这使得代码more可读, 因为代码只是做了什么 算法说它应该做。

  • 复制代码,并以嵌套形式重写,以便您可以
    使用结构化跳转。

    这通常会使代码变得更少 可读,难以维护,并且 大。

Pascal 语言就是一个典型的例子 的后一个问题。因为它 没有“break”声明, (传统)Pascal 中的循环最终结束 通常看起来完全是一坨狗屎,因为 你必须添加完全任意的 逻辑上说“我现在完成了”。

Is goto资源管理可以接受吗?我应该使用嵌套如果声明或者有更好的方法吗?

Update: C 语言中良好 Goto 的示例 https://stackoverflow.com/questions/245742/examples-of-good-gotos-in-c-or-c


毫无疑问,Dijkstra 是编程界的一位令人敬畏的人物。他的后藤被认为是有害的 http://www.massey.ac.nz/~kahawick/159331/Goto-Harmful-Dijkstra.pdf纸 太夸张了。是的,GoTo 可能会被滥用并且可能有害,但许多人认为彻底禁止 GoTo 是 没有保证。高德纳 (Knuth) 对迪杰斯特拉 (Dijkstra) 提出了非常有理有据的反驳:带有 GO TO 的结构化编程 http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf

阅读 Knuth 的论文,你会发现你的 GoTo 模式是很好的用途之一 对于转到。

顺便说一句,迪杰斯特拉在许多其他事情上也很容易被引用。怎么样:

  • 面向对象编程是一个非常糟糕的想法,它只能起源于加利福尼亚州。

Dijkstra 是一位伟大的数学家,对计算机科学做出了巨大贡献。然而,我不 99.99% 的人认为他必须处理日常事务,或者对这些事务感兴趣 我们的程序可以。

仅在有理由和结构的情况下使用 GoTo。很少使用它们。但一定要使用它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C:嵌套的 If 或 Goto 的相关文章

  • UTF8/UTF16 和 Base64 在编码方面有什么区别

    In c 我们可以使用下面的类来进行编码 System Text Encoding UTF8 System Text Encoding UTF16 System Text Encoding ASCII 为什么没有System Text En
  • ROWNUM 的 OracleType 是什么

    我试图参数化所有现有的 sql 但以下代码给了我一个问题 command CommandText String Format SELECT FROM 0 WHERE ROWNUM lt maxRecords command CommandT
  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在我的应用程序中使用 Windows Key

    Like Windows Key E Opens a new Explorer Window And Windows Key R Displays the Run command 如何在应用程序的 KeyDown 事件中使用 Windows
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • HttpClient 像浏览器一样请求

    当我通过 HttpClient 类调用网站 www livescore com 时 我总是收到错误 500 可能服务器阻止了来自 HttpClient 的请求 1 还有其他方法可以从网页获取html吗 2 如何设置标题来获取html内容 当
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • 编译的表达式树会泄漏吗?

    根据我的理解 JIT 代码在程序运行时永远不会从内存中释放 这是否意味着重复调用 Compile 表达式树上会泄漏内存吗 这意味着仅在静态构造函数中编译表达式树或以其他方式缓存它们 这可能不那么简单 正确的 他们可能是GCed Lambda
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 什么是 C 语言的高效工作流程? - Makefile + bash脚本

    我正在开发我的第一个项目 该项目将跨越多个 C 文件 对于我的前几个练习程序 我只是在中编写了我的代码main c并使用编译gcc main c o main 当我学习时 这对我有用 现在 我正在独自开展一个更大的项目 我想继续自己进行编译
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 将 viewbag 从操作控制器传递到部分视图

    我有一个带有部分视图的 mvc 视图 控制器中有一个 ActionResult 方法 它将返回 PartialView 因此 我需要将 ViewBag 数据从 ActionResult 方法传递到 Partial View 这是我的控制器

随机推荐