【问题标题】:What is the best way to transition to C from higher level languages?从高级语言过渡到 C 的最佳方法是什么?
【发布时间】:2009-05-19 13:57:47
【问题描述】:

我是一名网络编码员:我目前喜欢 AS3 并处理 PHP。我拥有一台 Nintendo DS,想试试 C。

从更高的层面来看,哪些基本的东西/生物舒适会消失? 我找不到 [for... in] 循环,所以我认为它们不存在。看起来我将不得不虔诚地声明事情,并且我假设我没有对象(我之前在 PHP 中处理过)。

哈希表?有趣的数据类型?

【问题讨论】:

    标签: c language-features


    【解决方案1】:

    总结起来,你基本上会得到:

    • 类型变量
    • 功能
    • 指针
    • 标准库

    然后,您完成剩下的工作——这可能有点过于简单,但这是一个关于要面对什么的粗略想法。

    一开始可能会令人生畏,并且可能需要克服学习曲线。以下是您可能会遇到的一些减速带:

    字符串?什么字符串?

    要习惯的一件大事是字符串。在 C 中没有 string 这样的东西。字符串是一个“null-终止字符数组”(有时称为C strings),这基本上意味着一个char 类型的数组,最后一个元素是\0char0)。

    在内存中,长度为 4 且包含 Hi!char 数组将显示为:

    char[0] == 'H'
    char[1] == 'i'
    char[2] == '!'
    char[3] == '\0'
    

    此外,字符串不知道自己的长度(没有像 C 中免费提供的“对象”之类的东西),因此需要使用标准库调用 strlen,这或多或少是一个 @ 987654341@ 循环遍历字符串直到遇到\0 字符。 (这意味着它是一个 O(N) 操作——字符串越长,查找长度所需的时间就越长,这与现代语言中大多数 string 实现的 O(1) 操作不同。)

    垃圾回收?

    C 中没有垃圾收集器这种东西。实际上,您需要自己分配和释放内存:

    /* Allocate enough memory for array of 10 int values. */
    int* array_of_ints = malloc(sizeof(int) * 10);
    
    /* Done with the array? Don't forget to free the memory! */
    free(array_of_ints);
    

    在分配内存后未能清理可能会导致称为 memory leaks 的事情,我相信您以前听说过。

    指针!

    和往常一样,当我们谈论 C 时,我们不能忘记 pointers。引用变量和取消引用指针的整个概念可能是一个令人头疼的概念,但是一旦你掌握了它,它实际上并不算太糟糕。

    除了您希望它以一种方式工作的时候,但您发现您对指针的理解不够好,它实际上做了其他事情——正如他们所说,去过那里,做过那个。

    哦,指针可能是您第一次真正看到程序崩溃的严重程度,以至于操作系统会对您大喊大叫。 segmentation faultnot something the computer likes a lot

    类型

    C 中的所有变量都有类型。 C 是statically-typed language,这意味着将在编译时检查变量类型。刚开始这可能需要一些时间来适应,但也可以看作是一件好事,因为它可以减少运行时错误,例如尝试将数字分配给字符串的类型错误。

    但是,可以执行typecasts,因此可以将int 类型(整数值)转换为double 类型(浮点类型值)。但是,无法尝试将int 直接转换为char* 之类的字符串。

    因此,例如,在某些语言中,以下是允许的:

    // Example of a very weakly-typed pseudolanguage with implicit typecasts:
    number n = 42
    string s = "answer: "
    string result = s + n  // Result: "answer: 42"
    

    在 C 语言中,必须调用 itoa 函数来获取 intchar* 表示,然后使用 strcat 连接两个字符串。

    结论

    如上所述,从一门高级语言学习 C 语言可能会让人大开眼界,而且一开始可能具有挑战性,但一旦掌握了它,使用起来会非常有趣。

    我建议开始尝试使用 C 编译器,并拥有一本好书或参考书。

    我想很多人都会推荐K&R book,这确实是一本好书。

    起初,我不认为推荐 K&R 作为第一本 C 书会是一个好主意,因为它可能有点困难,但仔细想想,我认为它是一本非常全面且很好的——如果您已经有一些编程经验,那么这本书对于进入 C 语言很有帮助。

    祝你好运!

    【讨论】:

    • +1。非常全面。我不是从 C 开始,而是从其他“更友好”的语言开始。然而,当我深入研究 C 语言时,我开始理解为什么很多东西都像其他语言一样,比如 Java。所以我认为这将是一次非常有教育意义的经历。
    【解决方案2】:

    嗯...您可能会受到文化冲击。 These 是 C 语言中的 32 个标准关键字,包括基本类型。

    C 的标准库非常实用(可能超出人们的预期),但与高级语言提供的功能相比,它非常薄。看不到哈希表,您可以正确地假设 C 没有对对象的句法或语义支持。

    无论如何都可以编写漂亮的面向对象的代码,但是您将不得不跳过一些障碍,并且手动完成更多工作,因为该语言无法帮助您。例如,请参阅GTK+ UI 工具包,了解精心设计的面向对象的 C 库/API 示例。

    【讨论】:

    • 我知道多萝西离堪萨斯这么远的感觉...感谢关键字参考...它...稀疏:)
    • 哈希表?!尝试寻找一个单纯的字符串类型开始! :)
    【解决方案3】:

    我是一名网络编码员:我目前喜欢 AS3 并处理 PHP。我拥有一台 Nintendo DS,想试试 C。

    你为什么想做 C 编程? 你的理由是什么,你希望达到什么目的? 是为了给任天堂DS写软件吗?

    从更高的层面来看,哪些基本的东西/生物舒适会消失?

    鉴于你的背景,我认为你个人会怀念缺乏动态类型支持的问题,换句话说,你必须在你的 C 程序中非常明确,你的数据必须用正确的类型指定,以便编译器知道您正在使用什么类型的数据。这也适用于任何类型的内存管理,即基本上任何一旦你开始使用非 POD 的数据结构。

    例如,你会在 php 中做这样的事情:

    function multiply(x) {
     return (x*x);
    }
    

    你必须在 C 中做这样的事情:

    int multiply(int x) {
     return (x*x);
    }
    

    虽然这些看起来很相似,但有很大的不同,即类型限制:php 版本也适用于浮点值,而在 C 中,您必须明确提供不同类型和值范围的版本(C 类型被限制在某些范围内)。

    我找不到 [for... in] 循环,所以假设它们不存在

    在 C 中,它看起来更像以下内容:

    int c; 对于 (c=0;c

    看来我得虔诚地宣布事情了

    是的,非常如此 - 远远超过你会感激的

    我假设我没有对象(我之前在 PHP 中处理过)。

    正确,没有对象 - 但 OOP 仍然可以使用其他方式模拟,例如 function(struct obj)

    根据您的目标和动机,我认为您可能会发现 C 是一种非常令人沮丧的语言,开始认真编程时,您可能想研究一些相关的替代方案,例如 Java。

    【讨论】:

    • 他明确表示他想为 Nintendo DS 编程。因此 Java 和其他类似语言是完全不合适的。
    • 不,他没有明确说明任何类似的内容,您是在做一个假设……不过,这是一个安全的假设。我的假设是一样的,但仍然不清楚,这就是我要求澄清的原因。
    • 无论哪种方式,当他明确表示想学习 C 时,推荐 Java 作为学习 C 的替代方法,并没有那么有帮助。
    • 我不会继续争论阅读理解相关的问题,但众所周知的事实是,Java 是一种从 C 中借用许多元素和概念的语言,它实际上是为什么大学经常使用 Java 来向学生介绍编程,为最终过渡到 C 做准备。从这个意义上说,Java 实际上可能是一个很好的途径,可以让您更加熟悉用类似 C 的语言进行编程。跨度>
    • 孩子们!冷静下来!一个很好的答案,Java 可能完全 r0x0r5,但是是的,对于我正在查看的 DS 特定库,C 似乎是要走的路。事先学习Java可能很好,但我很不耐烦。
    【解决方案4】:

    动态数组和垃圾回收。它不是内置于 C 语言中的,因此您需要自行开发或使用预先存在的解决方案。

    标准程序是您自己管理内存,这听起来可能很可怕,但实际上并非如此。例如,在 AS3 和 PHP 中,您可以创建一个数组并在完成后忘记它。在 C 语言中,您必须确保自己释放它,否则内存会泄漏并且可能/将会发生坏事。

    【讨论】:

      【解决方案5】:

      您会特别怀念自动内存管理和语义上有意义的数据类型,例如字符串、表格等。然而,学好 C 是很有启发性的,即使你可能不想将它用于应用程序级编程,所以我建议你拿一本“K&R”(Kernighan 和 Ritchie 的开创性书籍)并试一试——你' 会在网络上找到大量免费库供您使用和学习,尽管您必须训练自己使用正确的内存管理启发式方法......学习愉快!

      【讨论】:

        【解决方案6】:

        我只是在网上做一些研究,似乎有可能使用 lua 在“nintendo DS”上进行开发,这实际上可能是熟悉高级语言的人开始做嵌入式的最简单方法开发,而不会牺牲太多的 HLL 能力,也不会在从 HLL 迁移到 C 时经历不可避免的文化冲击:microlua,这里是API docs

        所以你可能想试一试,可能使用模拟器作为初学者。

        随时通知我们!

        【讨论】:

        • 哇!卢阿?我不认为我有任何选择。我也可以看看!谢谢
        【解决方案7】:

        我很确定你想看的是 C++,而不是 C。C++ 基本上是面向对象的 C。

        【讨论】:

        • 糟糕的 C++ 是“基本上面向对象的 C”。好的 C++ 与 C 完全不同。
        • 当我开始学习 c++ 时,我将从 Bad C++ 开始并继续努力。
        【解决方案8】:

        您会真正怀念的是快速制作原型和测试更改的能力。您不能只更改一行代码并运行。即使使用诸如“make”之类的构建工具,重新编译通常也需要几分钟时间。当您考虑到在 C/C++ 中很容易出错时,情况就更糟了。在大型项目中,我认为我花在编译而不是实际编码上的时间更多。作为脚本语言的长期用户,这是我使用 C 时最大的问题。

        【讨论】:

          【解决方案9】:

          直接从在具有无限资源的机器上运行的高级语言转移到 DS 将是一个挑战,而不仅仅是因为语言。

          Nintendo DS 只有 4MB 的 RAM、66MHz 的 ARM-7,没有操作系统,可用的开发库(例如 libnds)仅提供对硬件本身的薄抽象。

          因此,除了必须处理手动内存管理、更简单的语言、更少的生物舒适、静态类型、缺少对​​象以及需要运行编译步骤才能看到任何更改之外,您还必须处理内存碎片、现代标准的非常慢的 CPU,并且需要直接与硬件交互才能做任何有用的事情。

          为 DS 编写代码,唯一的其他选择是 C++。在这样一个有限的系统上,你不能使用许多使 C++ 有价值的高级特性。您将使用 C++ 编译器编写 C 代码。

          也就是说,这很有趣。您可以随心所欲地使用硬件,而无需与操作系统接口,因为没有操作系统。

          【讨论】:

            【解决方案10】:

            C 是直接汇编程序之上的下一个级别,允许您在金属附近进行操作。这使您有能力做出惊人的事情,但也可以轻松地射中自己的脚!

            一个这样的例子是直接内存访问和指针运算的危险和奇迹。指针非常强大、快速且方便,但需要仔细管理。有关示例,请参阅此 SO question

            正如其他回答者所提到的,您必须自己进行内存管理。再次强大而痛苦。

            我建议您研究一下good textbook 并找到一些高质量的示例代码。关键是要学习使所有这些东西正确而优雅地组合在一起的模式(嗯,尽可能多)。一个好的调试器也会真正帮助并熟悉标准 C 库。

            您可能会注意到您的应用程序一开始就崩溃了,但坚持使用 C 绝对值得至少涉足。您将了解高级语言提供的一些惊人的抽象以及幕后实际发生的事情。

            【讨论】:

              【解决方案11】:

              我们需要更多的自制软件开发人员。我是 GBA/NDS 和许多其他嵌入式平台开发人员,希望看到您继续这样做。我会说跳到 arm 汇编器,然后回到 C 或任何其他你喜欢的语言,一旦你知道处理器是如何工作的,语言就是语法。

              我假设您之前的经验涵盖了编程思维,将事物分解成小块,然后编写代码来执行这些块。然后是另一个将它们链接在一起的模块,依此类推。那么C只是另一种语言,一种非常非常简单的语言,不需要钻到它的角落里,从中间往下走。声明变量等是一个好习惯,在这里你必须这样做。当您忘记某些内容时,编译器会告诉您。你不需要大概念,大结构,语言魔法,这是嵌入式的,你是资源有限的,在这里写一些字节,在那里读一个寄存器,从数据中提取一点来看看是否按下了按钮,写响应移动精灵等的寄存器。

              我想一开始你会发现 NDS 比 C 更难,有两个处理器和一些基础设施来获得最简单的工作二进制文件。当然,那里也有很多例子。我通常(并且仍然这样做)建议从 GBA 开始,然后毕业到 NDS。一口大小的块。

              【讨论】:

              • 真的吗?你认为我应该去汇编?哇。我知道这将是具有挑战性的......
              • 甚至 BASIC 都不像汇编程序那么简单。想想你不必声明变量,你可以随意使用寄存器。
              【解决方案12】:

              OOP 的很多东西在 PHP 和 C# 中是相同或几乎相同的。

              你不会在 C# 中使用指针(与 C++ 相比),所以如果你想使用 C,我肯定会推荐使用 C#。

              你在说什么 C?

              C#

              foreach(string item in itemsCollection)
              {
              ...
              }
              

              PHP

              foreach($itemsCollection as $key=>$value)
              {
              ...
              }
              

              等等

              我喜欢 C#,因为它是强类型的,并且在您编写代码时会自动检查您的类型...与可以将任何内容保存到任何内容的 PHP 相比,尝试将整数保存到字符串或反之亦然的可能性为零。 ..

              【讨论】:

              • C 和 C# 与 Car 和 Carpet 差不多。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-02-20
              • 1970-01-01
              • 2011-02-15
              • 2014-04-11
              • 2011-09-30
              相关资源
              最近更新 更多