面试官向我展示了这样的代码,并问我是否会编译,并给出我的推理.我告诉他非常肯定它不会编译,因为10是一个常量,你不能给非const引用赋一个常量(比如int&b = 10也不会编译),同样,_a是一个临时变量,它也是再考虑const,你不能使用非const引用来引用const变量.
然而,在我惊讶地回到家后,我发现它与所有可能的编译器完美编译.而且,我没有得到这份工作.我理解的哪一部分出了问题?
class A {
int& a;
public:
A(int _a):a(_a) {}
};
int main() {
A a(10);
}
Run Code Online (Sandbox Code Playgroud) 在CLRS的教科书"算法导论"中,有关于pg的这一段.258.
如果列表是双重链接,我们可以在O(1)时间内删除一个元素.(注意,CHAINED-HASH-DELETE将元素x作为输入而不是其键k,因此我们不必首先搜索x.如果哈希表支持删除,则其链表应该双重链接,以便我们可以快速删除一个项目.如果列表只是单链接,那么要删除元素x,我们首先必须在列表中找到x,以便我们可以更新x的前一个属性的下一个属性.使用单链表,两个都删除并且搜索将具有相同的渐近运行时间).
让我感到困惑的是这个大家伙,我无法理解它的逻辑.有了双链表,还是要找到x才能删除它,这与单链表有什么不同?请帮我理解一下!
我们知道异常类有两个派生类:logic_error和runtime_error.
logic_error有四个派生类:定义域,invalid_argument,length_error和out_of_range.
runtime_error有三个派生类:range_error,overflow_error和underflow_error.
虽然其中一些是不言自明的,比如overflow_error和underflow_error,但有些并不是那么清楚,特别是range_error,MSDN和cplusplus都只是说"报告范围错误",这几乎没有说什么,它是多么不同out_of_range和domain_error ???
另一个问题是当我抛出异常时,我应该选择哪一个?例如,在reverse_string(char*s)中,当s为NULL时抛出哪个异常?在float calc_ellipse_area(float a,float b)中,当a或b <= 0时抛出?当a == b时(严格来说,圆圈不是椭圆!)?
最后,实际上,如果我抛出一个未正确分类的异常,真的很重要吗?
例如,计算书中单词的出现次数,我看到有人简单地写道:
map<string, int> count;
string s;
while (cin >> s) count[s]++;
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?我在我的机器上测试过,看起来如此.但保证初始化为零吗?如果不是,我会想象这样的代码:
map<string, int> count;
string s;
while (cin >> s)
if (count.find(s) != count.end()) count[s]++;
else count[s] = 1;
Run Code Online (Sandbox Code Playgroud) 我的意思是,我知道关于throw的所有语言规则,尝试{} catch {},但我不确定我是否在现实世界中正确使用它们.请参阅以下示例:
我们有大量的科学代码可以完成各种图像处理工作,最近我们决定对其进行修改,使其更加强大.经常使用的一个例程是void rotate_in_place(float*image,image_size sz) ;
为了使其更加健壮,我们在代码的开头添加了一些健全性检查:
void rotate_in_place(float* image, image_size sz) {
// rotate_in_place does not support non-square image;
if (sz.nx != sz.ny) throw NonSquareImageError;
// rotate_in_place does not support image too small or too large
if (sz.nx <= 2 || sz.nx > 1024) throw WrongImageSizeError;
// Real rode here
.....
}
Run Code Online (Sandbox Code Playgroud)
现在的问题是rotate_in_place()在1000多个地方使用,我应该用try {} catch {}包装每次调用rotate_in_place(),这对我来说会让代码难以置信地膨胀.另一种可能性是不包装任何try {} catch {}并让程序退出,但这与仅使用有什么不同
if (sz.nx != sz.ny) {
cerr << "Error: non-squared image error!\n";
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
简而言之,我不太确定使用throw,try,catch,任何好建议的真正好处?
在说“以前有人问过这个”或“找一本算法书”之前,请继续阅读并告诉我我的推理的哪一部分出了问题?
假设您有 n 个整数,并将它们分成 k 个 bin,这将花费 O(n) 时间。但是,需要对 k 个 bin 中的每一个进行排序,如果对每个 bin 使用快速排序,这是一个 O((n/k) log(n/k)) 操作,因此这一步将花费 O(n log(n/ k)+k) 最后需要组装这个数组,这需要 O(n+k),(参见这篇文章),所以总操作将是 O(n+n log(n/k)+k)。现在,这个 n log(n/k) 是怎么消失的,我完全想不通。我的猜测是有一些数学运算可以消除这个 n*log(n/k)。任何人都可以帮忙吗?
函数(Say"fun()")分配内存并将指针返回到已分配的内存.我应该如何确保释放此内存.我无法在函数"fun()"中立即释放它,因为它返回给调用者.如果fun()是图书馆的一部分怎么办?释放记忆是谁的责任.在fopen()的情况下,内存由fclose()释放.但在我的情况下,反复调用"fun()".所以我不能等到最后释放内存.
C++不支持嵌套函数.假设我有一个功能a和b,我想保证只有一个可以调用b,其他人没有,是否有办法这样做?
请阅读以下C++代码和结果.根据一些维基页面,静态,自动和动态分配的变量分配在不同的地址空间中,即数据段,堆栈和堆.但是,在我看来,静态和动态变量的地址大致相同.为什么会这样?我怎么知道静态变量真的在数据段中,而不是在堆中?
一个更广泛的问题是,在C++中是否有可能知道每个地址空间的范围(或可用大小)?
我的另一个问题是为什么volatile变量的地址是1?
#include <iostream>
using namespace std;
static int i;
int main() {
cout << sizeof(int*) << endl;
int j;
int* k = new int[10];
volatile int l;
cout << &i << endl;
cout << &j << endl;
cout << k << endl;
cout << &l << endl;
delete[] k;
}
Run Code Online (Sandbox Code Playgroud)
结果:
8
0x1000010e4
0x7fff5fbff66c
0x100100080
1
Run Code Online (Sandbox Code Playgroud)