第一章 程序设计和C语言

1.1 什么是计算机程序

计算机的每一个操作都是根据人们事先指定的指令进行的。
所谓程序,就是一组计算机能识别和执行的指令。每一条指令使计算机执行特定的操作。
一个特定的指令序列用来完成一定的功能。
总之,计算机的一切操作都是由程序控制的……所以,计算机的本质是程序的机器,程序和指令是计算机系统中最基本的概念。

1.2 什么是计算机语言

人和计算机交流信息也要解决语言问题。需要创造一种计算机和人都能识别的语言,这就是计算机语言。

计算机语言经历了以下几个发展阶段。

  • 机器语言

计算机工作基于二进制。从根本上说,计算机只能识别和接受由0和1组成的指令。
在计算机发展的初期,一般计算机的指令长度为16,即以16个二进制数(0或1)组成一条指令,16个0和1可以组成各种排列组合。
要使计算机知道和执行自己的意图,就要编写许多条由0和1组成的指令。然后要用纸带穿孔机以人工的方法在特制的黑色纸带上穿孔,在指定位置上有孔代表1,无孔代表0。一个程序往往需要一卷长长的纸带。在需要运行此程序时就将此纸带装在光电输入机上,当光电输入机从纸带读入信息时,有孔处产生一个电脉冲,指令变成电信号,让计算机执行各种操作。
这种计算机能直接识别和接受的二进制代码称为机器指令
机器指令的集合就是该计算机的机器语言。在语言的规则中规定各种指令的表现形式以及它的作用。

初期只有极少数的计算机专业人员会编写计算机程序。

  • 符号语言

它用一些英文字母和数字表示一个指令。

ADD代表 “加”
SUB代表 “减”
LD代表 “传送”

ADD A,B
—— 执行A+B => A,将寄存器A中的数与寄存器B中的数相加,放到寄存器A中。

计算机并不能直接识别和执行符号语言的指令,需要用一种称为汇编程序的软件把符号语言的指令转换为机器指令。
一般,一条符号语言的指令对应转换为一条机器指令。转换的过程称为 “代真” 或 “汇编” ,因此,符号语言又称为符号汇编语言或**汇编语言**。

仍然难以普及,只在专业人员中使用。

不同型号的计算机的机器语言和汇编语言是互不通用的。
机器语言和汇编语言是完全依赖于具体机器特性的,是面向机器的语言。

机器语言和汇编语言称为计算机低级语言

  • 高级语言

20世纪50年代创造出了第一个计算机高级语言——FORTRAN语言
这种语言功能很强,且不依赖于具体机器。
当然,计算机也是不能直接识别高级语言程序的,也要进行“翻译”。用一种称为编译程序的软件把用高级语言写的程序(称为源程序)转换为机器指令的程序(称为目标程序),然后让计算机执行机器指令程序,最后得到结果。高级语言的一个语句往往对应多条机器指令。

高级语言的出现为计算机的推广普及创造了良好的条件。

高级语言经历了不同的发展阶段:

  1. 非结构化的语言。
    编程风格随意,符合语法规则即可,流程可随意跳转。
    eg.BASIC,FORTRAN,ALGOL
  2. 结构化语言。
    “结构化程序设计方法”规定程序必须由具有良好特性的基本结构(顺序结构/选择结构/循环结构)构成,程序中的流程不允许随意跳转,程序总是由上而下顺序执行各个基本结构。
    优点:结构清晰,易于编写、阅读和维护。
    eg.QBASIC,FORTRAN 77,C语言

以上两种语言都是基于过程的语言,在编写程序时需要具体指定每一个过程的细节。

  1. 面向对象的语言
    eg.C++,C#,Visual Basic,Java
    程序面对的不是过程的细节,而是一个个对象,对象是由数据以及对数据进行的操作组成的。

1.3 C语言的发展及其特点

