C++学习(19)

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.

achar,-128~127,a=101,a+=27后溢出a=-128:

a=127时不溢出 01111111(127补码)

a+=1时溢出 10000000(-128补码)

 

sum += a;

sumint型,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 *pa本身是一个指针,而&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;
};

则构造函数中,成员变量一定要通过初始化列表来初始化的是: bc、  (此处可以参考学习点击打开链接

 

分析:构造函数初始化时必须采用初始化列表一共有三种情况:

1.需要初始化的数据成员是对象(继承时调用基类构造函数)

2.需要初始化const修饰的类成员

3.需要初始化引用成员数据

 

因为static属于类并不属于具体的对象,所以 static成员是不允许在类内初始化的,那么static const 成员是不是在初始化列表中呢?

答案是NO

一是static属于类,它在未实例化的时候就已经存在了,而构造函数的初始化列表,只有在实例化的时候才执行。

二是static成员不属于对象。我们在调用构造函数自然是创建对象,一个跟对象没直接关系的成员要它做什么呢。

 

分析二:初始化:从无到有,创建了新对象;如:string foo = "HelloWorld!"

赋值:没有创建新对象,而是对已有对象赋值。如:string bar; bar = "Hello World!"

 

有时我们可以忽略数据成员初始化和赋值之间的差异,但并非总能这样。

如果成员是const或者是引用的话,必须将其初始化。类似的,当成员属于某种类类型且该类没有定义默认构造函数时,也必须将这个成员初始化。(比如:类A中有一成员是B b,但类B中没有定义默认构造函数时,就必须对Ab成员进行初始化)

 

随着构造函数体一开始执行(即大括号里面部分),初始化就完成了(构造函数体内只是赋值操作)。因此,上面三种情况,比如初始化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]/				//,很明显数组越界了

 

8testArray是一个包含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指向了数组的首元素,++一次使得其指向下一个元素。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值