计算机基础综合速成(1):编程语言(C/C++/Java)

CC++Java三种编程语言相关概念辨析。大部分内容较为基本,疑难点见“常见内容问答”“核心概念对比”小节。

Hyplus目录

1 C和C++

1.1 基本辨析

C语言面向过程,重点在于算法和数据结构。C程序的设计首先考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出,或实现过程(事务)控制。

C++语言面向对象,首先考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出,或实现过程(事务)控制。它在C的基础上添加了面向对象、模板等现在程序设计语言的特性。它拓展了面向对象设计的内容,如类、继承、虚函数、模板和容器类等,使之更加符合现代程序设计的需要。

C++是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计(泛型编程),还可以进行以继承和多态为特点的面向对象的程序设计(面向对象编程),支持类、封装、继承、多态等特性。

1.2 关于面向对象

面向对象编程:面向对象是一种对现实世界理解和抽象的方法、思想,通过将需求要素转化为对象进行问题处理的一种思想。

:类定义了事物的属性和它可以做的行为。一个类的方法或属性被称为成员。一个类所包含的数据和方法描述一组对象的共同属性和行为。类是在对象之上的抽象,对象则是对类的具象化,是类的实例。

封装性:封装使数据和加工该数据的方法(函数)封装为一个整体,把对象的设计者和对象的使用者分开,使用者不必知晓行为实现的细节。可以增加安全性。

继承性:继承是子类共享父类之间数据和方法的机制。一个类直接继承其他类的全部描述,可以对其进行修改和扩充。可以增强代码的复用性。

多态性:对象根据所接收的消息做出动作,同一消息被不同的对象接收时可能产生完全不同的行动,这种现象称为多态。可使不同内部结构的对象共享相同的外部接口。可以增加扩展性。

1.3 常见内容问答

  1. 指针和变量的自增自减有什么不同?
    • 变量的自增自减是改变变量的值;指针的自增自减是改变指针的指向地址。
  2. 宏定义与操作符的区别?
    • 宏定义是C/C++的预处理命令之一,它是一种替换操作,不执行计算和表达式求解不占内存和编译时间
  3. 虚函数纯虚函数的特点?
    • 虚函数(virtual ReturnType functionName(Parameter) { ... }):。必须是基类的非静态成员函数,其访问权限可以是protectedpublic
    • 纯虚函数(virtual void functionName() = 0;):虚函数的一个子集,含有纯虚函数的类就是抽象类,它不能生成对象
  4. 如何使用纯虚函数?
    • 纯虚函数用于定义没有意义的实现,用于抽象类中需要交给派生类具体实现的方法。
  5. 值传递引用传递的区别?
    • 值传递:传递的是值的副本,函数对形参的操作不会影响实参的值。
    • 引用传递:传递的是引用对象的内存地址,函数对形参的操作会影响实参的值,实参的值会随着形参的值的改变而改变。
  6. 引用和指针的区别?
    1. 引用无需解引用,指针需要解引用。
    2. 引用在定义时被初始化之后就不可变,指针可变。
    3. 引用不能为空,指针可以为空。
    4. 指针变量需要分配内存区域,而引用不需要分配内存区域。故指针自增操作是指针变量的自增,引用自增操作是变量值的自增
  7. 面向过程和面向对象的区别?
    • 面向过程是一种以过程为中心的编程思想,以算法进行驱动。组成:程序=算法+数据。
    • 面向对象是一种以对象为中心的编程思想,以消息进行驱动。组成:程序=对象+消息。
  8. 面向对象的特征是什么?
    • 面向对象3要素:封装、继承、多态。面向对象中所有对象都可以归属为各种类。
  9. 结构体和类有什么区别?
    1. 结构体存储在中;类的实例化既可以存储在栈中,也可以存储在堆中。
    2. 结构体的执行效率比类要高。
    3. 结构体没有析构函数,类有析构函数。
    4. 结构体不可以继承,类可以继承。
  10. C++覆盖隐藏概述?
    • 覆盖:子类和父类中,存在函数名与参数均相同的函数,并且父类的该函数为虚函数
    • 隐藏:子类和父类中——
      1. 存在函数名相同、参数不同的函数,此时父类函数无论是否为虚函数都被隐藏。
      2. 存在函数名与参数均相同的函数,此时父类函数只有当不为虚函数时才会被隐藏。
  11. C++支持参数个数不确定的函数吗?
    • C++可以通过可变参数机制支持参数不确定的函数。
  12. 什么是内联函数
    • 使用inline关键字修饰。可理解为将调用的函数体直接嵌入调用处,省去了调用时的参数传递、挂起和返回的开销,从而提高了程序的执行效率在类声明的内部实现的函数自动成为内联函数。在内联函数内不允许有循环语句和switch语句,且无法递归调用。
  13. 什么是静态函数?如何使用静态函数?
    • 使用static关键字修饰。静态函数中不能使用this指针,只能访问静态变量
    • 类中若某成员函数调用的结果不会访问或修改任何对象数据成员,则该函数声明为静态成员函数比较好。
  14. 什么是函数重载
    • 函数重载是指在相同作用域下,函数名相同、参数列表不同的多个函数。
  15. 什么是函数模板
    • 函数模板技术是指使用了模板(Template)技术定义了参数化类型的非成员函数,这使得程序能够使用不同的参数类型调用相同的函数
  16. 什么是类模板
    • 类模板是指使用模板技术的类,描述了能够管理其他数据类型的通用数据类型。类模板技术通常用于建立包含其他类型的容器类(链表、栈与队列等)。
  17. 什么是泛型编程?如何实现泛型编程?
    • 泛型编程就是以独立于特定类实现的方式编写代码,针对不同的类型提供通用的实现
    • C++中使用模板技术来实现泛型编程,主要用于设计函数模板和类模板。

