C 编程/入门练习
传统上,我们从一个显示“Hello, World!”问候语到屏幕,然后换行并退出程序开始。以下是用 C 语言编写的源代码,可以实现这个功能。将这段代码输入你喜欢的文本编辑器/IDE,并将其保存到一个名为hello.c的文件中。
#include <stdio.h> int main(void) { printf("Hello, World!\n"); return 0; }
虽然这是一个非常简单的程序,但在你看到的代码中包含了很多隐含的含义。虽然你的编译器理解它,但你只能猜测代码(散布着一些熟悉的英文单词)可能会做什么。作为一名新程序员,你的第一个工作之一就是学习 C 编程语言的许多“单词”和符号,这是你的编译器所理解的语言。一旦你了解代码背后的含义,你就可以“与”编译器“交谈”,并给它下达你自己的命令,并构建任何你具有足够的创造力和资源可以创建的程序。
但需要注意的是,了解神秘符号的含义并不是编程的全部。你不能通过阅读翻译词典来掌握另一种语言。要精通另一种语言,你必须练习用这种语言交谈。学习编程语言也是一样的。你必须练习用你编写的源代码与编译器“交谈”。因此,请务必输入上面的代码示例,并根据你的好奇心随意进行实验和修改。
好的,让我们深入了解我们程序的第一行
#include <stdio.h>
在你理解这一行做了什么之前,你必须知道你的机器已经预装了一些 C 软件代码。这些代码是为了让你免于编写执行基本、常见任务的代码的繁琐工作。这种可重用的代码被称为库。因此,我们示例程序的第一行向编译器发出信号,我们想从库中“查看”一些代码,并在我们的程序中使用它。在这里,我们借用了帮助我们打印文本到屏幕的代码。
我们告诉 C 编译器将库代码包含到我们自己的代码中的方法是使用被称为预处理器指令的东西。你的编译器将执行的最早任务之一是在你的源代码中搜索预处理器指令,这些指令会以某种方式修改你的源代码。在我们的例子中,#include
预处理器指令告诉编译器从库中复制源代码,并将其直接插入到找到预处理器指令的代码中。由于我们的指令位于文件的顶部,库代码将插入到源文件的顶部。(请注意,所有这些操作都发生在计算机的内存中,因此磁盘上的原始文件实际上永远不会被修改。)
但是编译器应该插入哪个库代码呢?这一行中的下一部分,<stdio.h>
,告诉编译器从stdio.h文件中复制和粘贴 C 代码到你的代码中。围绕文件名的一对尖括号告诉编译器在标准库中查找该文件,而不是说你自己的可重用代码库。请注意,扩展名为.h的文件被称为头文件。stdio.h 头文件包含许多与输入和输出相关的函数,这些函数是根据 C 标准定义的。虽然这个头文件让我们可以使用许多不同的函数,但我们感兴趣的 stdio.h 中唯一一个库函数是printf
函数。
好的,但是函数到底是什么呢?让我们看看我们代码中的下一行,这样我们就可以开始了解它了
int main(void)
在这里,我们创建了一个名为main
的函数,它是所有 C 程序的起点。所有 C 程序都需要一个名为“main”的函数,否则它们将无法编译。我们的函数名称被两个神秘的符号包围,int 和 (void)。“int”部分告诉编译器我们的函数将返回什么类型的数值,而“(void)”部分告诉我们的编译器我们将向我们的函数“传递”什么类型的数值。我们现在暂时跳过这到底是什么意思,因为这些值将在本书后面的章节中详细介绍。现在最重要的是要了解,这些符号一起声明我们的函数给编译器,并告诉它函数存在。
那么函数是什么呢?在计算机科学中,“函数”这个词的含义比在数学中要宽泛一些,因为函数通常表达命令式的想法(比如 C 语言中的情况)——也就是说,如何进行处理,而不是声明。现在,只需说,函数定义了一组一起工作以完成特定任务的计算机语句。在 C 语言中,与函数相关的语句放在一对花括号{ }
之间,它们标记着语句的开始和结束。花括号和语句一起被称为代码块。让我们看看我们函数代码块中的第一行
printf("Hello World!\n");
这行代码是我们程序的核心,是将问候语输出到用户控制台(在类Unix操作系统环境中也称为终端,即安装在你计算机上的基于文本的界面)的代码。这个语句是一个函数调用,它主要有两部分:用来打印问候语的库函数的名称,printf,以及我们将传递给函数的数据,在这里看到的是一对括号之间的部分。我们传递给函数的数据是字符串,“Hello World!\n”。字符串末尾的“\n”部分是一种特殊类型的字符,称为转义序列。“\n”转义序列在文本末尾生成换行符。字符串和转义序列将在后面详细介绍。我们在函数调用语句的末尾用分号结束,这样编译器就知道它应该开始寻找新的语句,它在下一行找到了它
return 0;
在这里,我们使用return
关键字说明我们的main
函数返回一个整数类型的值。我们返回的整数值是“0”。但是这到底意味着什么呢?在main
函数的特定上下文中,我们返回的值称为退出状态,我们将其报告回操作系统,以指示我们的代码是否运行没有错误。随着我们的程序变得越来越复杂,我们可以使用其他整数作为代码来指示各种类型的错误。这种提供退出状态的风格是一个长期的约定[1]。我们将在本书后面的章节中更详细地介绍函数的返回值。
所以对于这样一个简短的程序来说,我们要学习的内容很多。如果你没有完全理解它,或者没有记住它,不要担心。你不是通过记忆来学习编程,而是通过重复和实践来学习。记住贝多芬第五交响曲的所有音符并不能让你成为一名钢琴演奏家,你必须坐在键盘前练习和演奏!
接下来,我们将向你展示如何使用你的编译器将你输入的源代码转换成可执行文件。
编译是我们用来描述将你给编译器下达的指令(在你的源代码中)转换成你的操作系统和微处理器可以运行的机器语言的过程。这样,你的 C 编译器就是一个中间人。你用编译器可以理解的语言(C 源代码)与编译器交谈,编译器将源代码转换成机器代码,为你省去了大量编写汇编代码的痛苦和繁琐工作。
如果编译器发现您的源代码令人困惑,它会抛出一个错误以及一条消息来帮助您修复源代码并消除任何混淆。然后,您需要尝试重新编译代码并重复此过程,直到它在没有错误的情况下编译。请注意,没有错误的代码并不意味着它没有错误。它只是意味着编译器理解您的源代码提供的指令。
如果您使用的是类 Unix 系统,例如 GNU/Linux、Mac OS X 或 Solaris,它很可能已经安装了 GCC,否则在 Linux 上,您可以使用您发行版的包管理器安装它。打开虚拟控制台或终端模拟器并输入以下内容(确保您的当前工作目录是包含您的源代码的目录)
gcc hello.c
默认情况下,gcc 会生成我们的可执行二进制文件,名称为 a.out。要运行您新生成程序,请键入
./a.out
您应该在最后一个提示符之后看到 Hello, World!
打印出来。
要查看您运行的最后一个程序的退出状态,请在您的 shell 命令中键入
echo $?
这显示了 main
函数返回的值,在本例中为 0。
您可以使用许多选项与 gcc 编译器一起使用。例如,如果您希望输出具有与 a.out 不同的名称,则可以使用 -o 选项。以下显示了一些示例
-o
- 表示下一个参数是结果程序(或库)的名称。如果未指定此选项,出于历史原因,已编译程序最终将位于名为“a.out”或“a.exe”的文件中(对于 cygwin 用户)。
-Wall
- 表示 gcc 应该警告可能不正确的许多类型可疑代码。
您可以使用这些选项创建一个名为“helloworld”的程序,而不是“a.out”,方法是键入
gcc -o helloworld hello.c -Wall
现在您可以通过键入以下内容运行它
./helloworld
所有选项在 GCC 的手册[2] 中都有详细的说明。
如果您使用的是 IDE,您可能需要选择控制台项目,要编译,您只需从菜单或工具栏中选择构建即可。可执行文件将出现在项目文件夹中,但您应该有一个菜单按钮,因此您可以直接从 IDE 运行可执行文件。该过程在所有 IDE 上大致相同。