【操作系统】编译时 运行时

文章介绍编译时和运行时的概念,并通过C++和C#的数组越界处理行为加深理解!


编译时

编译时顾名思义就是正在编译的时候。那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码。(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言,比如Java只有JVM识别的字节码,C#中只有CLR能识别的MSIL。另外还有链接器、汇编器。为了了便于理解我们可以统称为编译器)。

编译时就是简单的作一些翻译工作,如检查你有没有粗心写错关键字、词法分析、语法分析.如果发现错误编译器就告诉你.如果用微软的VS的话,点下build,开始编译,如果下面有errors或者warning信息,那都是编译器检查出来的。所谓这时的错误就叫编译时错误,这个过程中做的类型检查就叫编译时类型检查,或静态类型检查(所谓静态就是没把代码加载到内存中运行起来,而只是把代码当文本来扫描)。所以编译时分配内存是错误的说法。

运行时

所谓运行时是指代码被装载到内存中运行的过程(代码保存在磁盘上没装入内存之前是个死家伙,只有跑到内存中才变成活的)。而运行时类型检查与前面讲的编译时类型检查(或者静态类型检查)不一样,并不是简单的扫描代码,而是在内存中进行操作、判断。

代码示例

下面我们来看一下C++和C#中对于数组越界的处理方式,来加深理解编译时运行时机制。

C++
代码:
int arr[] = {1,2,3};
int result = arr[4];
count << rrsult << end;//<< 是移位运算符,更多请自行谷歌

代码中存在数组越界:

  • 当使用编译器编译时,不会报错,因为编译器编译的过程只是代码翻译的过程;
  • 当点击Start Debugging,报错了;
  • 当点击Start Release,不报错,仍然可以正常运行,得到的值不确定(arr[4]内存越界访问);

C++运行时不做数组越界检查,为了性能问题,C++只做很少且必须的运行时检查操作,如:多态;
所以当使用debugging模式运行时,其实是VS中的某些工具帮助做的数组越界检查,然后报错。

C#
代码:
int arr[] = {1,2,3};
int result = arr[4];
console.WriteLine(result);

代码中存在数组越界:

  • 同样的编译可以正常通过;
  • 运行后立马报错;

C#与C++不同,它有运行时类型检查机制,可以检查数组越界,但是它并不会返回错误结果描述,而是直接报错,所以需要自行添加异常处理语句捕获出错代码。


关键概念:

  • 左值:可以在赋值运算符两边同时使用的值;
  • 右值:只能在赋值运算符右边使用的值,不能在左边使用;

int a = 3; int b = a;
a 和 b都是左值,可以在赋值运算符两边使用;
3 是右值,只能在赋值运算符右边使用;

  • #define定义的对象称为常数,常数的值在编译时就可以确定;
  • const限定词定义并初始化的对象称为常量,常量的值在运行时初始化后才能确定,然后只能作为右值使用;

你可能感兴趣的:(【操作系统】编译时 运行时)