2 C++和Java

2.1 基本辨析

Java由C++发展而来,保留了C++的大部分内容。Java的编程方式类似于C++,但句法更清晰、规模更小、更易学。Sun公司曾对多种程序设计语言进行分析研究,取其精华去其糟粕,最终推出了Java。Java从根本上解决了C++的固有缺陷,形成了新一代面向对象的程序设计语言。

2.2 核心概念对比

  1. 解释编译
    • Java是一种半编译半解释的解释型语言,其在执行时需要用JVM(Java虚拟机)解释成二进制形式。现代的Java语言除了这种解释执行方式外,还存在即时编译器(Just-In-Time compiler,JITC)技术和原型编译技术,运行效率大大提高。
    • C++是编译型语言,程序只能在特定操作系统上编译并在特定系统上运行,即一步到位变成机器语言。
  2. 关于指针
    • Java没有指针的概念。在C/C++中,指针操作内存时经常会出现错误;Java通过取消指针这一概念,有效防止了一系列由指针引起的操作层失误(如指针悬空造成的系统崩溃),更有利于Java程序的安全。
  3. 内存安全
    • Java是一种内存安全型语言,这意味着可以为给定数组分配任意参数,即使超出范围也只会返回错误提示。C++更为灵活,但代价是一旦分配的参数超出资源范围,则会引起错误甚至严重崩溃。
  4. 关于多重继承
    • Java不支持多重继承。多重继承允许多个父类派生一个子类,即一个类允许继承多个父类。尽管多重继承功能性很强,但使用复杂,且容易引起许多麻烦,编译器的实现开销也不小。因此Java不支持多重继承,但允许一个类实现多个接口,可见,Java既保留了C++多重继承的功能效果,又避免了C++的许多问题。
  5. 关于数据类型
    • Java是完全面向对象的语言,故所有方法和数据都必须是类的一部分。除了基本数据类型之外,其余类型的数据都作为对象型数据(例如字符串和数组)。类封装了数据和方法,这样每个对象都可实现具有自己特点的行为。C++仍可用面向过程的编码方式,定义全局变量和函数并进行调用,这容易增加程序负担。此外,Java还取消了C/C++中的结构体和联合,两者均可用类来实现,这使得编写程序更加简洁。
  6. 自动内存管理
    • Java自动进行无用内存回收操作,不再需要手动删除。Java程序中所有对象都可通过new操作符定义在堆栈上,这类似于C++中的new操作符。当Java中一个对象不再被用到时,无需手动使用内存回收器,在其被添加删除标签之后,无用内存回收器便会利用空闲时间在后台运行内存回收。而C++中必须由程序释放内存资源,这增加了编码负担。
  7. 关于操作符重载
    • Java不支持操作符重载。操作符重载是C++的突出特征之一,通过给操作符(Operator)赋予新的意义,可实现更为细致具体的运算等功能。要实现操作符重载,必须使用操作符重载函数,而运用函数就肯定会存在各种限制条件和特殊情况,特殊情况需要特殊处理,因此编写优质的操作符重载的过程相当繁琐。Java主打简洁性,毅然抛弃了操作符重载这一繁琐功能,但为了避免舍本逐末,Java仍可通过类来实现操作符重载所具有的功能。
  8. 关于预处理功能
    • C/C++在编译过程中都存在预处理阶段,由预处理器负责,它为编码提供了便利,但增加了编译的复杂性。Java允许预处理,但没有预处理器,而是提供了引入语句import),与C++预处理器的功能类似。
  9. 关于缺省参数函数
    • Java不支持缺省参数函数,而C++支持。在C语言中,代码组织在函数中,函数可以访问程序的全局变量;C++引入了类,提供了类方法;Java类方法与C++类方法十分相似。由于C++仍支持C语言,故C++程序中仍可使用C的函数,结果导致函数和方法混合使用,使得程序编码混乱。而Java严格意义上讲没有函数(应称为方法),作为比C++更纯粹的面向对象的语言,Java强迫开发人员把所有例行程序包括在类中。事实上,用方法实现例行程序可激励开发人员更好地组织编码。
  10. 字符串
    • C和C++不支持字符串变量(STL容器除外),在C和C++程序中使用'/0'(NULL)终止符代码字符串的结束。在Java中,字符串使用类对象(StringStringBuffer等)来实现,在任何系统中建立字符串和访问字符串元素的方法都是一致的。Java字符串类是作为Java语言的一部分定义的,而不是作为外加的延伸部分。此外,Java还可以对字符串用+进行连接操作。
  11. 关于goto语句
    • 可怕的goto语句是C和C++的“遗物”,它是语言技术上的合法部分。goto语句又称为无条件转移语句,通常与条件语句配合使用,用于实现条件转移、构成循环、跳出循环体等功能。但是,在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱、使程序的可读性变差、增加程序调试的难度。Java尽管指定goto作为关键字,但不提供它的使用,这使程序更简洁易读。
  12. 关于类型转换
    • 在C和C++中,有时会出现数据类型的隐式转换,这涉及到强制类型转换问题,例如,在C++中可将一个浮点值赋予整型变量,这使得其小数部分被去掉。Java不支持自动强制类型转换,必须由程序显式地进行强制类型转换。

2.3 应用场景对比

Java侧重于大型企业级应用开发。Java是Android开发领域的首选语言之一,移动端开发者常选择它作为项目基础。此外,Java也常见于Web桌面应用乃至服务端应用开发。

C++侧重于底层应用开发。C++更接近机器语言,因此其软件运行速度更快,且能够直接与计算机内存、磁盘、CPU或其他设备进行协作。此外,C++也能为游戏提供良好的运行性能。

发表评论