【问题标题】:Need some help with C programming [closed]在 C 编程方面需要一些帮助 [关闭]
【发布时间】:2011-03-17 03:31:37
【问题描述】:

我是 C 编程新手,在理解 C 编程中不同库函数的常见缺陷和常见用法时遇到问题。有人能给我指出一个很好的资源,我可以在其中学习 C 编程的精妙之处。也有人可以向我指出一个很好的资源来学习 gdb 之类的调试工具。

我也想知道 char *c="hello";char c[10]="hello" 有什么区别。有人能告诉我在不同的情况下推荐哪一种。

感谢和问候,

鼠标。

【问题讨论】:

  • 这里有很多问题,请尝试将它们作为单独的问题重新发布。也尝试搜索每个子问题。我相信搜索这个网站会给你一些很好的教程链接。
  • 您的问题标题根本没有描述您的问题。明智的做法是对其进行编辑和改写以具有实际意义。
  • 关于char*char[] 的问题已被多次询问和回答。这是其中之一:stackoverflow.com/questions/1880573/…
  • @mousey:分别问前两个问题。到时候你就会得到答案。
  • 有关 C 的书籍,请参阅stackoverflow.com/questions/562303/…

标签: c


【解决方案1】:
char *c = "hello";

这使得c 成为一个指针并指向不应修改的内存(因此您无法修改数据)。但是由于c是一个指针,你可以改变它指向的位置。

char c[10] = "hello";

这使c 成为一个数组,并安排用指定的字符串初始化该数组。由于它是一个数组,因此您可以修改数据(尽管确保不会溢出缓冲区),但您无法更改内存中的 c 引用。

