02. C语言概述

一、简单的C程序实例

#include <stdio.h>

/* 一个简单的C程序 */
int main(void)  
{
    int num;                    /* 定义一个名为num的变量 */
    num = 1;                    /* 为num赋一个值 */

    printf("I am a simple ");   /* 使用printf()函数 */
    printf("computer.\n");
    printf("My favorite number is %d because it is first.\n", num);

    return 0;
}

如果程序的输出窗口在屏幕上一闪而过,我们可与在 return 语句前加一个 getchar(); 语句,这行代码会让程序等待输入,窗口会在用户按下一个键后才关闭;

二、示例解释

2.1、快速概要

#include <stdio.h>

  该行告诉编译器把 stdio.h 中的内容包含在当前程序中。stdio.h 是 C 编译器软件包的标准部分,它提供键盘输入和屏幕输出支持。

int main(void)

  C 程序中包含一个或多个 函数,它们是 C 程序的 基本模块。上述程序中有一个名为 main() 的函数。圆括号表示 main() 是一个函数名。int 表示 main() 函数返回一个整数。void 表示 main() 不带任何参数。main() 函数是 C 程序的入口函数。

/* 一个简单的C程序 */

  多行注释在 /* 和 */ 两个符号之间,单行注释在 // 之后,这些注释能提高程序的可读性。注释只是为了帮助读者理解程序,并不会参与程序的编译和运行,编译器会忽略它们。

{}

  左花括号({) 表示 函数定义开始右花括号(}) 表示 函数定义结束

int num;

  该语句是一个声明语句,表示将使用一个名为 num 的变量,而且 num 是 int(整型)类型。

num = 1;

  该语句是一个赋值语句,表示把值 1 赋值给名为 num 的变量。

printf("I am a simple ");

  该语句使用 printf() 函数,在屏幕上显示 “I an a simple ”,光标停在一行。printf() 是标准的 C 库函数。在程序中使用函数叫做 调用函数

printf("computer.\n");

  接下来调用的 printf() 函数在上条语句打印出来的内容后面加上 “computer”。代码 \n 告诉计算机另起一行,即把光标移至下一行。

printf("My favorite number is %d because it is first.\n", num);

  最后调用的 printf() 函数把 num 的值(1)内嵌在用说引号括起来的内容中一并打印。%d 告诉计算机以何种形式输出 num 的值,打印在何处。

return 0;

  C 函数可以给调用方提供(或返回)一个数。

2.2、程序细节

2.2.1、#include指令和头文件

#include <stdio.h>

  这是程序的第一行,#include <stdio.h> 的作用相当于把 stdio.h 文件中的所有内容都输入该行所在的位置。实际上,这是一种 “拷贝—粘贴” 的操作。#include 文件提供了一种方便的途径通向许多程序的共有信息。

  #include 这行代码是一条 C 预处理指令(preprocessor directive)。通常,C 编译器都提供 stdio.h 文件。该文件中包含了共编译器使用的输入和输出函数信息。该文件名的含义是 标准输入/输出头文件。通常,在 C 程序顶部的信息的集合被称为 头文件(header)。在大多数情况下,头文件包含了编译器创建最终可执行程序要用到的信息。

2.2.2、main()函数

int main(void)

  main() 函数是 C 程序的入口函数。一个 C 程序有且只有一个 main() 函数。int 是 main() 函数的返回值,这表明 main() 函数返回的值是整数。这个整数值会返回给操作系统。通常,函数名后面的圆括号中包含一些传入的信息。该示例中没有传递任何信息。因此,圆括号内是单词 void。

  如果是旧式的 C 代码,会发现 main() 函数如下书写:

main()

  C90 标准勉强接受这种形式,但是 C99 和 C11 标准不允许这样写。

  有时,我们还会看会如下格式:

void main()

  一些编译器允许这样写,但是所有的标准都未认可这种写法。

2.2.3、注释

/* 一个简单的C程序 */

  在程序中,被 /**/ 两个符号括起来的部分是程序的注释。写注释能让他人(包括自己)更容易明白你所写的程序。C 语言注释的好处之一是,可将注释放在任意的地方,这是是与要解释的内容在同一行。较长的注释可以单独放一行或多行。在 /**/ 之间的内容都会被编译器忽略。

  C99 新增了另一种风格的注释,普遍用于 C++ 和 Java。这种新风格使用 // 符号创建注释,仅限于单行。

// 这种注释只能写一行

  因为一行末尾就标志的注释的结束,所以这种风格的注释值需要在注释开始处表名 // 符号即可。

