如何生产一个程序
第一阶段: 编程
编程就是使用计算机能理解的语言来描述解决问题的方案.
编程的具体过程
假设我们需要编写一个程序,计算圆的面积
- 分析问题
- 需要什么输入?半径
- 需要做什么计算?面积=π*半径²
- 需要什么输出?面积的数值
- 设计解决方案
- 提示用户输入半径
- 读取用户输入的半径
- 使用公式计算面积
- 显示计算结果
- 编写代码
#include <stdio.h>
int main() {
float radius, area;
const float PI = 3.14159;
// 提示用户输入
printf("请输入圆的半径: ");
// 读取用户输入
scanf("%f", &radius);
// 计算面积
area = PI * radius * radius;
// 输出结果
printf("圆的面积是: %.2f\n", area);
return 0;
}第二阶段: 编译 - 翻译成计算机语言
编译的详细过程
- 预处理: 这是编译的第一步,预处理器会处理所有以
#开头的指令,比如#include <stdio.h>,把stdio.h文件里的内容复制到当前文件中. - 编译: 把预处理后的 C 语言代码翻译成汇编语言,汇编语言比机器语言容易理解一些,但仍然很接近硬件.这就像把中文先翻译成英文,为进一步翻译做准备.
- 汇编: 把汇编语言翻译成机器语言,生成目标文件(.obj或者.o文件).这就像把翻译好的各个章节装订成一本完整的书.
- 链接
编译工具的使用
通常我们使用集成的开发环境 IDE 来简化编译过程
命令行编译
gcc -o circle_area circle_area.c这条命令告诉 GCC 编译器,把circle_area.c编译成名为circle_area的可执行文件.
第三阶段: 执行
编译完成后,我们得到了一个可执行文件,我们还需要点击执行。
执行过程的详解
- 加载:当你双击可执行文件的时候,操作系统会把程序从硬盘加载到内存中。这就像把一本书从书架上取下来,打开准备阅读。操作系统会为程序分配内存空间,包括:
- 代码段:存储程序的指令
- 数据段:存储全局变量和静态变量
- 堆:用于动态分配内存
- 栈:用于存储局部变量和函数调用信息
- 创建进程:操作系统会为程序创建一个进程,分配一个
PID进程 ID,并在进程表中记录相关信息,这就像给每个正在做菜的厨师分配一个工作台和工具。 - 开始执行:CPU 开始执行程序的指令,对我们的圆形的面积计算程序:
- 先执行
printf("请输入圆的半径: ");在屏幕上显示提示信息 - 然后执行
scanf("%f", &radius);等待用户输入 - 然后用户输入数据之后,执行
area = PI * radius * radius;进行计算 - 最后执行
printf("圆的面积是: %.2f\n", area);显示结果
- 先执行
调试 Debugging - 发现和修复错误
程序很少能一次性完美运行,通常需要经过调试过程来发现和修复错误。
- 语法调试:修复编译时发现的语法错误
- 逻辑调试:程序能够运行,但结果不正确,需要检查算法逻辑是否准确
- 运行时调试:程序在某些情况下会崩溃或产生异常,需要找出导致问题的原因
C 语言简单代码解析
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}注意:include是一个关键字,不能拼错,#是英文符号的,后面的<可以换成",里面是对应的一个包含的一个文件stdio.h
如果是windows下安装了mingw64的可以使用everything搜索一下stdio.h,里面会有很多内容,常见的printf就在里面。
代码的第二行是一个空行,空行是不受影响的。
int main(),int是一个返回值类型,对应return 0需要返回一个整型的数据。main()函数现在是没有参数的,或者在括号里面写void,也是代表没有参数的。
花括号是配对的,花括号里面是真正的执行的逻辑的代码。
printf能够在终端里打印出内容进行展示
\n是换行符
分号是在c语言里代表的一个语句的结束,即这一行代码的写完了,即这一行可以进行翻译为对应的机器码交给计算机来执行。
所有的英文符号都必须是对应的英文符号,中文符号肯定是不行的。
数据类型
整型数据类型
- int
- short
- long
- long long
浮点型数据类型
- float:单精度浮点数,精度有限但够用,它通常能够提供 6-7 位有效数字的精度
- double:双精度浮点数,精度更高,它通常能提供大约 15-16 位有效数字的精度,大多数情况下来使用
double来处理小数 - long double:扩展精度浮点数,精度最高,这个基本上用不到,且在不同系统中具体实现可能不同
字符型数据类型
- char 类型用来存储单个字符,比如字母
A,数字5,标点符号!等。需要注意的是,字符要用单引号括起来,比如'A',而不是"A" - 在计算机内部,字符实际上是以数字形式存储的,每个字符都有对应的数字编码,比如字母
'A'对应的数字是 65,这套编码标准叫做ASCII码,这就像每个汉字都有一个拼音编码一样,计算机用数字来编码字符。
构造数据类型
- 数组类型
- 指针类型:就像是地址标签,它不直接存储数据,而是存储数据的地址
- 结构体类型:允许我们把不同的类型的数据组合在一起
- 联合体类型:允许不同类型的数据共享同一块内存空间,就像一个多功能房间,有时候当卧室使用,有时候当客厅使用,但同一时间只能有一种用途。
- 枚举类型:表示一组有限的选择,比如一周的七天,一年的十二个月,交通灯三种颜色,让程序更容易维护。
自定义数据类型
使用typedef关键字来定义自己的数据类型,这就像给数据类型起别名一样,让程序更容易理解。
typedef int StudentAge; // 定义学生的年龄类型
typedef float StudentHeight; // 定义学生的身高类型这样在程序中使用 StudentAge和StudentHeight就更容易理解这些变量的用途。
数据在内存中的存储
字节和位的概念
位:bit,是计算机中最小的数据单位,它只能存储 0 或 1 这两个值,这就像一个开关,只有开和关两种状态。位的英文是 bit 实际上是binary digit二进制数字的缩写
字节:byte,由 8 个连续的位组成,是计算机中基本的存储单位。一个字节可以存储 256 种不同的值,从 00000000 到 11111111,也就是十进制的 0 到 255。为什么是 8 个位呢?这是历史上形成的标准,8 个位恰好可以表示一个英文字符。
不同类型的数据的存储空间
字符型 char
char类型通常占用 1 个字节的空间,一个字节的 8 个位可以表示 256 种不同的值,这足够表示所有的ASCII字符,包括大小写字母、数字、标点符号等。
整型
short通常占用 2 个字节 16 位,可以表示 65536 种不同的值,如果是有符号的,范围则是 -32768 到 32767;如果是无符号的,则是 0-65535int在现代系统重通常占用 4 个字节,32 位,可以表示约 42 亿种不同的值long的大小取决于系统,在 32 位系统通常是 4 个字节,64 位系统里通常是 8 个字节long long通常占用 8 个字节 64 位,可以表示非常大的数值范围
浮点型
float通常占用 4 个字节double通常占用 8 个字节
浮点数的存储比整数复杂的多,它分为 3 个部分:符号位、指数位、尾数位