【讨论】:

    【解决方案2】:

    只需阅读The C Programming Language 并编写代码。如果您是新手,那么您需要第一手经验,以便了解其中的微妙之处。仅仅阅读一个列表不会有很大帮助。

    【讨论】:

    • 我熟悉c标准库中的所有函数。但是我经常被需要特别注意的 c 指针和函数所欺骗。
    • 智慧之言,为 Kernighan 和 Ritchie +1 @mousey:所以你的问题不是真正的标准库,而是准确理解指针的一些问题。那么K&R是最好的选择
    • @mousey:但是 C++ 中的指针(你说你很熟悉)与 C 中的指针相同;那么真正的问题是什么?
    • +1:我没有在回答中特别提到 K&R,因为您已经这样做了。作为“已接受”的答案,尽管它只解决了问题的一部分。正如已经评论的那样,出于这个原因,它们应该单独发布。
    【解决方案3】:

    对于语言本身,book by the language designers 是一本不错的读物。一定要做好练习。

    另一个有用的资源是comp.lang.c FAQ。你问过question 6.2(请务必阅读6.16.3)。

    上面的链接已经解释过了,但只是坚持:指针和数组在 C 中不是相同的东西。相反,在某些情况下语言需要指针,但你可以使用数组,它会自动转换。

    【讨论】:

    • +1 comp.lang.c 非常棒,尤其是在细节方面。
    【解决方案4】:

    区别如下:

    char *c = "hello";
    

    创造了几个东西:

    • char* 称为 c
    • 内存中填充了“hello\0”的静态字符串
    • 并将c 设置为该静态内存的地址

    鉴于:

    char c[10] = "hello";
    

    创建:

    • char* 称为 c(请参阅下面的注释)
    • 内存中某处的 10 个插槽
    • c设置为上面第一个位置的地址
    • 并将"hello" 视为{'h','e','l','l','o','\0'},从而将这些值复制到c[0]c[5]
    • 取决于编译器,"hello" 可能会或可能不会分配到内存中的某个位置

    注意:

    在第二种情况下,从技术上讲,不存在仅包含数组地址的数组和变量,看起来就是这样。所以c 实际上只是数组中第一个位置地址的别名。在 cmets 下面用 Tim 的信息进行了更新。

    【讨论】:

    • Nitpick:数组声明不会创建一个名为 cchar * 指针。它有一个地址,但它是隐含的。可以从它创建一个指针——有时是隐式的,比如当数组“降级”为指针时——取决于它的使用方式。 c 在这种情况下 数组,而不是指向它的指针。
    • @tim - 你如何建议我改写准确而又不会太混乱。另外,您确定为指向c 的指针的地址选择内存位置不是依赖于编译器的事情吗?
    • @eruciform:我承认,很难在不混淆的情况下进行解释。 C 可以有一个特殊的运算符来给你一个指向c 的第一个字符的字符指针,但是让数组用作指针更容易。 c 是一个数组而不是指针,这与编译器无关,因为这个事实不是结果程序的事实,而是 C 语言工作的抽象机器的事实。
    • @tim - 我会添加一条评论,然后尝试解释这一点......在那里。我玩了一半——一次是根据它的外观,然后是一个脚注来深入解释......希望在两者之间,人们可以理解它。
    • @eruciform:酷。我知道我说这是吹毛求疵,但它确实有实际效果。例如。当c 是指针时,&c 为您提供不同的东西(不同类型),而不是c 是数组时。
    【解决方案5】:

    gdb,文档在线http://sourceware.org/gdb/current/onlinedocs/gdb/

    还有一张我觉得更有用的备忘单:http://users.ece.utexas.edu/~adnan/gdb-refcard.pdf

    【讨论】:

      【解决方案6】:

      我的第一个建议是,除非您有充分的理由专门学习 C,否则请改为学习 C++。我意识到这可能会引起一些人的争议。如果您还没有这样做,请考虑一下。

      对于资源,首先一本好书总是最好的,但是如果您正在寻找在线资源,那么您会发现许多与 C++ 相关,有些涉及 C 和 C++;不同的写作风格和呈现方式适合不同的用户;尝试其中一些:

      以下与 C++ 相关的站点包含对 C 标准库的出色介绍:

      关于 GDB,我对使用符号调试器的好处表示赞赏,值得注意的是,有多少开发人员避免使用这个必不可少的工具,但建议使用原始 GDB 可能会让你终生放弃这些工具。如果您能够在 Windows 上使用 VC++,那么它的调试器是首屈一指的,而且 VC++ Express 是免费的。如果您必须使用 GDB(例如因为您使用的是 Linux),我建议您使用集成到 IDE(如 Eclipse 或 KDevelop)中的 GDB,或者使用独立的 Insight 调试器。如果您确实选择了硬核并直接使用 GDB,那么除了 GDB manual 本身之外,似乎很少有关于如何有效使用它的资源。还有Debugging with GDB: The GNU Source-Level Debugger 30 美元。

      【讨论】:

      • 不同意。 C 是一种更简单的语言。如果您要建议另一种新手语言,请选择具有垃圾收集功能的高级语言。
      • 很抱歉提到这件事。我擅长 C++ 和 Visual Studio。在过去的 3 年里,我一直在使用 C++。但我正在让自己进入内核编程。我只是想要一个有用的 Linux 内核调试快速入门指南。所以我询问了 gdb。
      • @Nathon:C 更简单,但您不必使用 all 的 C++ 来有效地使用它。即使对于直接的 C 代码,C++ 编译也有好处。除此之外,他似乎不是新手,对于内核编程来说,这样的语言是不合适的(尽管承认之前并不清楚那是状态)
      • @mousey:如果您已经了解 C++,那么您已经了解 C。编译器很快就会拒绝您使用的任何 C++ 特定代码。你在 C++ 中使用了什么调试器(因为 GDB 也可以用于 C++)?鉴于 Torvalds 对 C++ 的著名仇恨,在这种情况下您可能需要 C,但 C++ 与 C 一样适合系统级编程。
      • @mousey:对于内核级别的工作,您可能需要考虑通过 TCP/IP 连接远程使用 GDB。如果您没有单独的目标和主机,您可以使用虚拟机目标并在单台机器上进行开发和调试。请注意,它看起来越来越像您应该将这些问题分开。
      【解决方案7】:

      如果您有数学倾向,Project Euler 可能会在某些领域为您提供一些好的实践,尤其是在数组操作和其他方面。

      但请记住,编程不仅仅是数学——不管你的教授可能会告诉你什么。

      【讨论】:

        【解决方案8】:

        Andrew Koenig 的“C 陷阱和陷阱”是一本非常适合学习 C 陷阱的书籍。不过,这是一本很薄的书。其他人指出的 comp.lang.c FAQ 也是一个很好的资源。

        【讨论】:

          【解决方案9】:

          尝试搜索“c 编程难题”,您会发现很多关于语言本身微妙之处的资源(而且还有很多)。例如。 here

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-08
            • 1970-01-01
            • 1970-01-01
            • 2018-10-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多