第一章 程序设计和C语言

1.1 什么是计算机程序


程序
一组计算机能识别和执行的指令

1.2 什么是计算机语言


机器指令
计算机能直接识别和接受的二进制代码
机器语言
机器指令的集合

机器语言的优缺点:

  • 运行速度快,能充分发挥机器的性能
  • 难学,难写,难记,难检查和修改
  • 不同机器的指令不同

1.2.1 机器语言

1.2.1 机器语言

1.2.1 机器语言

1.2.1 机器语言

1.2.2 汇编语言


符号语言(symbolic language): 用一些英文字母(单词)和数字来表示一个指令。

计算机不能直接识别符号语言,必须经过编译器(compiler)编译(compile)为机器语言指令,计算机才能识别和运行。

因此,符号语言又称为汇编语言(assembler language)

ADD A, B (A寄存器中的数和B寄存器中的数相加,结果放回A中)

1.2.2 汇编语言


汇编语言的优缺点:

  • 基本上和机器语言一一对应,所以依然运行速度快,能充分发挥机器的性能
  • 比机器语言指令稍好记一点,但不好移植,不同机器不同指令
  • 一些复杂算法不好实现,不适合编写大型的程序(人和机器的思维不同)

1.2.3 高级语言


高级语言(high level language): 用人们习惯的自然语言和数学语言,一般不依赖具体的机器。

计算机不能直接识别高级语言,必须经过编译器(compiler)编译(compile)为机器语言指令,计算机才能识别和运行。

有时,编译好的机器语言代码还需要链接(link)其他的机器语言代码,组成最终的机器语言代码进行运行。

1.2.3 高级语言


高级语言例子:用参数方程绘制圆

angle = 0
radius = 50
while angle < 360 do :
  x = radius * sin ( angle * PI / 180.0 )
  y = radius * cos ( angle * PI / 180.0 )
  plot ( x, y)
  angle = angle + 10

1.2.3 高级语言--优点和缺点


  • 不同机器上可以有不同的编译器编译为各自的机器语言指令,可移植性较好
  • 可以一条语句编译为多条指令,编程效率高,也可以实现复杂算法和大型程序的组织
  • 由于不是一一对应机器语言指令,编译不好的程序可能运行效率比较低

1.2.3 高级语言--种类


  • 静态(编译)语言:在运行前先经过编译和链接转换为机器语言程序,如C, C++等
  • 动态(编译)语言:在运行的时候边编译为机器语言指令边运行,也称为脚本语言, 如 javascript, python, ruby等
  • 中间(编译)语言:在运行前先经过编译和链接转换为中间语言程序(字节码),在运行的时候才编译为机器语言运行,如java, C#等

1.3 C语言的发展及其特点

1.3.1 BCPL语言


1967年,英国剑桥大学 Martin Richards。

BCPL
GET "LIBHDR"
LET START() = VALOF $(
   FOR I = 1 TO 5 DO
      WRITEF("%N! = %I4*N", I, FACT(I))
      RESULTIS 0
$)
AND FACT(N) = N = 0 -> 1, N * FACT(N - 1)

1.3.2 B语言


1970年,美国AT&T Ken Thompson。

B
printn(n, b) {
    extrn putchar;
    auto a;

    if (a = n / b)        /* assignment, not test for equality */
            printn(a, b); /* recursive */
    putchar(n % b + '0');
}

1.3.3 C语言


1972-1973年,美国AT&T Dennis Ritchie

#include <stdio.h>

int main(void)
{
    printf("hello, world\n");
}

1.3.4 开发C语言的目的


  • 提供多种数据类型并提供静态的检查
  • 降低对平台的依赖,具有很好的移植性

1.3.5 C语言的应用和发展


  • 1969, Ken Thompson 和 Dennis Ritchie 用汇编语言开发UNIX第一版
  • 1973, Dennis Ritchie 发明C语言
  • 1973, Ken Thompson 和 Dennis Ritchie 用C语言重写UNIX第五版(90%)
  • 1978, C语言先后移植到大中小和微型机上

1.3.6 C 标准


  • 1978年,在UNIX第7版的C语言编译程序为基础,Brian W. Kernighan 和 Dennis Ritchie, 《The C Programming Language》,"C圣经(Bible)" , K&R C
  • 1989年, Brian W. Kernighan 和 Dennis Ritchie, 《The C Programming Language, 2nd》, ANSI89, ISO1990, C89
  • 1999年, ISO1999, C99
  • 2011年, ISO2011, C11
  • 2017年, ISO2017, C17
  • 20xx年, ISO20xx, C2x?

