1——of C++ and Java togather
因为那个C++最全的笔记是从第18课开始做(笔者说18课之前都很基础),所以这里就对前18课的知识做个笔记总结
C++的工作过程
- 这里提到的C++工作过程主要涉及两个:编译与链接
- 之前考研时候学到,(在组成原理的某个章节),计算机的工作过程其实就涉及 “将源程序转换成可执行文件”,与其中便有许多雷同之处
编译
- 编译之前程序需要进行预处理,Cherno说明预处理其实就是把include文件内容复制进来,然后会输出一个 xx.i 文件(上图有说明,包括视频之后会演示)
- 一个cpp文件就是有一个翻译单元
- 当我们运行vs的运行之后,翻译单元会 预处理-编译-(汇编)-链接,其中 xx.obj 是汇编后的二进制文件,而文件链接后就生成 xx.exe文件
链接
- 链接就是把各个.obj,还有标准库连接起来。其中关键一点在于,连接焦点是要找到每个符号与函数在哪
- ps:如果A.cpp中只写函数声明,而其他cpp文件没有函数,则会编译不会报错,运行时会出现链接错误
与Java对比
- C++与Java虽然都同属于高级语言,但java属于解释性语言,也就是每解释一行代码就将其直接转换成机器码,然后执行
- 虽然java有生成字节码,但字节码不是编译也不是翻译,就是单纯一个转换,字节码依旧属于高级语言范畴,需要又jvm解释成机器码才能运行
C/C++与java的变量定义、声明、初始化(或者还有分配内存?)
int i; //c.c++直接定义,但java也相同
int i=1;
class A{}
A a; //但对于类或者结构体,c.c++也是直接定义并分配内存了,并且这是在栈内分配
A* a=new A(); //c.c++也可通过指针定义,需要用new,但是在堆内分配
A a; //java这样的话只会分配句柄(引用),不会实际分配内容,其实底层就是C++指针实现
a = new A(); //这样才有内存分配
深刻理解C++里的指针与引用
- 指针即指向内存的地址,甚至数组名本身也是一个指针
int x[10];
int* x=new int[10];
cout<<x[1]<<endl;
- ps:方括号内的是索引数index,而之所以指针也能使用x[2]这种方式是因为,对于int*这个指针其前面的类型int表明一个索引移动int类型的长度,即4B
C++的默认初始化(对比java默认初始化的异同)
- C++的默认初始化其实很大程度上和编译器/编译模式相关,甚至在VS中运行Debug模式或者Release模式都会有不一样的结果(可能release下初始化了但Debug下没有),所以如下是在VS的Debug模式下讨论
- C++的局部变量如果没有初始化便会报编译错误,这与java相同
- C++的全局变量会有默认初始化;通过new分配到堆上的变量也会进行默认初始化;甚至对于类中(A)的成员变量,如果类对象初始化在全局(A a)-即int main()之外,便成员变量a会默认初始化,反之类对象初始化在局部(A b),则成员变量a不会默认初始化
#include<iostream>
#include "hello.h"
class A {
private:
int a;
public:
void print() const {
std::cout << a << std::endl;
}
};
A a;
int main() {
A b;
a.print(); //会默认初始化
b.print(); //不会默认初始化
}
- 而java其实更直接了:在局部变量中,基本数据类型不初始化会报错,引用数据类型不初始化则都是为null类型;而在成员变量中,基本数据类型才会默认初始化