C 编程/预备知识
在学习 C 语法和编程结构之前,了解一些理解 C 的核心术语非常重要。
接下来,我们将讨论 C 程序的**基本结构**。如果您熟悉 PASCAL,您可能听说过它被称为**块结构**语言。C 没有完全的块结构(当您详细了解函数时,您将了解原因),但了解块是什么以及如何使用它们仍然非常重要。
那么**块**里面有什么?一般来说,块由可执行的**语句**组成。
但在深入了解块之前,让我们先检查一下语句。描述语句的一种方式是,它们是编译器将尝试将其转换为可执行指令的文本(以及周围的空白)。更简单的定义是,语句是执行某些操作的代码片段。例如
int i = 6;
这**声明**了一个整型变量,可以使用**标识符** 'i' 来**访问**它,并将其**初始化**为值 6。各种数据类型在变量 一章中介绍。
您可能已经注意到语句末尾的分号。C 中的语句总是以分号 (;) 结尾。遗漏分号是许多人(包括初学者和专家)常犯的错误!因此,在它成为第二天性之前,请务必仔细检查您的语句!
由于 C 是一种“自由格式”语言,因此多个语句可以在源文件中的同一行共享,例如
/* this declares the variables 'i', 'test', 'foo', and 'bar'
note that ONLY the variable named 'bar' is initialized to six! */
int i, test, foo, bar = 6;
有几种类型的语句。您已经看到其中一些,例如赋值(i = 6;
)。本书的很大一部分内容都涉及语句的构造。
回到我们对块的讨论。在 C 中,块以左花括号开始"{"并以右花括号结束"}". 块可以包含其他块,这些块可以包含它们自己的块,等等。
让我们看一个块的例子。
int main(void)
{
/* this is a 'block' */
int i = 5;
{
/* this is also a 'block', nested inside the outer block */
int j = 6;
}
return 0;
}
您可以将块与前面的语句一起使用,例如主函数声明(以及我们尚未介绍的其他语句),但您也可以单独使用块。
**空白**指的是用于分隔构成源代码的文本字符的制表符、空格和换行符。
就像生活中很多事情一样,在它消失之前很难体会空白。对于 C 编译器来说,源代码
printf("Hello world"); return 0;
与
printf("Hello world");
return 0;
相同,也与
printf (
"Hello world") ;
return 0;
相同。编译器只是忽略了大多数空白(除了例如分隔return
和 0
的情况)。但是,通常使用空格(或制表符)来组织源代码以提高人类可读性。
大多数情况下,我们不希望其他函数或其他程序员的 例程 访问我们当前正在操作的数据,这就是为什么了解作用域概念很重要。
**作用域**描述了数据片段或函数可见的级别。C 中有两种作用域,**局部**和**全局**。当我们谈到**全局**作用域时,我们指的是可以在程序中的任何位置看到或操作的东西。**局部**作用域适用于仅在声明它的块内可见或可操作的程序元素。
让我们看一些例子来更好地了解作用域。
int i = 5; /* this is a 'global' variable, it can be accessed from anywhere in the program */
/* this is a function, all variables inside of it
are "local" to the function. */
int main(void)
{
int i = 6; /* "local" 'i' is set to 6 */
printf("%d\n", i); /* prints a '6' to the screen, instead of the global variable of 'i', which is 5 */
return 0;
}
这展示了局部和全局的示例。但是,不同作用域在函数**内部**呢?
(您将在后面了解有关函数的更多信息,现在只关注“main”部分。)
/* the main function */
int main(void)
{
/* this is the beginning of a 'block', you read about those above */
int i = 6; /* this is the first variable of this 'block', 'i' */
{
/* this is a new 'block', and because it's a different block, it has its own scope */
/* this is also a variable called 'i', but in a different 'block',
because it's in a different 'block' than the first variable named 'i', it doesn't affect the first one! */
int i = 5;
printf("%d\n", i); /* prints a '5' onto the screen */
}
/* now we're back into the first block */
printf("%d\n", i); /* prints a '6' onto the screen */
return 0;
}
**函数**是编程的重要组成部分。函数是一种特殊的块,它执行一个定义明确的任务。如果一个函数设计得当,它可以使程序员能够执行一项任务,而无需了解该函数的工作原理。请求函数执行其任务的行为称为**函数调用**。许多函数需要函数调用来传递它执行其任务所需的部分数据;这些被称为**参数**。许多函数在完成时也会向函数调用返回一个值;这被称为**返回值**(上述程序中的返回值是**0**)。
在调用函数之前,您需要知道以下内容
- 函数的作用
- 参数的数据类型(稍后讨论)以及它们的含义
- 返回值的数据类型以及它的含义
许多函数使用返回值来表示计算结果。有些函数使用返回值来指示它们是否成功完成了工作。正如您在简介练习中所见,main
函数使用返回值向操作系统提供退出状态。
除全局数据定义和声明之外的所有代码都必须是函数的一部分。
通常,您可以随时自由地调用函数。唯一的限制是每个可执行程序都必须有一个且只有一个**main** 函数,该函数是程序开始执行的地方。
我们将在后面的章节中更详细地讨论函数,C 编程/过程和函数。
1983 年,当 C 正在标准化的过程中,美国国家标准协会 (ANSI) 成立了一个委员会来制定 C 的标准规范,称为“ANSI C”。该标准规范创建了一组每个 C 实现都共有的基本函数集,称为 标准库。标准库提供用于输入/输出、字符串操作、数学、文件和内存分配等任务的函数。标准库不提供依赖于特定硬件或操作系统的函数,例如图形、声音或网络。在“Hello, World”程序中,使用了一个标准库函数(printf
),它将文本行输出到 标准输出 流。