用游戏概念学习 C/简介
- 本书旨在向新用户介绍 C 语言,同时使学习过程变得有趣,并为他们提供可以玩耍和修改的代码,以便他们在继续学习的过程中进行自我教育。本书的作者是一位 C 语言初学者,面向初学者编写,因此我可能并不总是使用最佳实践。有兴趣更深入地了解 C 语言的用户建议查看优秀的 C_Programming 维基教科书.
- 我刚开始与他人分享代码,所以我觉得我应该声明,包含在本维基教科书中的代码是由作者生成的,与其他代码的任何相似之处并非有意为之,除非它是一些基本的东西,比如数据结构的实现(链表、堆等)。
本书建议初学者使用 Linux 发行版,例如 Linux Mint 或 Ubuntu。虽然我对 Windows 上的 C 编程不熟悉,但微软的 Visual C++ 编译器应该能够编译 C 代码(如果可用)。C 语言在 Unix/Linux 环境中很容易开始学习,因为 Gnu C 编译器 (GCC) 默认包含在大多数发行版中。GCC 是一个命令行实用程序,它将 C 源代码转换为机器指令(二进制文件)。为了编写代码,你需要一个文本编辑器或集成开发环境 (IDE)。一个易于使用的 IDE 是 Geany,你可以在 Linux 上使用包管理器找到它。
文本编辑器可以像记事本一样简单,也可以像 Vim 和 Emacs 一样复杂。
让我们一举概括变量和标准 IO。
intro.c
#include <stdio.h>
int main() {
char input[50]; // # of characters we can read from standard input.
char name[50]; // variable to contain a name
printf("What is your name good sir?\n");
fgets(input, sizeof(input), stdin);
sscanf(input, "%s", &name);
printf("Ah, %s, a pleasure to meet you.\n", name);
return(0);
}
在我们编译它之前,让我们回顾一下我们的代码做了什么。
程序开头的 #include 语句让编译器知道我们要使用库。C 语言中的库称为头文件,以 ".h" 文件扩展名结尾。C 语言包含标准库来执行各种常见任务。STDIO,顾名思义,包含各种用于打印和读取的函数。
每个 C 程序的核心是主函数。它包含程序的主体,并且是程序启动时调用的第一个函数。所有函数都遵循此语法
datatype functionName (datatype argument) {
statement;
return (datatype); // The datatype before the function name lets the
// compiler know this is the kind of variable we will return.
}
语句可以是变量声明 (x = 100;) 或函数调用 (CallingFunction();)。所有语句都以分号结尾,并且将每个语句都放在自己的行上是一个好习惯。同样重要的是要仔细检查你的代码,以确保你没有遗漏任何分号。
C 语言中有 3 种基本数据类型,我们必须使用它们来声明我们的变量。我们使用数据类型声明它们,以便编译器确切地知道每个变量包含什么。它们包括
- char (例如 'a' | 单个字符)
- int (例如 123 | 整数)
- float (例如 12.345 | 小数)
在我们的示例中,我们使用 char,但在它后面添加方括号和一个数字。语法 Variable[#] 让编译器知道,我们想要的不是单个字符,而是一个 数组(字符字符串)。
我们正在使用 STDIO 中的 3 个函数:printf、fgets 和 sscanf。我们的 stdin 和 stdout 来自我们将运行代码的命令行。
Printf 将字符串(用引号表示)打印到标准输出。如果字符串中存在占位符(%letter),它还会打印变量。Fgets 从标准输入中读取一行并将其放入名为 Input 的变量中。Sscanf 查看名为 input 的变量并将它转移到名为 name 的变量中。当我们获取用户输入时,我们希望再次使用 Input,因此我们不能将我们的信息留在其中,否则我们会覆盖它!
return 语句可以从函数中返回 1 个数据类型或变量。我们使用返回值的最简单示例是查看某事物是真还是假。如果你有一个名为 isCapital 的函数,并对一个字母调用它,例如 isCapital('a'),我们将返回(False)。如果我们调用 isCapital('B'),我们将让我们的函数返回(True)。调用 isCapital 函数的函数将被设计为根据我们返回的值做出决定。
但是,函数不需要返回值。有时你可能会看到在函数之前使用 'void'。这意味着该函数根本不返回值。
既然我们已经了解了我们的代码的作用,让我们编译并运行它。导航到包含你的 C 程序的文件夹。如果你不熟悉 BASH,则需要学习 cd 和 ls 命令。在命令终端中输入
gcc intro.c -o intro
此命令调用编译器 (GCC) 编译 Intro.c 并输出一个名为 Intro 的可执行文件。如果由于某种原因你的文件在编译后未设置为可执行文件,你可以输入
chmod +x intro
要运行你的可执行文件,请输入
./intro
这不像打印 "Hello World" 那样简单,但希望它不难理解。随着你继续阅读,随着你开始识别编程中的常见模式,事情应该开始变得更有意义。
在我们继续之前,花点时间调整我们的 Intro 程序。声明一个名为 age 的 int 变量。将第一个打印语句更改为询问你的年龄,并使用整数占位符 %d 在第二个打印语句中打印你的年龄。
如果我们将所有函数和变量都放在一个文件中,那么阅读大型程序将非常困难。假设我们还创建了一个很棒的函数,并且希望在所有程序中使用它,我们该怎么做呢?
如果我们希望我们的可重用函数执行我们上一个程序执行的操作,我们只需将之前的所有语句放在一个具有唯一名称的函数中,并将它们放在头文件中。
greet.h
#include <stdio.h>
int Greet() {
char input[50]; // # of characters we can read from standard input.
char name[50]; // variable to contain a name
printf("What is your name good sir?\n");
fgets(input, sizeof(input), stdin);
sscanf(input, "%s", &name);
printf("Ah, %s, a pleasure to meet you.\n", name);
return(0);
}
现在可以在我们的程序中像 STDIO 一样包含 Greet.h,我们甚至不需要在使用它之前编译它。唯一的区别是,我们使用引号 "" 而不是尖括号 <>。如果你的主程序和你的头文件在同一个文件夹中,#include "Greet.h" 是你唯一需要指定的内容。如果它们位于不同的文件夹中,你需要为编译器提供完整路径 #include "fullpath/Greet.h"
main_prog.c
#include "greet.h"
int main() {
Greet(); // We declared this function in greet.h
return(0);
}
当 main_prog.c 被编译时,编译器会查找头文件并将它们包含在编译中。
gcc main_prog.c -o main_prog
main_prog,可执行文件,将包含主程序和 Greet 文件的机器指令。
./main_prog
What is your name good sir?
Theodore Roosevelt
Ah, Theodore Roosevelt, a pleasure to meet you.