多行注释不能嵌套使用;

2.2.4、花括号、函数体和块

{
    // 函数体
}

  花括号把 main() 函数括起来。一般而言,所有的 C 函数都使用花括号标记函数体的开始和结束。花括号还可以用于把函数中的多条语句合并为一个单元或块。

2.2.5、声明

int num;

  在该示例中声明完成了两件事。其一,在函数中有一个名为 num 的变量(variable)。其二,int 表明 num 是一个整数(即,没有小数点或小数部分的数)。int 是一种数据类型。编译器使用这些信息为 num 变量在内存中分配存储空间,分号在 C 语言中式大部分语句和声明的一部分。

  int 是 C 语言的一个关键字(keyword),它表示一种基本的 C 语言 =数据类型。关键字是语言定义的单词,不能用做其它用途。

  示例中 num 是一个标识符(idenfifier),也就是一个 变量、函数 或 其它实体 的名称。因此,声明把特定标识符与计算机内存中的特定位置联系起来,同时也确定了存储在某位置的信息类型或数据类型。

  在 C 语言中,所有的变量都必须声明才能使用。这意味着必须列出程序中用到的所有变量名及其类型。

  在以前的 C 语言,还要求把变量声明在块的顶部,其它语句不能再任何声明的前面。也就是说,main() 函数体如下:

int main(void)
{
    int doors;
    int dogs;
    doors = 5;
    dogs = 3;
    // 其它语句
}

  C99 和 C11 遵循 C++ 的惯例,可以把声明放在块中的任何位置。尽管如此,首次使用变量之前一定要先声明它。

int main(void)
{
    // 一些语句
    int doors;
    doors = 5;		// 第一次使用doors
    // 其它语句
    int dogs;
    dogs = 5;		// 第一次使用dogs
    // 其它语句
}

  C99 和 C11 允许使用更长的标识符名,但是编译器只识别前 63 个字符。对于外部标识符,只允许使用 31 个字符。(以前的 C90 只允许 6 个字符,就是编译器通常最多只允许使用 8 个字符)。实际上,你可以使用更长的字符,但是编译器会忽略超出的字符。也就是说,如果有两个标识符都有 63 个字符,只有一个字符不同,那么编译器会识别这是两个不同的名称。如果两个标识符都是 64 个字符,只有最后一个字符不同,那么编译器可能将其视为同一个名称,也可能不会。标准并为定义在这种情况下会发生什么。

  标识符可以使用 小写字母大写字母数字下划线(_)来命名,标识符的 第一个字符 必须是 字符下划线,不能是数字。操作系统和 C 库经常使用以一个或两个下划线字符开始的标识符。这样的标识符都是保留的。这意味着,虽然使用它们没有语法错误,但是会导致名称冲突。

  为了让 C语言 更加国际化,C99 和 C11 根据通用字符名(即 UCN)机制扩展字符集。其中包含了除英文字母以外的部分字符。

2.2.6、赋值

num =1;

  该代码的意思是 “把值 1 赋给变量 num”。在执行 int num; 声明时,编译器在计算机内存中为变量 num 预留了空间,然后在执行这行赋值表达式语句时,把值存储在之前预留的位置。可以给 num 赋不同的值,这就是 num 值之所以被称为 变量(variable)的原因。该赋值表达式从左侧把值赋给左侧。另外,该语句以分号结尾。

2.2.7、printf()函数

printf("I am a simple ");
printf("computer.\n");
printf("My favorite number is %d because it is first.\n", num);

  这 3 行都使用了 C语言 的一本标准函数:printf() 函数。圆括号表明 printf 是一个函数名。圆括号的内容是从 main() 函数传递给 printf() 函数的信息。(在 C 语言中,实际参数(简称实参)是传递函数的特定值,形式参数(简称形参)是函数中用于存储的变量)。

  第一行 printf() 演示了在 C 语言中如何调用函数。只需要输入函数名,把所需的参数填入圆括号即可。当程序运行到这一行时,控制权被转给以命名的函数(该示例中是 printf() 函数)。函数执行结束后,控制权被返回至 主调函数(calling function),该示例是 main()。

  第二行 printf() 函数的双引号中的 \n 字符并未输出。这是因为 \n 组合(依次输入这两个字符)代表一个 换行符(newline character)。对于 printf() 而言,它的意思就是 “在下一行的最左边开始新的一行”。也就是说,打印换行符的效果与键盘按下 Enter 键相同。如果我们在 printf() 函数中直接使用 Enter 键,编译器可能会认为这是直接的命令,而不是存储在源代码中的指令。换句话说,如果直接按下 Enter 键,编译器会退出当前行并开始新的一行。如果使用 \n 换行符,仅会影响程序输出的显示格式。

  换行符是一个 转义序列(escapse sequence)。转义序列用以表示难以表示或无法输入的字符。如,\t 代表 Tab 键,\b 代表 Backspace 键(退格键)。每个 转义序列 都以 反斜杠(|)开始。

  第三行 printf() 函数参数中的 %d 被 数字 1 代替了,而 1 就是变量 num 的值。%d 相当于是一个占位符,其作用是指明输出 num 值的位置。% 提醒程序,要在该处打印一个变量,d 表示把变量作为十进制整数打印。printf() 函数名中的 f 提醒用户,这是一个格式化打印函数。

