在学习 C 语言的语法和编程结构之前,了解一些关键术语非常重要,因为它们在理解 C 语言时至关重要。

块结构、语句、空白符和作用域
/**/ 定义的句子是注释,编译器会忽略它们。它们将在《编程结构与风格》中详细描述。


接下来,我们将讨论 C 程序的基本结构。如果你熟悉 PASCAL 语言,可能听说过它是块结构化语言。C 语言并不具备完整的块结构(你将会在详细讲解函数时了解原因),但了解什么是块以及如何使用它们仍然非常重要。

那么,块里包含什么呢?一般来说,块由可执行的语句组成。

但在深入讨论块之前,我们先来看看语句。描述语句的一种方式是:它们是编译器会尝试将其转化为可执行指令的文本(以及周围的空白符)。更简单的定义是:语句是执行某些操作的代码片段。例如:

int i = 6;

这声明了一个整数变量,可以通过标识符 i 访问,并将其初始化为值 6。各种数据类型将在《变量》章节中介绍。

你可能注意到了语句末尾的分号。C 语言中的语句总是以分号(;)结尾。省略分号是许多人,包括初学者和专家常犯的错误!所以,直到这成为你的一种习惯,确保仔细检查你的语句!

由于 C 是一种“自由格式”的语言,多个语句可以共享源文件中的一行,例如:

/* 这声明了变量 'i'、'test'、'foo' 和 'bar',
   请注意,只有名为 'bar' 的变量被初始化为 6! */
int i, test, foo, bar = 6;

语句有多种类型。你已经看到了一些,例如赋值语句(i = 6;)。本书的很大一部分内容都会讨论语句的构造。

回到我们对块的讨论。在 C 中,块以开括号“{”开始,并以闭括号“}”结束。块可以包含其他块,而这些块又可以包含自己的块,依此类推。

让我们来看一个块的例子:

int main(void)
{
    /* 这是一个 '块' */
    int i = 5;

    {
        /* 这是另一个 '块',嵌套在外部块内 */
        int j = 6;
    }

    return 0;
}

你可以在前面的语句中使用块,例如主函数声明(以及我们尚未讨论的其他语句),但你也可以仅仅单独使用块。

空白符指的是分隔源代码中组成文本字符的制表符、空格符和换行符。
像生活中的许多事情一样,直到它消失了,才会意识到空白符的重要性。对于 C 编译器来说,源代码

printf("Hello world"); return 0;

与以下代码是一样的:

printf("Hello world");
return 0;

这两者与以下代码也相同:

printf (
"Hello world") ;

return 0;

编译器会忽略大多数空白符(例如,空白符并不会影响 return0 之间的分隔)。然而,通常情况下,我们使用空格(或制表符)来组织源代码,以提高人类可读性。

大多数时候,我们并不希望其他函数或程序员的代码访问我们正在操作的数据,这就是为什么理解作用域的概念很重要。

作用域描述了数据或函数可见的层次。在 C 中有两种作用域,局部作用域和全局作用域。当我们谈到全局作用域时,指的是可以从程序中的任何地方访问或操作的内容。局部作用域则适用于只能在声明它的块内访问或操作的程序元素。

让我们看一些例子,以更好地理解作用域。

int i = 5; /* 这是一个 '全局' 变量,可以从程序中的任何地方访问 */
 
/* 这是一个函数,里面的所有变量都是该函数的“局部”变量。 */
int main(void)
{
    int i = 6; /* 这是“局部”变量 'i',被赋值为 6 */
    printf("%d\n", i); /* 打印一个 '6' 到屏幕,而不是全局变量 'i' 的值 5 */

    return 0;
}

这展示了局部作用域与全局作用域的区别。那么,函数内部的不同作用域呢? (稍后你将了解函数的详细内容,现在先专注于“main”部分。)

/* 主函数 */
int main(void)
{
    /* 这是一个 '块' 的开始,你在上面已经阅读过这些内容 */

    int i = 6; /* 这是这个 '块' 中的第一个变量,'i' */

    {
        /* 这是一个新的 '块',因为它是不同的块,所以它有自己的作用域 */

        /* 这里同样是一个名为 'i' 的变量,但它位于不同的 '块' 中,
           因为它在不同的块中,所以它不会影响第一个名为 'i' 的变量! */
        int i = 5;
        printf("%d\n", i); /* 打印一个 '5' 到屏幕 */
    }
    /* 现在我们回到了第一个块 */

    printf("%d\n", i); /* 打印一个 '6' 到屏幕 */

    return 0;
}

函数的基本使用
函数是编程中的重要组成部分。函数是一种执行特定任务的特殊块。如果一个函数设计得好,它可以让程序员在不需要了解函数内部工作原理的情况下完成任务。请求函数执行其任务的动作称为函数调用。许多函数需要一个函数调用来传递执行任务所需的某些数据,这些数据被称为参数。许多函数在完成后还会返回一个值给函数调用,这个返回值称为返回值(上面程序中的返回值是 0)。

调用函数之前你需要知道的事项:

  • 函数执行的任务
  • 参数的数据类型(稍后讨论)及其含义
  • 返回值的数据类型及其含义

许多函数使用返回值来表示计算结果。一些函数使用返回值来指示它们是否成功完成了任务。正如你在引导练习中看到的那样,主函数使用返回值为操作系统提供退出状态。

除全局数据定义和声明外,所有代码都需要是函数的一部分。

通常,你可以随时调用一个函数。唯一的限制是,每个可执行程序需要有一个且只有一个主函数,它是程序开始执行的地方。

我们将在稍后的章节中更详细地讨论函数,具体内容参见《C 编程/过程与函数》。

标准库
1983年,当 C 语言正在成为标准化语言时,美国国家标准协会(ANSI)成立了一个委员会,制定了一个名为“ANSI C”的标准规范。该标准规范创建了一组在每个 C 实现中都通用的基本函数,这些函数被称为标准库。标准库提供了诸如输入/输出、字符串处理、数学运算、文件操作和内存分配等任务的函数。标准库不提供依赖于特定硬件或操作系统的函数,如图形、声音或网络等。在“Hello, World”程序中,使用了标准库中的一个函数(printf),它将文本输出到标准输出流。

Last modified: Sunday, 12 January 2025, 1:21 PM