1. 在构造函数XB的下列定义中,正确的是(B)

 

C++学习(60)_html

B XB::XB(int a,int b):Xa(a),y(b){}

分析:引用A类型的变量,必须初始化列表。

 

2. 以下代码中,A的构造函数和析构函数分别执行了几次:10、10

A *pa = new A[10];

delete []pa;

A*pa = new A[10];  调用new分配原始未类型化的内存,在分配的内存上运行构造函数,即运行10次构造函数,对新建的对象进行初始化构造,返回指向分配并构造好的对象的数组指针

delete []pa; 对数组中的10个对象分别运行析构函数,然后释放申请的空间

 

3.’\0’的ASCII码是0

4.math.h的abs返回值(C)

A 不可能是负数    B不可能是正数    C 都有可能     D 不可能是0

因为负数的范围比正数大一个,比如8位的二进制,可以表示范围为-128~127。所以abs(-128)可能并不能表示为128,所以只能返回原值

 

5.关于do循环体while(条件表达式):

条件表达式的执行次数与循环体的执行次数无关。

分析:可能一次都没执行条件,可能执行相同的次数

do {

if()

break;

//continue;

}while();

 

6.要使指针变量p指向二维数组A的第一个元素,正确的赋值:

C p=A[0] 或p=&A[0][0];

分析:这道题假设A[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};,A是二维数组名,包含3行,即3个行元素,即A[0],A[1],A[2]。而每个行元素又是一个一维数组,包含4个元素。 从二维数组角度来看,A代表二维数组首元素的地址,现在的首元素不是一个简单的整形元素,而是由4个整形元素组成的一维数组,因此A代表是首行(序号为0的行)的首地址。A+1代表序号为1的首地址。A+1指向A[1],A+1的值是A[1]的首地址。 A[0],A[1],A[2]既然是一维数组名,而c语言规定了数组名代表数组首元素地址,因此A[0]代表一维数组A[0]中0第0列元素地址,即&aA[0][0]。A[1]代表&A[1][0]等等。

具体详细见谭浩强的C语言,P245~P247。

如果A是二维数组,则A[i]是一维数组名,只是一个地址,并不代表一个元素值。 A是二维数组名,指向一维数组A[0],即0行首地址。 A[0]代表0行0列元素地址。 重新看一下题目,还是C都满足题意要求。因为数组名只代表了0行首地址,并不是第一个元素的地址,尽管数值是一样的,但是意义不同。

 

7.给出以下定义,下列哪些说法是合法的?A

const char *p1=”hello”;

char *const p2=”world”;

A p1++;    Bp1[2]=’w’    C p2[2]=’l’ D p2++;

分析:只能选A。
p1是指向字符常量的指针,p1本身不是常量,所以p1++合法,A正确。
p2本身是指针常量,可以指向非常量的字符。但是"hello"这样声明的字符串是存储在只读存储区的,不可修改,所以B,C,D都错误。

C是错误的,P2是字符指针,且用字符串初始化,具有只读属性,所以不能直接赋值,编译可以通过,但是运行会出错。

 

a是合法的

b对const内容进行写入,非法

c对常量区内存进行写入,非法

d对常量指针进行修改,非法

8. 数组可以也动态实现,int n; cin>>n,int *p=new int[n]; 指针传递也是传地址

 

9.字符串复制函数strcpy(字符数组1,字符数组2),字符数组1的长度应该大于字符数组2的长度。 (正确)


10 处理a.html文件时,以下哪行伪代码可能导致内存越界或者抛出异常(B)


int totalBlank = 0;
         int blankNum = 0;
         int taglen = page.taglst.size();
A       for(int i = 1; i < taglen-1; ++i)
        {
                 //check blank
B             while(page.taglst[i] == "<br>" && i < taglen)
               {
C                       ++totalBlank;
D                       ++i;
               }
E             if(totalBlank > 10)
F                      blankNum += totalBlank;
G             totalBlank = 0;
        }


注意:以下代码中taglen是html文件中存在元素的个数,a.html中taglen的值是15,page.taglst[i]取的是a.html中的元素,例如page.taglst[1]的值是<html>


a.html的文件如下:


<html>
<title>test</title>
<body>
<div>aaaaaaa</div>
</body>
</html>
<br>
<br>
<br>
<br>
<br>

  • A
B
  • C
  • D
  • E
  • F
  • G


分析 

跟while条件判断顺序有关。若先执行比较语句page.taglst[i] == "<br>",则此时可能已经超出了数组的范围,即内存越界了。所以应该先进行i的大小判断,若此时条件不成立,也就不会再执行后面的其他并列条件了(&&)。


11 在一个64位的操作系统中定义如下结构体:


1



2



3



4



5



6


struct st_task



{



uint16_t id;



uint32_t value;



uint64_t timestamp;



};



同时定义fool函数如下:


1



2



3



4



5



6



7


void fool()



{



st_task task = {};



uint64_t a =  0x00010001 ;



memcpy(&task, &a, sizeof(uint64_t));



printf( "%11u,%11u,%11u" , task.id, task.value, task.timestamp);



}



上述fool()程序的执行结果为(A)

A 1 0  0


考点:字节对齐,低地址到高地址


    因为字节对齐的原因,所以id占用4个字节,value和timestamp分别是4个字节、8个字节。虽然id占用四个字节的地址,但是只有低两位地址的数值有效(字节对齐的机制,即value存储时的地址对4(自身对齐值)求余应为0)。所以id为 0001 0001,高四位无效,所以为0001,value与timestamp分别为0.


  比如:地址从0x0000开始,id存储地址本来为0x0000-0x0001,但value存储地址要从0x0004开始,因为0x0004%4==0,所以id存储地址为0x0000-0x0003, value存储地址为0x0004-0x0007, timestamp存储地址为0x0008-0x000F. 所以id == 0x00010001,去掉高4位,id=0x0001,其余为0.