C语言既可用于编写应用软件,又可用于编写系统软件。

  1. C语言一共只有37个关键字、9种控制语句,程序书写形式自由,主要用小写字母表示,压缩了一切不必要的成分。
    C是一个很小的内核语言,只包括极少的与硬件有关的成分,C语言不直接提供输入和输出语句、有关文件操作的语句和动态内存管理的语句等(这些操作是由编译系统所提供的库函数来实现的),C的编译系统相当简洁。
  2. C语言的运算符包含的范围很广泛,共有34种运算符。C语言把括号、赋值和强制类型转换等都作为运算符处理。
  3. C语言提供的数据类型包括整形、浮点型、字符型、数组类型、指针类型、结构体类型和共用体类型等,C99又扩充了复数浮点类型、超长类型和布尔类型等。
    指针类型数据能用来实现各种复杂的数据结构(如链表、树、栈等)的运算。
  4. C语言具有结构化的控制语句。用函数作为程序的模块单位,便于实现程序的模块化。C语言是完全模块化和结构化的语言。
  5. 语法限制不太严格,程序设计自由度大。
    对变量的类型使用比较灵活,例如,整型量与字符型数据以及逻辑性数据可以通用。
  6. 允许直接访问物理地址,能进行位(bit)操作,能实现汇编语言的大部分功能,可以直接对硬件进行操作。因此C语言既具有高级语言的功能,又具有低级语言的许多功能,可用来编写系统软件。C语言的这种双重性,使它既是成功的系统描述语言,又是通用的程序设计语言。
  7. 用C语言编写的程序可移植性好。
    C编译系统在新的系统上运行时,可以直接编译“标准链接库”中的大部分功能,不需要修改源代码,因为标准链接库是用可移植的C语言写的。
    因此,几乎在所有的计算机系统中都可以使用C语言。
  8. 生成目标代码质量高,程序执行效率高。
    硬件控制能力高,表达和运算能力强。
    目前C的主要用途之一是编写嵌入式系统程序。

1.4 最简单的C语言程序

1.4.1 最简单的C语言程序举例

【例1.1】 要求在屏幕上输出以下一行信息。
This is a C program.
思路:在主函数中用 printf 函数原样输出以上文字。
程序

# include<stdio.h>
int main()
{
 printf("This is a C program.\n");
 return 0;
}

结果

分析

  1. main 是函数的名字,表示 “主函数” ,main 前面的 int 表示此函数的类型是 int 类型(整型)。在执行主函数后会得到一个值(即函数值),其值为整型。
    return 0 ; ” 的作用是:当 main 函数执行结束前将整数 0 作为函数值,返回到调用函数=处。每一个C语言程序都必须有一个 main 函数。
    函数体由花括号 { } 括起来。
    \ n 是换行符,即在输出 " This is a C progrm. " 后,显示屏上的光标位置移到下一行的开头。这个光标位置称为输出的当前位置,即下一个输出的字符出现在此位置上。
    每个语句最后都有一个分号,表示语句结束。
  2. 在使用函数库中输入输出函数,编译系统要求程序提供有关此函数的信息(例如对输入输出函数的声明和宏的定义、全局量的定义等),“ # include <stdio.h> ” 的作用就是用来提供这些信息的。
    stdio.h 是系统提供的一个文件名,stdio 是 standard inout & output 的缩写,文件后缀 .h 的意思是头文件(header file),因为这些文件都是放在程序各文件模块的开头的。
    输入输出函数的相关信息已事先放在 stdio.h 文件中。现在,用 # include 指令把这些信息调入供使用。如果没有此 # include 指令,就不可能执行 printf 函数。
    # include :编译预处理指令
  3. 在以上程序各行的右侧,如果有 // ,则表示从此处到本行结束是 “ 注释 ” ,用来对程序有关部分进行必要的说明。
    在程序进行预编译处理时将每个注释替换为一个空格,因此在编译时注释部分不产生目标代码,注释对运行不起作用。

说明:C语言允许用两种注释方式:

  1. 以 // 开始,以换行符结束的单行注释,不能跨行,如果注释内容一行写不下可以用多个单行注释。
  2. 以 / * 开始,以 * / 结束的块式注释,可以包含多行内容。
  3. 字符串中的 // 和 / * 都不作为注释的开始,而是作为字符串的一部分。如:
    printf(" // how do you do ! \ n");

    printf(" / * how do you do ! * / \ n");
    输出分别是:
    // how do you do !

    / * how do you do ! * /
    注释可以用汉字或英文字符表示。

【例1.2】 求两个整数之和。
思路:设置3个变量,a 和 b 用来存放两个整数,sum 用来存放和数。用赋值运算符 “ = ” 把相加的结果传送给 sum。
程序

# include<stdio.h>
int main()
{
 int a,b,sum;
 a=123;
 b=456;
 sum=a+b;
 printf("sum is %d\n",sum);
 return 0;
}

结果

分析

  1. 第 4 行是声明部分,定义 a,b 和 sum 为整型(int)变量。
    第 5,6 行是两个赋值语句。
  2. printf 函数圆括号内有两个参数。第一个参数是双撇号中的内容 sum is %d \ n,它是输出格式字符串,作用是输出用户希望输出的字符和输出的格式。其中 sum is 是用户希望输出的字符,%d 是指定的输出格式,d 表示用 “ 十进制整数 ” 形式输出。
    圆括号内第二个参数 sum 表示要输出变量 sum 的值。在执行 printf 函数时,将 sum 变量的值(以十进制整数表示)取代双撇号中的 %d 。

程序正常运行和结束,main 函数的返回值应为 0。

【例1.3】 求两个整数中的较大者。
思路:用一个函数实现求较大者,在主函数中调用此函数并输出结果。
程序

