八:问题/不间断更新
前文
本章节记录一些问题和思考。
正文
为什么需要编译的四个过程
是在C++这个语言的规则下,分了四个过程,还是为了更好的管理源码,将源码编译到可执行文件,例如链接过程,不需要将重复的内容复制粘贴, 通过动态链接使用共同的部分。
为什么C++有多种整型
其实不管类型是什么,本质上是内存空间不一样,多种整型或者说多种变量类型都是为了编码上更好的人为分配空间。
为什么类型转换从大数值转到小数值有风险
和类型一样,本质上还是因为占用的字节数不一样,大字节数的数据存到小字节空间自然有不确定结果
为什么有的容器可以通过偏移量访问
这和容器类底层存储方式有关,连续存储可以支持迭代器加偏移量访问。
++和–即自增和自减运算符前缀和后缀版本有什么区别
通常来说,后缀的效率更低,因为前缀会直接+1,而后缀会复制一个副本,待表达式结束后,才会对副本+1并返回副本, 但对内置类型来说没什么区别,如果用户有自定义,则前缀效率更高。
内联函数的特点
因为函数也是地址(函数名是第一个可执行代码地址),因此程序运行时不同函数之间的跳跃会消耗性能, 本质上内联的语法是为了告诉编译器,不要跳跃寻找函数了,这里就有一份副本,因此内联函数不要写很多行很复杂, 且编译器在编译优化时,即使inline
声明了,编译器也可能不会将很复杂的函数优化成内联函数。
算法时间复杂度和空间复杂度是怎么计算的
时间复杂度的方法是分析算法中的循环次数和递归调用次数,其中最高阶的项作为结果。如变量n
需要循环n^2+n
次,其中n
可以忽略,其复杂度为O(n^2)。这和底层的存储方式也有关,例如数组需要获取第n
个元素为O(1),因为数组可以通过下标获取,但单向链表不一样,最多需要遍历到特定位置获取,为O(n)。一般O(1)、O(log n)、O(n)、O(n log n)、O(n^2)等。
空间复杂度是指算法执行所需的额外空间量度,也用大O符号表示。它表示随着输入规模的增加,算法所需的额外空间的增长趋势。计算空间复杂度的方法是分析算法中的变量、数组、递归调用等所占用的空间,然后找出最高阶的项作为空间复杂度。一般O(1)、O(n)、O(n^2)等。
map中的key只能是字符串、整型等吗?可以是数组吗?
不是的。可以是数组,但必须是能够比较的类型,如array
、vector
,举例如std::map<std::vector<int>, std::string> myMap; myMap[{2, 3, 4}] = "apple";
链表中,ListNode* curr = head,意味着什么,改变head能否改变curr?
首先head
是一个指针变量,即地址,ListNode* curr = head
意味着curr
变量值即地址为head
值即地址, 改变head
能改变curr
,但是必须改变结构才行,如head->next = nullptr
,此时,curr
的next
才会是nullptr
, 仅作head = nullptr
,curr
还是head
值即地址,并不是nullptr
。下面这段简单的代码也可表示这种情况:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int a = 10;
int* n = &a;
*n = 100;
cout << n << endl;
cout << &a << endl;
n = nullptr;
cout << n << endl;
cout << &a << endl;
// output
0x7fff69715a5c
0x7fff69715a5c
0
0x7fff69715a5c
设置n为nullptr时,a还是正常的。