参考资料:https://zh.cppreference.com/w/c/language/history

1.3.7 C 语言的特点


  • 语言简洁紧凑,使用方便灵活
  • 运算符丰富
  • 数据类型丰富
  • 有结构化的控制语句
  • 语法限制不严格,设计自由度大
  • 运行直接访问物理地址,位操作,实现汇编的绝大部分功能
  • 可移植性好
  • 生成目标代码质量高,程序执行效率高

1.3.8 C 语言的用途


  • 操作系统(几乎所有,windows,Mac OS,Linux等)
  • 要求性能高的程序,比如游戏,实时控制系统

1.4 简单的C语言程序浏览

1.4.1 最简单的C语言程序


例 1.1 要求在屏幕上输出一行信息:

Hello World!

程序和解释:


#include <stdio.h>
int main(void) 
{   printf("Hello world!\n"); 
    return 0; 
}
  • C语言的基本组织单位是函数
  • 每个独立C语言程序都有且只有一个main函数,这是C语言程序的开始和结束
  • #XXX表示这是预编译指令,是在C语言编译器开始之前进行的智能化文本处理, #include<stdio.h>表示将stdio.h文件的内容包含到本行中.

程序和解释:


#include <stdio.h>
int main(void) 
{   printf("Hello world!\n"); 
    return 0; 
}
  • int main(void)函数头main是函数的名称,前面的int表示该函数运行结束后应该有一个返回值,其类型是整数(int),void表示该函数(即main函数)被调用时无需传入参数
  • C语言中可以有很多函数,每个函数的名称必须独一无二,每个函数都需要先定义再使用。函数的定义包括函数头函数的实现,函数的实现由一对大括号{ }来包括

程序和解释:


#include <stdio.h>
int main(void) 
{   printf("Hello world!\n"); 
    return 0; 
}
  • printf是一个C标准库函数,所谓标准库,是指每个C语言标准规定必须存在的很多函数的集合,编译器的实现厂商负责提供。printf函数负责将指定的信息显示到屏幕上
  • printf有很多用法,后面我们会看到更多。printf("xxx")是将文字串 xxx(文字串又称为字符串,string,在C语言中用" "来包括起来)
  • 文字串(字符串)末尾的"\n"表示本行结束,后面再有文字输出的时候就换到下一行开头进行显示

程序和解释:


#include <stdio.h>
int main(void) 
{   printf("Hello world!\n"); 
    return 0; 
}
  • printf("xxx"); 称为一条语句,这是C语言的基本语法单位,每条语句末尾必须用来结束(后面会介绍几种特殊的情况)
  • return 0;表示函数(main结束并以一个值(这里是0)返回到调用者(对于main函数来说,就是操作系统)
  • 注释,两种注释方法://表示单行注释,从//开始到行尾都是注释,编译器自动忽略不编译,C99;
  • 另一种注释是/* ... */这样的块注释,K&R C, C89,C99都适合,注意/**/之间都不能有空格,这样的注释不能嵌套,比如/* /* */ */这样是错误的,但是上面的//可以,比如// //是可以的.

In [5]:
#include <stdio.h>
int main() 
{   printf("Hello world!\n"); 
    return 0; 
}


Hello world!

1.4.1 最简单的C语言程序


例 1.2 求一个数的开方:

9.000000的开方是:3.000000

程序和解释:


#include<stdio.h>
#include<math.h>
int main(void)
{ float a = 9;                    
  printf("%f的开方是:%f\n", a, sqrt(a));
  return 0; 
}
  • C语言中可以定义变量,变量有名称类型,类型决定了变量能够保存的数据类型和大小,常见的类型有int(整数类型,简称整型, 如123, +10086, -34 , 0 , 012 , 0xf )、float(单精度浮点类型,可以保存实数类型,如 1.45, 3.4e-3)、char(字符类型,可以保存字符等符号数据, 如'a', 'B', '+', '#', '1'

In [ ]:
//%cflags:-lm
#include<stdio.h>
#include<math.h>
int main(void)
{ float a = 9;
  printf("%f的开方是:%lf\n", 
     a, sqrt(9));
  return 0; 
}

In [ ]: