C primer plus - 第1章:C语言概述

270 阅读7分钟

1、初识C语言

1.1、C语言的起源

1972年,贝尔实验室的丹尼斯·里奇和肯·汤普逊在开发UNIX操作系统时设计了C语言。(在B语言基础上) C语言设计的初衷是将其作为程序员使用的一种编程工具。

1.2、选择C语言的理由

1、设计特性

  • C语言的设计理念让用户能轻松地完成自顶向下的规划、结构化编程和模块化设计。
  • 用C编写的程序更易懂、更可靠。

2、高效性

C是高效的语言。C程序紧凑、运行速度快。具有汇编语言的微调控制能力。

3、可移植性

在一种系统中编写的C程序几乎不用修改就能在其他系统上运行。

4、强大而灵活

C语言功能强大且灵活(计算机领域经常使用这两个词)。例如,功能强大且灵活的UNIX操作系统,大 部分是用C语言写的;其他语言(如, FORTRAN、Perl、 Python、 Pascal、 LISP、Logo、BASIC) 的许多 编译器和解释器都是用C语言编写的。

5、面向程序员

6、缺点

C语言使用指针,容易出现难以发现的错误。

1.3、C语言标准

  • 1989 年 ANSI C 标准 定义了C语言和C标准库 (通常称作C89标准或C90标准)
  • 1994 年 C99
  • 2011 年 C11 但是这个标准并不是所有编译器都支持。
  • 每一代标准都有一些不同,但差别不大。

1.4、使用C语言的7个步骤

  1. 定义程序的目标

  2. 设计程序

  3. 编写代码

  4. 编译

    1. 前面介绍过,编译器是把源代码转换成可执行代码的程序
    2. C编译器负责把C代码翻译成特定的机器语言。
    3. 此外,C编译器还将源代码与C库(库中包含大量的标准函数供用户使用,如printf() 和scanf())的代码合并成最终的程序
    4. 更精确地说,应该是由一个被称为链接器的程序来链接库函数,但是在大多数系统中,编译器运行链接器。
    5. 其结果是,生成一个用户可以运行的可执行文件.exe,其中包含着计算机能理解的代码。
    6. 编译器还会检查C语言程序是否有效。如果C编译器发现错误,就不生成可执行文件并报错。
  5. 运行程序

  6. 测试和调试

  7. 维护和修改代码

  8. 说明

编程并非是像上述1~7那样的线性过程,有时要在不同步骤间往复。(比如测试时发现编写的思路有问题,就可能要重新分析问题)

1.5、编程机制

  • .c:源文件
  • .h:头文件

C编程的基本策略是,用程序把源代码文件转换为可执行文件(其中包含可直接运行的机器语言代码)。典型的C实现通过编译和链接两个步骤来完成这一过程。

  • 编译器把源代码转换成中间代码
  • 链接器把中间代码和其他代码(库代码、启动代码)合并,生成可执行.exe文件。

C使用这种分而治之的方法方便对程序进行模块化,可以独立编译单独的模块,稍后再用链接器合并(装载) 已编译的模块。通过这种方式,如果只更改某个模块,不必因此重新编译其他模块。另外,链接器还将你编写的程序和预编译的库代码合并。

image.png

2、C语言入门介绍

2.1、简单的C程序示例

first.c 程序

#include <stdio.h>
int main(void)                /*一个简单的C程序*/
{
    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;
}

打印结果:

I am a simple computer.
My favorite number is 1 because it is first.

注意: 我是在CLion下写的这个程序。另外,如果程序运行时一闪而过,可以在return 0;语句前面加一句getchar(); 意思是可以让程序等待按下一个按键后窗口才关闭。

2.2、示例解释

image.png

2.3、简单程序的结构

  • 程序由一个或多个函数组成。
  • 必须有main函数(main是入口函数,可以认为程序从main函数开始)
  • 函数由函数头 和 函数体组成。
  • 函数头格式为 返回值类型 函数名(需要传入的参数)
  • 函数体格式是{ …} 即花括号括起来的一些语句

image.png

一般的简单C程序格式如下:

#include<stdio.h>
Int main(void){
    语句
    return 0;
}

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

  1. 选择有意义的函数名和变量名,特别是程序较大时,尽量给变量和函数起个好名字,不会混淆
  2. 合理的注释
  3. 用空行分隔概念上的多个部分
  4. 每条语句独占一行

2.5、进一步使用C

// fathm_ft.c -- 把2英寻转换成英尺 
#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; 
}

2.5.1、多条声明

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

int feet, fathoms;

int feet;
int fathoms;

等价

2.6、多个函数

一个程序可以包含多个函数,也可以包含自己定义的函数。

/* two_func.c -- 一个文件中包含两个函数 */ 
#include <stdio.h> 
void butler(void); /* ANSI/ISO C函数原型 */ 
int main(void) { 
    printf("I will summon the butler function.\n"); 
    butler(); //调用butler函数
    printf("Yes. Bring me some tea and writeable DVDs.\n"); 
    
    return 0; 
} 

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

结果如下:

I will summon the butler function. 
You rang, sir? 
Yes. Bring me some tea and writeable DVDs.

butler()函数在程序中出现了 3次:

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

C标准建议, 要为程序中用到的所有函数提供函数原型。标准include 文件(包含文 件)为标准库函数提供了函数原型。例如,在C标准中,stdio.h文件包含了printf()的函数原型。第6章最后一个示例演示了如何使用带返回值的函数,第9章将详细全面地介绍函数。

2.7、调试程序(debug)

有两种常见的错误:语法错误 和 逻辑错误,不要忘记每一句最后的分号

定位错误的常用办法:

  • 在关键点插入 printf(),打印当前值

  • ide的debug

2.8、关键字和保留标识符

关键字是C语言的词汇。它们对C而言比较特殊,不能用它们作为标识符(如,变量名)。许多关键字用于指定不同的类型,如int。 还有一些关键字 (如if)于控制程序中语句的执行顺序。在表2.2 中所列的C语言关键字中, 粗体表示的是C90 标准新增的关键字,斜体表示的C99 标准新增的关键字 ,粗斜体表示的是C11 标准新增的关键字。

image.png

如果使用关键字不当(如,关键字作为变量名),编译器 会将其视为语法错误。还有 一些保留标识符(reserved identifier),C语言已经指定了它们的用途或保留它们的使用 权,如果你使用这些标识符来表示其他意思会导致一些问题。因此,尽管它们也是有效的名称,不会引|起语法错误,也不能随便使用。保留标识符包括那些以下划线字符开头的标识符和标准库函数名,如printf()。