1972 年,Dennis Ritchie 在贝尔实验室工作,几年前,他和他的团队成员在那里发明了 Unix。在创建了一个持久耐用的操作系统(至今仍在使用)之后,他需要一种好的方法来编程这些 Unix 计算机,以便它们可以执行新的任务。现在看来很奇怪,但在当时,编程语言相对较少;Fortran、Lisp、Algol 和 B 很流行,但对于贝尔实验室的研究人员想要做的事情来说还不够。Dennis Ritchie 展示了程序员的主要特征,他创建了自己的解决方案。他称之为 C,将近 50 年后,它仍然被广泛使用。
为什么你应该学习 C 语言
今天,有许多语言提供的功能比 C 语言更多。最明显的一个是 C++,这是一种相当明显的命名语言,它建立在 C 语言之上,创建了一种很好的面向对象语言。尽管如此,还有许多其他语言,它们的存在是有充分理由的。计算机擅长一致的重复,因此任何可预测到足以构建到语言中的东西都意味着程序员的工作量减少。当一行 C++ (long x = long(n);
) 可以完成相同的工作时,为什么要花费两行代码在 C 语言中将 int
重新转换为 long
呢?
然而,C 语言在今天仍然有用。
首先,C 语言是一种相当精简和直接的语言。除了编程基础知识之外,没有非常高级的概念,这主要是因为 C 语言实际上是现代编程语言的基础之一。例如,C 语言具有数组,但不提供字典(除非你自己编写)。当你学习 C 语言时,你将学习编程的构建块,这可以帮助你认识到最近语言的改进和精巧的设计。
因为 C 语言是一种精简的语言,你的应用程序可能会获得性能提升,而这在许多其他语言中是看不到的。当你考虑代码执行速度时,很容易陷入追求极致速度的竞赛中,因此重要的是要问你是否需要针对特定任务获得更快的速度。而且,与 Python 或 Java 相比,使用 C 语言,你每行代码需要关注的东西更少。C 语言速度很快。Linux 内核是用 C 语言编写的,这是有充分理由的。
最后,C 语言很容易上手,尤其是当你运行 Linux 时。你已经可以运行 C 代码,因为 Linux 系统包含 GNU C 库 (glibc
)。要编写和构建它,你所需要做的就是安装编译器,打开文本编辑器并开始编码。
C 语言入门
如果你运行的是 Linux,你可以使用你的软件包管理器安装 C 编译器。在 Fedora 或 RHEL 上
$ sudo dnf install gcc
在 Debian 和类似系统上
$ sudo apt install build-essential
在 macOS 上,你可以安装 Homebrew 并使用它来安装 GCC
$ brew install gcc
在 Windows 上,你可以使用 MinGW 安装一套最小化的 GNU 实用程序,包括 GCC。
验证你是否在 Linux 或 macOS 上安装了 GCC
$ gcc --version
gcc (GCC) x.y.z
Copyright (C) 20XX Free Software Foundation, Inc.
在 Windows 上,提供 EXE 文件的完整路径
PS> C:\MinGW\bin\gcc.exe --version
gcc.exe (MinGW.org GCC Build-2) x.y.z
Copyright (C) 20XX Free Software Foundation, Inc.
C 语法
C 语言不是脚本语言。它是编译型语言,这意味着它由 C 编译器处理以生成二进制可执行文件。这与 Bash 这样的脚本语言或 Python 这样的混合语言不同。
在 C 语言中,你创建函数来执行你想要的任务。默认情况下会执行名为 main
的函数。
这是一个用 C 语言编写的简单“hello world”程序
#include <stdio.h>
int main() {
printf("Hello world");
return 0;
}
第一行包含一个头文件,本质上是免费且非常底层的 C 代码,你可以在自己的程序中重用,称为 stdio.h
(标准输入和输出)。创建一个名为 main
的函数,并用一个基本的打印语句填充它。将此文本保存到名为 hello.c
的文件中,然后使用 GCC 编译它
$ gcc hello.c --output hello
尝试运行你的 C 程序
$ ./hello
Hello world$
返回值
Unix 哲学的一部分是,函数在执行后会“返回”一些东西给你:成功时什么也不返回,失败时返回其他东西(例如错误消息)。这些返回代码通常用数字(整数,更准确地说)表示:0 表示什么也没有,任何大于 0 的数字表示某种非成功状态。
Unix 和 Linux 被设计为期望成功时保持沉默是有充分理由的。这样你就可以始终计划成功,假设在执行一系列命令时不会遇到任何错误或警告。同样,C 语言中的函数在设计上期望没有错误。
你可以通过一个小小的修改来亲自查看这一点,使你的程序看起来会失败
include <stdio.h>
int main() {
printf("Hello world");
return 1;
}
编译它
$ gcc hello.c --output failer
现在使用内置的 Linux 成功测试来运行它。 &&
运算符仅在成功时执行命令的后半部分。例如
$ echo "success" && echo "it worked"
success
it worked
||
测试在失败时执行命令的后半部分。
$ ls blah || echo "it did not work"
ls: cannot access 'blah': No such file or directory
it did not work
现在尝试你的程序,它在成功时不返回 0;而是返回 1
$ ./failer && echo "it worked"
String is: hello
程序成功执行,但没有触发第二个命令。
变量和类型
在某些语言中,你可以创建变量而无需指定它们包含的数据类型。这些语言的设计使得解释器对变量运行一些测试,试图发现它包含的数据类型。例如,当你创建一个将 var
添加到显然是整数的表达式时,Python 知道 var=1
定义了一个整数。当你连接 hello
和 world
时,它同样知道单词 world
是一个字符串。
C 语言不会为你进行任何这些调查;你必须定义你的变量类型。有几种类型的变量,包括整数 (int)、字符 (char)、浮点数 (float) 和布尔值 (Boolean)。
你可能还会注意到没有字符串类型。与 Python、Java 和 Lua 以及许多其他语言不同,C 语言没有字符串类型,而是将字符串视为字符数组。
这里有一些简单的代码,用于建立一个 char
数组变量,然后使用 printf 以及一条简短的消息将其打印到屏幕上
#include <stdio.h>
int main() {
char var[6] = "hello";
printf("Your string is: %s\r\n",var);
你可能会注意到,此代码示例为一个五字母单词允许了六个字符。这是因为字符串末尾有一个隐藏的终止符,它占用数组中的一个字节。你可以通过编译和执行代码来运行代码
$ gcc hello.c --output hello
$ ./hello
hello
函数
与其他语言一样,C 语言函数接受可选参数。你可以通过定义函数要接受的数据类型,将参数从一个函数传递到另一个函数
#include <stdio.h>
int printmsg(char a[]) {
printf("String is: %s\r\n",a);
}
int main() {
char a[6] = "hello";
printmsg(a);
return 0;
}
此代码示例将一个函数分成两个函数的方式不是很有用,但它演示了 main
默认运行以及如何在函数之间传递数据。
条件语句
在实际编程中,你通常希望你的代码根据数据做出决策。这是通过条件语句完成的,if
语句是最基本的语句之一。
为了使此示例程序更具动态性,你可以包含 string.h
头文件,该文件包含用于检查(顾名思义)字符串的代码。尝试使用 string.h
文件中的 strlen
函数测试传递给 printmsg
函数的字符串是否大于 0
#include <stdio.h>
#include <string.h>
int printmsg(char a[]) {
size_t len = strlen(a);
if ( len > 0) {
printf("String is: %s\r\n",a);
}
}
int main() {
char a[6] = "hello";
printmsg(a);
return 1;
}
如此示例中所实现的那样,示例条件永远不会为假,因为提供的字符串始终是“hello”,其长度始终大于 0。此简陋的 echo
命令重新实现的最后一步是接受来自用户的输入。
命令行参数
每次启动程序时,stdio.h
文件都包含提供两个参数的代码:命令中包含的项目计数 (argc
) 和包含每个项目的数组 (argv
)。例如,假设你发出此假想命令
$ foo -i bar
argc
为 3,argv
的内容为
argv[0] = foo
argv[1] = -i
argv[2] = bar
你可以修改示例 C 程序以接受 argv[2]
作为字符串,而不是默认为 hello
吗?
命令式编程
C 语言是一种命令式编程语言。它不是面向对象的,也没有类结构。使用 C 语言可以教会你很多关于数据如何处理以及如何更好地管理代码运行时生成的数据。充分使用 C 语言,你最终将能够编写其他语言(例如 Python 和 Lua)可以使用的库。
要了解更多关于 C 语言的信息,你需要使用它。在 /usr/include/
中查找有用的 C 头文件,看看你可以做哪些小任务来使 C 语言对你有所帮助。在学习时,使用我们的 C 语言速查表,由 FreeDOS 的 Jim Hall 制作。它在一张双面纸上包含了所有基础知识,因此你可以在练习时立即访问 C 语法的所有要点。
5 条评论