1、 通过封装,对象的全部属性和操作结合在一起,形成一个整体;
通过封装,一个对象的实现细节被尽可能地隐藏起来;(不可见)
通过封装,每个对象都成为相对独立的实体;
2、 数值型常量有整型常量,实型常量,不论是整型常量还是实型常量都有正值和负值之分;
在C语言的预编译处理中,可以用符号名代表一个常量,定义时不必指定常量类型;
常量的定义就是常量是在程序运行过程中值不能够被改变的量;
3、下列程序的输出结果:72.
#include<iostream>
#include<cstdlib >
using namespace std;
int main() {
char a=101;
int sum=200;
a+=27;sum+=a;
cout<<sum<<endl;
}
分析:char类型的范围是-128---+127,当a+=27,之后a的值超出可表示范围会变为-128.
a为char型,-128~127,a=101,a+=27后溢出a=-128:
a=127时不溢出 01111111(127补码)
a+=1时溢出 10000000(-128补码)
sum += a;
sum为int型,a(char提升为int)
10000000------->11111111 11111111 11111111 10000000(-128补码)
所以,sum=200-128:00000000 00000000 00000000 11001000
+11111111 11111111 11111111 10000000
----------------------------------------------------------------------------------
00000000 00000000 00000000 01001000 (64+8=72)
3、 具有相同类型的指针类型变量p与数组a,不能进行的操作是:D
A p=a;// a表示数组a的地址指针,a和p类型相同,所以p=a操作正确;
B *p=a[0];//*p表示p指向的值,a[0]表示数组的第一个值,两者类型相同,可赋值,正确;
C p=&a[0];//&a[0]是数组第一个元素的地址,与a相同,也是指针,可赋值,正确;
D p=&a;// 设数组a[3],指针为int *p,a本身是一个指针,而&a的类型int(*)[3],而不是int *,但p不一定是int型的,所以p=&a错误。
数组名是一级指针,数组地址为二级指针。
4、有一个类A,其数据成员如下:
class A {
……
private:
int a;
public:
const int b;
float* &c;
static const char * d;
static double *e;
};
则构造函数中,成员变量一定要通过初始化列表来初始化的是: b,c、 (此处可以参考学习点击打开链接)
分析:构造函数初始化时必须采用初始化列表一共有三种情况:
1).需要初始化的数据成员是对象(继承时调用基类构造函数);
2).需要初始化const修饰的类成员;
3).需要初始化引用成员数据;
因为static属于类并不属于具体的对象,所以 static成员是不允许在类内初始化的,那么static const 成员是不是在初始化列表中呢?
答案是NO
一是static属于类,它在未实例化的时候就已经存在了,而构造函数的初始化列表,只有在实例化的时候才执行。
二是static成员不属于对象。我们在调用构造函数自然是创建对象,一个跟对象没直接关系的成员要它做什么呢。
分析二:初始化:从无到有,创建了新对象;如:string foo = "HelloWorld!"
赋值:没有创建新对象,而是对已有对象赋值。如:string bar; bar = "Hello World!"
有时我们可以忽略数据成员初始化和赋值之间的差异,但并非总能这样。
如果成员是const或者是引用的话,必须将其初始化。类似的,当成员属于某种类类型且该类没有定义默认构造函数时,也必须将这个成员初始化。(比如:类A中有一成员是B b,但类B中没有定义默认构造函数时,就必须对A中b成员进行初始化)
随着构造函数体一开始执行(即大括号里面部分),初始化就完成了(构造函数体内只是赋值操作)。因此,上面三种情况,比如初始化const或者引用类型的数据成员的唯一机会就是通过构造函数初始值,形如:ConstRef::ConstRef(int n): i(n), j(n) { }
5、存在性就是变量生命周期。可见性就是能访问。内部静态类就是只有在包含该类的上下文里才能使用的类,比如在一个类内部定义的类,但它是全局存在的。因此内部静态类的可见性和存在性不一致。
6、转义字符的定义为:所有的 ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。
7、对下述代码执行后,会出现:数组越界问题。
charszMsisdn[MAX_LEN_MSISDN-1]; //建立一个长度为MAX_LEN_MSISDN-1的数组,下标范围应为0~MAX_LEN_MSISDN-2
szMsisdn[sizeof(szMsidn)='\0']; //sizeof(szMsidn)得到的是数组长度,为MAX_LEN_MSISDN-1,那么szMsisdn[sizeof(szMsidn)]= szMsisdn[MAX_LEN_MSISDN-1]/ //,很明显数组越界了
8、testArray是一个包含8个元素的int型数组,请问sizeof(testArray)/sizeof(testArray[0])=8、
分析:sizeof(testArray)是数组大小8*4=32;
sizeof(testArray[0])是testArray[0]的大小4;
所以sizeof(testArray)/sizeof(testArray[0])=8
#include<iostream>
#include<cstdlib>
using namespace std;
int main() {
inttestArray[8]={0};
cout<<sizeof(testArray)/sizeof(testArray[0]);
}
9、
#include<iostream>
#include<cstdlib>
using namespace std;
int main() {
char*a[]={"work","at","alibaba"};
char**pa=a;
cout<<pa<<endl;
cout<<*pa<<endl;
cout<<**pa<<endl;
pa++;
cout<<*pa<<endl;
}
打印结果:
0x22fe30
work
w
at
分析:首先对编译器来说没有数组这一概念,数组都被看成指针,所以a[]就是*a,那么就是**a换成了**pa,pa即是a,换个名字而已,根据数组的++,也就是取a[1][]的值,即“at”。
数组里存储的是指针;
而我们创建的变量pa相当于指向指针的指针是一个二级指针;
所以我们联系之前所学的内容,其实呢就是pa指向了数组的首元素,++一次使得其指向下一个元素。