2.2.8、return语句

return 0;

  int main(void) 中的 int 表明 main() 函数应返回一个整数。C 标准要求 main() 这样做。有返回的 C 函数要有 return 语句。该语句以 return 关键字开始,后面是带返回的值,并以分号结尾。

三、简易程序的结构

  程序由一个或多个函数组成,必须有 main() 函数。函数 由 函数头 和 函数体 组成。函数头 包括 函数名、传入该函数的信息类型 和 函数的返回类型。通常函数名后的圆括号可识别除函数,圆括号里可能为空,可能有参数。函数体被花括号括起来,由一系列语句、声明组成。

大部分程序都以分号结尾;

四、提高程序可读性的技巧

  • 选择有意义的函数名和写注释
  • 在函数中用空行分隔概念上的多个部分
  • 每条语句各占一行

分号告诉编译器一条语句在哪里结束、下一条语句在哪里开始;

五、进一步使用C

#include <stdio.h>

int main(void)
{
    int feet, fathoms;

    fathoms = 2;
    feet = 6 * fathoms;
    printf("There are %d feet in %d fathoms!\n", feet, fathoms);
    printf("Yes ,I said %d feet!\n", 6 * fathoms);

    return 0;
}

  程序在一条声明中声明了两个变量,而不是一个变量。为此,要在声明中用逗号隔开两个变量。也就是说,

int feet, fathoms;

int feet;
int fathoms;

等价。

  程序的第 1 个 printf() 函数进行了两次替换。双引号后面的第 1 个变量(feet)替换了双引号中的第 1 个 %d。双引号后面的第 2 个变量(fathoms)替换了双引号中的第 2 个 %d。待输出的变量列于双引号的后面,变量之间要用逗号隔开。

  第 2 个 printf() 函数说明待打印的值不一定是变量,只要可求值得出合适类型的项即可。

六、多个函数

#include <stdio.h>

void butler(void);              /* ANSI/ISO C 函数原型  */

int main(void)
{
    printf("I will summon the butler function.\n");
    butler();
    printf("Yes. Bring me some tea and writeable DIVDS.\n");

    return 0;
}

/* 函数定义开始  */
void butler(void)
{
        printf("You rang, sir?\n");
}

  butler() 函数出现了 3 次。第 1 次是 函数原型(prototype),告诉编译器在程序中要使用该函数。第 2 次以 函数调用(function call)的形式出现在 main() 函数中。最后一次出现在 函数定义(function definition)中,函数定义即是函数本身的源代码。

  C90 标准新增了函数原型,旧式的编译器可能会无法识别。函数原型 是一种声明形式告诉编译器正在收用某函数,因此函数原型也被称为 函数声明(function declaration)。函数原型还指明了函数的属性。例如,butler() 函数原型中第 1 个 void 表明,butler() 函数没有返回值(通常,被调函数会向主函数返回一个值)。第 2 个 void 的意思是 butler() 函数不带参数。因此,编译器运行到此,会检查 bulter 是否使用得当。

  在 main() 中调用 butler() 很简单,写出函数名和圆括号即可。当 butler() 执行完毕后,程序会继续执行 main() 中的下一条语句。

  何时执行 butler() 函数取决于它在 main() 中被调用的位置,而不是 butler() 的定义在文件中的位置。例如,把 butler() 函数的定义放在 main() 定义之前,不会改变程序的执行顺序,butler() 函数仍在两次 printf() 调用之间被调用。无论 main() 函数在程序处于什么位置,所有的 C程序 都从 main() 开始执行。

C 标准建议,要为程序用到的所有函数提供函数原型,标准 include 文件(包含文件)为标准库函数提供了函数原型;

posted @ 2023-02-15 13:01  星光映梦  阅读(140)  评论(0编辑  收藏  举报