BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #89925同步于 2016/1/16
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

Quiz:下面关于C/C++的说法,哪些是错误的?

nuanyangyang
2016/1/16镜像同步29 回复
好久没有新帖。来娱乐一下 0. C/C++标准规定,源代码应当以ASCII编码保存在文件里,以便编译器编译。所以,把源代码用ms word编辑,存成.doc文件,或者用Windows画图板画一个源代码,如下图,都不是合法的C/C++程序。 1. C/C++标准规定,一个char占1字节,一个short或者int占2字节,long占4字节。 2. C/C++标准规定,一个char占1字节,一个short占2字节,一个int或者long占4字节,一个long long占8字节。 3. C/C++标准规定,一个char占1字节,一个short占2字节,一个int占4字节,一个long或者long long占8字节。 4. 对于char, short, int或者long来说,如果没有加unsigned标注,就是有符号的。 5. float和double采用IEEE754浮点数格式。 6. 有符号整数采用补码(2's complement)表记法 7. 因为上述原因,如果int占4字节,那么有符号int数2147483647(2的31次方减1)再加1,结果是-2147483648。 8. 因为上述原因,只要x是有符号的,编译器就不可以假设x<x+1这样的表达式永远为真,因为x+1有可能突然变成负的。 9. 因为上述原因,可以用判断符号的方法判断有符号整数是否溢出,如: void f(int x, int delta) { assert(x>=0 && delta>=0); if (x + delta < 0) { printf("Overflow!\n"); exit(1); } // continue from here... } 10. 整数除以0的行为是:运行时报错,并立即退出程序。 11. 因为上述原因,应当在计算除法之前判断除数是否为零,这样就可以避免运行时出错,即: int x = ..., y = ...; if (y != 0) { return x / y; // 这行是安全的,因为y不可能为0。 } 12. 一个IEEE754的浮点数并不表示一个数,而是表示一个范围。 13. IEEE754浮点数的计算,比如加、减、乘、除、开平方、FMA(fma(a,b,c) = a * b + c),都不一定精确。就算其数学结果可以用和参数相同的IEEE754格式表示,在不同的机器上执行的结果也可能不一样。所以,像5.0 + 3.0 == 8.0这样的表达式有可能为假。 14. 对于32位整数x,移位运算x<<32的结果是0,因为所有的位都移出去了。 15. 类似地,x << (-2)相当于x>>2。 16. register关键字的作用是指定某些变量存放在寄存器里。如果不使用register关键字,那么变量就存放在内存里。 17. C/C++求表达式的值时,按先左后右,由里而外的原则。如果表达式有副作用(如i++),那么副作用发生的时间和表达式求值相同。 18. C/C++的程序,在函数调用时,函数的参数按从右往左的顺序压到栈上,被调函数从栈上获取参数。 19. 指针就是地址。 20. 指针访问的效率比数组下标访问更高,因为少一次下标运算。比如,下面函数g的效率高于f。 int f(int ar[], int sz) { int i, sum = 0; for(i=0;i<sz;i++) { sum += ar[i]; } return sum; } int g(int ar[], int sz) { int sum = 0, *p, *p2 = ar+sz; for(p=ar;p<p2;p++) { sum += *p; } return sum; } 21. 结构(struct)的大小是各个成员的大小的总和。如果int是4字节,char是1字节,那么struct{char a; int b;}占5字节。 22. 拥有0个元素的数组(如char data[0])很有用。它可以作为结构的最后一个成员,如struct foo { int a,b,c; char data[0]; }。C/C++标准允许这种数组并为这种结构开了一个特例:指向它的指针可以指向那个数组元素长度是任意长度结构,如,可以指向struct bar { int a,b,c; char data[1024]; } 23. 如果f是函数,那么,指向它的指针是&f,而f表示那个地址处的数据。因此,下面的程序是错误的: int f(int n) { return n + 1; } int main() { int (*fp)(int); fp = f; // 错误。fp会从函数f的代码处读取8个字节(或者4个,取决于指针长度)存在fp里。 int result = fp(100); // 运行时出错 } 24. printf,scanf等IO函数都不是线程安全的。如果在不同的线程里调用这些函数而没有使用锁等同步机制,是未定义行为,即,从什么也不发生到机器冒烟都可能发生。 25. main函数的返回值类型是int。因此如果执行到main的末尾却没有执行到return语句,是未定义行为,即,从什么也不发生到机器冒烟都可能发生。 26. 局部变量如果没有初始化就读取,结果是任意值。【已修正,现专门说“局部变量”】 27. C++的特色是面向对象编程。它有object的概念,即:一个数据和操作的结合体,具有继承、封装、多态的特性。 28. 相对地,C是一个面向过程的语言,它并没有object的概念。 29. 用//注释是C++的特性,很多C语言编译器都支持,但并没有被标准化。 30. const表示一个存储空间不能改变,但C++拥有const_cast,所以还是可以改变的,如下面程序(摘自某公司面试题): int main() { const int a = 42; int *b = const_cast<int*>(&a); *b = 43; cout<<a<<endl; // 43 } 31. new,new[],malloc都是用来分配内存的。分配出来的内存用delete,delete[]和free回收都可以。 32. 类的大小的计算方法和struct类似,为各个成员(含当前类和所有祖先类的成员)大小的总和。【已修正,强调包含当前类和所有祖先】 33. 异常处理(即try{...}catch(...){...})会影响正常程序的性能,因为进入try块执行之前必须保存一些上下文,以便异常发生的时候恢复。所以异常处理一定会在正常的执行路径中做额外的工作。对于性能很重要的程序,应当用返回特殊值的方法处理异常情形。 34. 如果整个栈上没有任何函数可以捕获异常,那么C++会执行每个函数里的局部变量析构函数,然后强行终止程序。例如:main函数调用f,f调用g,g调用h,h抛出了异常,但h,g,f,main中都没有try-catch块能够抓住这个异常,那么C++会顺次执行h,g,f,main里局部变量的析构函数,然后强行终止。【已修正:新添加了例子】 35. 因为上述原因,如果用ofstream这样有析构函数的对象打开文件,那么程序因未捕获的异常而退出之前可以保证文件被关闭。 36. 一些工程可能同时用到C和C++语言。因为C++兼容C,所以,在C++程序里,只要用和C++函数同样的方法声明了C的函数,就可以调用该函数。如下: // foo.c int foo(int x) { return x + 1;} // bar.cpp int foo(int x); // 声明 void bar() { int x = 10; int y = foo(x); // 调用 } 37. vector类内部动态地维护一个数组。为了性能,vector在删除元素时只是修改一个界限指针,并不会把值从vector中去掉。所以,下面的程序总能打印出删除以前的值: vector<int> a = {10, 20, 30, 40}; int *p = &a[3]; a.pop_back(); cout<<*p<<endl; // 这个是安全的,打印40。 38. string类通过copy-on-write高效实现字符串拷贝。在实际应用中,往往只有<1%的string赋值表达式真的造成了深拷贝。【这道题出得不太好,太经验化了,没有绝对的答案……大家自己估计吧。】 39. unique_ptr唯一地拥有一个指针,当它被赋值给另一个unique_ptr时,由于所有权转移,当前unique_ptr不再拥有该指针。所以,想操作该unique_ptr指向的内存,必须先获取它的所有权,而不可以在没有所有权的情况下绕开unique_ptr操作该内存。 40. 多线程是由计算机硬件以及操作系统实现的,和编程语言并没有太大关系。所以,即使编程语言不支持多线程(如C11和C++11之前的C/C++版本,或者别的语言,如lua),只要链接到多线程库(如pthread)并调用相关的API函数,就可以正确实现多线程了。 41. 多个线程可以被任意调度,谁先执行谁后执行,或者如何交错执行,是不一定的。但一个多线程的程序执行的结果,总是相当于各个线程执行的各个操作按某个顺序串起来一样。 42. 垃圾回收性能很差,其中一个原因是“堆”是中心资源,多个线程同时分配会造成大量阻塞,所以无法在多线程并行程序中很好地工作(这是Bjarne Stroustrup的原话,但正确性请读者自行判断)。 43. 因为垃圾回收性能很差,为了提高性能和内存管理效率,应当使用C/C++这样的非垃圾回收的语言。如果把一个需要大量new和delete的大型项目移植到有垃圾回收的语言上,往往性能会大幅度降低,其中垃圾回收是一大瓶颈。 就这些吧,祝各位爷玩儿得爽~[ema28] 答案:以上选项全部都是错的
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
iamluo机器人#1 · 2016/1/16
占座~~
Jialin机器人#2 · 2016/1/17
前排占座,一会电磁场学疯了来答
xiecaiji机器人#3 · 2016/1/18
暖神。给跪。。 回答一个:如果用new[]来分配内存, 用delete或者free来释放都会出错。。一定要用delete[] 还有:移位的右操作符不能是负数。。。
zx723机器人#4 · 2016/1/18
0. C/C++标准规定,源代码应当以ASCII编码保存在文件里,以便编译器编译。所以,把源代码用ms word编辑,存成.doc文件,或者用Windows画图板画一个源代码,如下图,都不是合法的C/C++程序。 不知道 1. C/C++标准规定,一个char占1字节,一个short或者int占2字节,long占4字节。 不记得有这个规定 2. C/C++标准规定,一个char占1字节,一个short占2字节,一个int或者long占4字节,一个long long占8字节。 不记得有这个规定 3. C/C++标准规定,一个char占1字节,一个short占2字节,一个int占4字节,一个long或者long long占8字节。 不记得有这个规定 4. 对于char, short, int或者long来说,如果没有加unsigned标注,就是有符号的。 个人觉得,是的 5. float和double采用IEEE754浮点数格式。 我见过的是这么表示的 6. 有符号整数采用补码(2's complement)表记法 是的 7. 因为上述原因,如果int占4字节,那么有符号int数2147483647(2的31次方减1)再加1,结果是-2147483648。 不是 8. 因为上述原因,只要x是有符号的,编译器就不可以假设x<x+1这样的表达式永远为真,因为x+1有可能突然变成负的。 不是 9. 因为上述原因,可以用判断符号的方法判断有符号整数是否溢出,如: 不是 10. 整数除以0的行为是:运行时报错,并立即退出程序。 不是 11. 因为上述原因,应当在计算除法之前判断除数是否为零,这样就可以避免运行时出错,即: x = INT_MIN; y = -1; 会发生什么呢? 12. 一个IEEE754的浮点数并不表示一个数,而是表示一个范围。 可以这么理解吧 13. IEEE754浮点数的计算,比如加、减、乘、除、开平方、FMA(fma(a,b,c) = a * b + c),都不一定精确。就算其数学结果可以用和参数相同的IEEE754格式表示,在不同的机器上执行的结果也可能不一样。所以,像5.0 + 3.0 == 8.0这样的表达式有可能为假。 貌似是的 14. 对于32位整数x,移位运算x<<32的结果是0,因为所有的位都移出去了。 不好说,看起来像是未定行为,c语言怎么会规定这么无聊的事情呢 15. 类似地,x << (-2)相当于x>>2。 同上 16. register关键字的作用是指定某些变量存放在寄存器里。如果不使用register关键字,那么变量就存放在内存里。 只能说期待编译器这样做,它不做你又有什么办法呢。 17. C/C++求表达式的值时,按先左后右,由里而外的原则。如果表达式有副作用(如i++),那么副作用发生的时间和表达式求值相同。 不是吧 18. C/C++的程序,在函数调用时,函数的参数按从右往左的顺序压到栈上,被调函数从栈上获取参数。 __fastcall/__stdcall/__thiscall/__cdecl 。。。。 19. 指针就是地址。 没这么浅薄吧 20. 指针访问的效率比数组下标访问更高,因为少一次下标运算。比如,下面函数g的效率高于f。 听说有个东东叫SIB 21. 结构(struct)的大小是各个成员的大小的总和。如果int是4字节,char是1字节,那么struct{char a; int b;}占5字节。 不是吧 22. 拥有0个元素的数组(如char data[0])很有用。它可以作为结构的最后一个成员,如struct foo { int a,b,c; char data[0]; }。C/C++标准允许这种数组并为这种结构开了一个特例:指向它的指针可以指向那个数组元素长度是任意长度结构,如,可以指向struct bar { int a,b,c; char data[1024]; } 没有考虑过这个事,待查 23. 如果f是函数,那么,指向它的指针是&f,而f表示那个地址处的数据。因此,下面的程序是错误的: 函数指针不是这样的。 24. printf,scanf等IO函数都不是线程安全的。如果在不同的线程里调用这些函数而没有使用锁等同步机制,是未定义行为,即,从什么也不发生到机器冒烟都可能发生。 不是很了解,不过我没遇到多线程printf出错。。。 25. main函数的返回值类型是int。因此如果执行到main的末尾却没有执行到return语句,是未定义行为,即,从什么也不发生到机器冒烟都可能发生。 至少返回值是未定义的 26. 变量如果没有初始化就读取,结果是任意值。 你得看是什么变量吧 27. C++的特色是面向对象编程。它有object的概念,即:一个数据和操作的结合体,具有继承、封装、多态的特性。 对呀 28. 相对地,C是一个面向过程的语言,它并没有object的概念。 个人觉得,是的 29. 用//注释是C++的特性,很多C语言编译器都支持,但并没有被标准化。 不知道 30. const表示一个存储空间不能改变,但C++拥有const_cast,所以还是可以改变的,如下面程序(摘自某公司面试题): 是 31. new,new[],malloc都是用来分配内存的。分配出来的内存用delete,delete[]和free回收都可以。 配对使用 32. 类的大小的计算方法和struct类似,为各个成员大小的总和。 类的大小计算,要考虑自己和父类的情况 33. 异常处理(即try{...}catch(...){...})会影响正常程序的性能,因为进入try块执行之前必须保存一些上下文,以便异常发生的时候恢复。所以异常处理一定会在正常的执行路径中做额外的工作。对于性能很重要的程序,应当用返回特殊值的方法处理异常情形。 貌似是? 34. 如果整个栈上没有任何函数可以捕获异常,那么C++会执行每个函数里的局部变量析构函数,然后强行终止程序。 没太明白什么意思 35. 因为上述原因,如果用ofstream这样有析构函数的对象打开文件,那么程序因未捕获的异常而退出之前可以保证文件被关闭。 RAII 36. 一些工程可能同时用到C和C++语言。因为C++兼容C,所以,在C++程序里,只要用和C++函数同样的方法声明了C的函数,就可以调用该函数。如下: name mangling extern "C" 37. vector类内部动态地维护一个数组。为了性能,vector在删除元素时只是修改一个界限指针,并不会把值从vector中去掉。所以,下面的程序总能打印出删除以前的值: stl的实现又不是一种,我高兴我也可以写一个,怎么敢这么做呢。 38. string类通过copy-on-write高效实现字符串拷贝。在实际应用中,往往只有<1%的string赋值表达式真的造成了深拷贝。 不知道小于多少。。。 39. unique_ptr唯一地拥有一个指针,当它被赋值给另一个unique_ptr时,由于所有权转移,当前unique_ptr不再拥有该指针。所以,想操作该unique_ptr指向的内存,必须先获取它的所有权,而不可以在没有所有权的情况下绕开unique_ptr操作该内存。 绕开?想访问怎么都有办法的,又不是做了隔离 40. 多线程是由计算机硬件以及操作系统实现的,和编程语言并没有太大关系。所以,即使编程语言不支持多线程(如C11和C++11之前的C/C++版本,或者别的语言,如lua),只要链接到多线程库(如pthread)并调用相关的API函数,就可以正确实现多线程了。 不太了解 41. 多个线程可以被任意调度,谁先执行谁后执行,或者如何交错执行,是不一定的。但一个多线程的程序执行的结果,总是相当于各个线程执行的各个操作按某个顺序串起来一样。 听起来是这样的啊 42. 垃圾回收性能很差,其中一个原因是“堆”是中心资源,多个线程同时分配会造成大量阻塞,所以无法在多线程并行程序中很好地工作(这是Bjarne Stroustrup的原话,但正确性请读者自行判断)。 没研究过,但是malloc什么的多线程时不是每个线程分自己的嘛 43. 因为垃圾回收性能很差,为了提高性能和内存管理效率,应当使用C/C++这样的非垃圾回收的语言。如果把一个需要大量new和delete的大型项目移植到有垃圾回收的语言上,往往性能会大幅度降低,其中垃圾回收是一大瓶颈。 大量的new和delete用c/c++来做,也要慎重啊。
nuanyangyang机器人#5 · 2016/1/18
【 在 zx723 的大作中提到: 】 : 0. C/C++标准规定,源代码应当以ASCII编码保存在文件里,以便编译器编译。所以,把源代码用ms word编辑,存成.doc文件,或者用Windows画图板画一个源代码,如下图,都不是合法的C/C++程序。 : 不知道 : 1. C/C++标准规定,一个char占1字节,一个short或者int占2字节,long占4字节。 : ................... 做得不多。对对答案吧。 26、32、34我叙述得有点不严谨,修正了。38题出得不太好,就都算对吧。
meng714620机器人#6 · 2016/1/20
答案呢?答案都给贴出来哇
nuanyangyang机器人#7 · 2016/1/20
【 在 meng714620 的大作中提到: 】 : 答案呢?答案都给贴出来哇 答案就在楼主贴里。找找
zx723机器人#8 · 2016/1/21
【 在 nuanyangyang 的大作中提到: 】 : : 做得不多。对对答案吧。 : 26、32、34我叙述得有点不严谨,修正了。38题出得不太好,就都算对吧。 显然我只是个初学者,距离语言律师还有很远的路。。。
hwjcool机器人#9 · 2016/1/21
默默围观 发自「贵邮」