# include<stdio.h>
int main()
{
 int max(int x,int y);
 int a,b,c;
 scanf("%d,%d",&a,&b);
 c=max(a,b);
 printf("max=%d\n",c);
 return 0;
}
int max(int x,int y)
{
 int z;
 if(x>y)z=x;
 else z=y;
 return(z);
}

结果

分析

  1. “&” 是地址符,&a 的含义是 “ 变量 a 的地址 ”。
  2. 程序第 8 行用 max(a,b) 调用 max 函数。在调用时将 a 和 b 作为 max 函数的参数(称为实际参数)的值分别传送给 max 函数中的参数 x 和 y(称为形式参数),然后执行 max 函数的函数体,使 max 函数中的变量 z 得到一个值。
    return(z) 的作用是把 z 的值作为 max 函数值带回到程序第 8 行 “ = ” 的右侧。

1.4.2 C语言程序的结构

  1. 一个程序由一个或多个源程序文件组成
    在一个源程序文件中可以包括 3 个部分:
    (1)预处理指令
    # include<stdio.h>
    # define
    (2)全局声明
    例如可以把【例1.2】程序中的 “ int a,b,sum; ”放到 main 函数的前面,这就是全局声明,在函数外面声明的变量称为全局变量。如果是在程序开头(定义函数之前)声明的变量,则在整个源程序文件范围内有效
    (3)函数定义

  2. 函数是C程序的主要组成部分
    函数是C程序的基本单位,一个C程序是由一个或多个函数组成的,其中必须包含一个 main 函数(且只能有一个 main 函数)。
    一个源程序文件就是一个程序模块,再进行编译时是以源程序文件为对象进行的。
    在程序中被调用的函数,可以是系统提供的库函数,也可以户根据需要自己编制设计的函数。

  3. 一个函数包括两个部分
    (1)函数首部
    即函数的第 1 行,包括函数名、函数类型、函数属性、函数参数(形式参数)名、参数类型。
    一个函数名后面必须跟一对圆括号,括号内写函数的参数名及其类型。如果函数没有参数,可以在括号中写 void ,也可以是空括号,如:
    int main(void)

    int main()
    (2)函数体
    即函数首部下面的花括号内的部分。如果在一个函数中包括有多层花括号,则最外层的一对花括号是函数体的范围。
    函数体一般包括以下两部分。

    • 声明部分
      声明部分包括:定义在本函数中所用到的变量。
    • 执行部分
      由若干个语句组成,指定在函数中所进行的操作。
      在某些情况下也可以没有声明部分,甚至可以既无声明部分也无执行部分。如:
      void dump()
      {}
      是一个空函数,什么也不做,但这是合法的。
  4. 程序总是从 main 函数开始执行的,而不论 main 函数在整个程序中的位置如何

  5. 程序中要求计算机完成的操作是由函数中的C语句完成的

  6. 在每个数据声明和语句的最后必须有一个分号。分号是C语句的必要组成部分。

  7. C语言本身不提供输入输出语句
    输入和输出的操作是由库函数 scanf 和 printf 等函数来完成的。C语言对输入输出实行 “ 函数化 ”。

  8. 程序应当包含注释

1.5 运行C程序的步骤与方法

步骤

  1. 上机输入和编辑源程序
    将编写好的源程序以文件形式存放在自己指定的文件夹内(如果不特别指定,一般存放在用户当前目录下),文件用 .c 作为后缀,生成源程序文件,如 f.c。
  2. 对原程序进行编译
    编译的作用首先是对源程序进行检查,判定它有无语法方面的错误。
    编译程序将自动把源程序转换为二进制形式的目标程序(在 Visual C++ 中后缀为 .obj,如 f.ojb)。
    此时源文件没有消失。
    在用编译系统对源程序进行编译时,自动包括了预编译和正式编译两个阶段。
  3. 进行连接处理
    把所有的编译后得到的目标模块连接装配起来,再与函数库相连接成一个整体,生成一个可供计算机执行的目标程序,称为可执行程序,在 Visual C++ 中其后缀为 .exe,如 f.exe。
  4. 运行可执行程序,得到运行结果

1.6 程序设计的任务

从确定问题到最后完成任务,一般经理以下几个工作阶段

  1. 问题分析
  2. 设计算法
  3. 编写程序
  4. 对原程序进行编辑、编译和连接,得到可执行程序
  5. 运行程序,分析结果
  6. 编写程序文档

注:此文档中引用的内容皆来自《C程序设计(第五版)》(谭浩强 著),是对该书内容所作的局部复刻,用于交流和学习,请勿转载。

更多推荐

新手入门 C程序设计 C++ 统计学科目(大一)C程序设计(第五版)谭浩强 第一章知识学习 程序设计和C语言