无知是痛苦的根源,坚持学习可以改变你的无知。
有些题目是经典的试题,有些题目是我自己编写的,都是平时在工作中遇到的头痛问题,最终得到了解决,希望后来人不要走弯路,与大家共勉。
【1】下面程序有什么问题
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main() {
stringstream ss("this is a string\n");
string str(ss.str());
const char* cstr1 = str.c_str();
const char* cstr2 = ss.str().c_str();
cout << cstr1
cout << cstr2;
system("PAUSE");
return 0;
}
参考答案:
.c_str()返回的是临时地址,会被STL的内存池回收。
cout << cstr1
cout << cstr2;
扩展说明,stringstream也有类似问题
http://blog.youkuaiyun.com/jimmyleeee/archive/2009/06/26/4300548.aspx
【2】
参考答案
#include <iostream>
using namespace std;
void CalNumInfoByType(unsigned int uNum, int iNumType)
{
}
例如计算123转换成2进制后的情况: CalNumInfoByType(123, 2);
【3】请写出 float
float型变量与零值比较:
#define FLT_EPSILON 1.192092896e-07F
if ((x >= - FLT_EPSILON) && (x <= FLT_EPSILON) )
不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。
如下是错误的写法。
if (x == 0.0)
if (x != 0.0)
【4】32位C++程序,请计算sizeof的值
sizeof数组,即计算数组所占用的空间大小,例如
char
sizeof(str)为6 sizeof(str2)为20
sizeof指针,大小固定为4。
char
注意:数组做为参数在C语言中是按指针变量对待的
{
sizeof( str ) =
}
void *p = malloc( 100 );
sizeof ( p ) =
【5】头文件中的 ifndef/define/endif 干什么用?
通常用来防止头文件被重复引用。还有就是按照条件编译,比如
#ifdef WIN32
#define write(fd,buf,len) send((fd),(buf),(len),0)
#define read(fd,buf,len) recv((fd),(buf),(len),0)
#endif
如果定义了宏WIN32(windows平台),就重新定义write和read
【6】const 有什么用途?
(1)可以定义 const 常量
(2)const可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
【7】 extern的用法?
1. 在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y);
该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。
C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
extern "C"
{
#include "lua/lua.h"
#include "lua/lualib.h"
#include "lua/lauxlib.h"
}
2. extern告诉编译器,某个变量、函数或类已经在某个.cpp(非.h)中已经定义了,另外一个cpp里面只不过是声明一下有这个东西,然后拿来用一下。定义只能出现一次,声明却可出现多次,也就是说extern声明可在多个文件中用(包括.h)。
// 1.cpp
int x = 10;
// 2.cpp 注意没有包含1.cpp
#include <iostream>
using namespace std;
extern int x;
int main ()
{ cout << x << endl; }
//则输出10
【8】 请问运行Test函数会有什么样的结果?
void Test(void)
{
char *str = (char *) malloc(100);
printf(str);
}
}
答:篡改动态内存区的内容,后果难以预料,非常危险。
因为free(str);之后,str成为野指针,
if(str != NULL)语句不起作用。
【9】编写strcpy函数
已知strcpy函数的原型是
char *mstrcpy(char *strDest, const char *strSrc)
{
}
strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?
例如
【10】 编写类String的构造函数、析构函数和赋值函数
已知类String的原型为:
参考答案:
class String
{
public:
private:
};
// String的普通构造函数
String::String(const char *str)
{
}
String::~String()
{
}
// 拷贝构造函数
String::String(const String &other)
{
}
// 赋值函数
String & String::operator = (const String & other)
{
}
【11】 const char*, char const*, char*const的区别
事实上这个概念谁都有只是三种声明方式非常相似很容易记混。 Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 把一个声明从右向左读。 const
char
cp is a const pointer to char
const char * p;
p is a pointer to const char;
char const * p;
同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。
【12】 C的指针
int *p[n];-----指针数组,每个元素均为指向整型数据的指针。
int (*)p[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。
int *p();----------函数带回指针,指针指向返回的值。
int (*)p();------p为指向函数的指针。
【13】数组越界问题
下面这个程序执行后会有什么错误或者效果:
#define MAX 255
int main()
{
}
解答:死循环A[255]=255;
由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去.
注:char类型为一个字节,取值范围是[-128,127],unsigned char [0 ,255]
【14】 ASSERT()是干什么用的
ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。例如
......
ASSERT( n != 0);
k = 10/ n;
......
ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。
assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。
【15】system("pause");
系统的暂停程序,按任意键继续,屏幕会打印,"按任意键继续。。。。。"
省去了使用getchar();
【16】 请问C++的类和C里面的struct有什么区别?
c++中的类具有成员保护功能,并且具有继承,多态这类oo特点,而c里的struct没有
【17】 请讲一讲析构函数和虚函数的用法和作用?
析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。知识在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编。另:析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,
虚拟函数的功能是使子类可以用同名的函数对父类函数进行重载,并且在调用时自动调用子类重载函数,如果是纯虚函数,则纯粹是为了在子类重载时有个统一的命名而已。
【18】全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?
全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。其实现是由编译器在编译时采用不同内存分配方法。全局变量在main函数调用后,就开始分配,如果是静态变量则是在main函数前就已经初始化了。而局部变量则是在用户栈中动态分配的(还是建议看编译原理中的活动记录这一块)
【19】 8086是多少位的系统?在数据总线上是怎么实现的?
8086系统是16位系统,其数据总线是20位。
【20】 编写用C语言实现的求n阶阶乘问题的递归算法:
long fact(int n)
{
}
【21】
int a = ……;
int b = ……;
a = a + b;
b = a - b;
a = a - b;
【22】
f(1)=1
f(2)=1
f(n)=f(n-1)+f(n-2) n>2
参考文献:http://bbs.bccn.net/thread-175695-1-1.html
解:
1)递归算法
int calfun(int n)
{
}
2)非递归算法
int Fibona(int n)
{
}
【23】分别用C与C++代码读取文件
int loadEncryptedFileCpp(lua_State *L, const char *filename)
{
}
int loadEncryptedFile(lua_State *L, const char *filename)
{
}
【24】printf中格式化参数"%-*.*s"代表什么意思,编程举例说明。
#include <stdio.h>
#include<string.h>
int main()
{
char ch[20];
int m,n;
strcpy(ch,"Happy!");
scanf("%d%d",&m,&n);
printf("%*.*s\n",m,n,ch);
return 0;
}
其中"-"表示左对齐,前边*定义的是总的宽度,后边*是指定输出字符个数。分别对应外边参数m和n。
输入: 10 3
输出: Hap
参考:http://baike.baidu.com/view/410546.htm
【25】虚析构函数
虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。
有下面的两个类:
{
public :
};
class
{
public :
};
代码
pTest -> DoSomething();
delete
的输出结果是:
Output from the destructor of class ClxDerived!
如果把类ClxBase析构函数前的virtual去掉,那输出结果就是下面的样子了:
【26】书写圆括号匹配函数,函数原型int check(char *input, int len)
返回值:匹配返回1,不匹配返回0。
例如:(a+b*9)(a+B)匹配返回1
答案: