1、判断
void main(){ char str1[] = "abc"; char str2[] = "abc"; const char str3[] = "abc"; const char str4[] = "abc"; const char* str5 = "abc"; const char* str6 = "abc"; std::cout << std::boolalpha << ( str1==str2 ) << std::endl; //false std::cout << std::boolalpha << ( str3==str4 ) << std::endl; // false std::cout << std::boolalpha << ( str5==str6 ) << std::endl; // true /*分别输出字符串的地址 str1,str2,str3,str4位于栈区,向低地址增长 str5,str6位于只读数据区,所以地址相同 */ printf("%p\t%p\n",str1,str2); printf("%p\t%p\n",str3,str4); printf("%p\t%p\n",str5,str6); system("pause"); }
解答:分别输出false,false,true
str1和str2都是字符数组,每个都有自己的存储器,数组名的值则是各存储器的首地址,所以不等。
str3和str4同上,只是按const语义,他们所指向的数据区不能修改。
str5和str6不是数组而是字符指针,并没有分别存储器,"abc"以常量形式存于静态数据区,指针则指向该区的首地址,所以相等。
2、 将 str 中的小写字母转换成大写字母
void UpperCase( char str[] ) { for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i ) if( 'a'<=str[i] && str[i]<='z' ) str[i] -= ('a'-'A' ); }UpperCase函数传递指针,sizeof(str)==4,字符串长度超过4,就不能够转换
3、非C++内建型别A和B, 在哪几种情况下B能隐式转化为A?
- // Case 1 : B公有继承自A
- class B : public A
- {
- ...
- }
- // Case 2 : B实现了隐式转化为A的转化
- class B
- {
- operator A();
- }
- // Case 3 : A实现了non-explicit的参数为B的构造函数
- class A
- {
- A(const B&);
- }
- // Case 4 : 赋值操作
- A & operator=(const A&);
5、c++空类默认产生的类成员函数
//c++空类默认产生的类成员函数
class Empty
{
public:
Empty();//缺省构造函数
Empty(const Empty&);//拷贝构造函数
~Empty();//析构函数
Empty& operator=(const Empty&);//赋值运算符
Empty* operator&();//取址运算符
const Empty* operator&() const;//取址运算符const
6判断
//1以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等
float a = 1.0f;
cout<<(int)a<<endl;//实际上是以浮点数 a为参数构造了一个整型数1,
cout<<(int&)a<<endl;//告诉编译器将a当作整数看(并没有做任何实质上的转换)
//0以整数形式存放和以浮点形式存放其内存数据是一样的,因此两者相等
float b = 0.0f;
cout<<(int)b<<endl;
cout<<(int&)b<<endl;
7、定义 int **a[3][4], 则变量占有的内存空间为:_____ ?
分析:由于优先级[]>*,所以a是存放二级指针的二维数组;
若(**a)[3][4],则a为指向二维数组的指针;
4、判断
struct Test
{
Test(int){}
Test(){}
void fun(){}
};
Test a(1);
a.fun();
Test b();//Error,默认构造函数初始化不加括号
b.fun();
8、数组和指针的区别
数组可以再静态存储区和栈上建立,指针可以指向任意类型的存储块
9、判断输出
main() { char *p1=“name”; char *p2; p2=(char*)malloc(20); memset (p2, 0, 20); while(*p2++ = *p1++); printf(“%s\n”,p2);//p2指向字符串末端,为空 }
10使用strcat()
main() { char *p1; char *p2; p1=(char *)malloc(25); p2=(char *)malloc(25); strcpy(p1,”Cisco”); strcpy(p2,“systems”); strcat(p1,p2);//注意空间的处理 printf(“%s”,p1); }尽管给p1,p2都分配了25字节的内存,但是使用strcat可以将函数连接在一起
11有哪几种情况只能用intialization list而不能用assignment?
当类中含有 const、reference 成员变量;基类的构造函数都需要初始化表。
12、初始化vector
vector< vector<int>> ivv;
ivv[0].push_back(1);
cout<<ivv[0][0]<<endl;
-----------------------------代码错误,没有初始化vector<int>就使用
vector<vector<int>> ivv;
ivv.push_back(vector<int>());
ivv[0].push_back(1);
cout<<ivv[0][0]<<endl;
------------------------------可以使用 vector<vector<int>> ivv(10);进行多数的初始化13.继承的优缺点
1、类继承是在编译时刻静态定义的,且可直接使用,
2、类继承可以较方便地改变父类的实现。(对于子类改变父类的实现)
缺点:
1、因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现
2、父类通常至少定义了子类的部分行为,父类的任何改变都可能影响子类的行为
3、如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。
这种依赖关系限制了灵活性并最终限制了复用性。
14、c++在头文件中进行类的声明,在对应的实现文件中进行类的定义有什么意义?
h为编译器提供一个索引,连接obj对象和主程序
编译器在编译的时候,如果需要,则去查找h,找到了h,再找对应的obj,就可以找到类的方法了
但是如果直接写入到同一个文件(例如hpp),主程序没有索引,也不清楚具体的类实现了没有,只能一次次重复的编译相同的代码,这样实际上没有把这个类该有的东西抽象出来