在32位编译器上,设有定义
1
|
char
* strl =
"Hello"
,str2[ ] =
"Hello"
;
|
则以下语句
1
|
printf(
"%d %d"
,sizeof(str),sizeof(str2));
|
A.定义静态数据成员时前边要加修饰符 static
B.静态数据成员要在类体外进行初始化
C.引用静态数据成员时,要在静态数据成员名前加<类名>和作用域运算符
D.静态数据成员不是所有对象所共用的。
A.不可以声明虚函数
B.不可以定义友元函数
C.不可以进行构造函数重载
D.不可以实例化
请在程序的下画线处填入正确的内容并将下画线删除,使程序得出正确的结果。
试题程序。
#include<stdio.h>
#include<stdlib.h>
#define N 8
typedef struct list
{
int data;
struct list *next;
} SLIST;
void fun(SLIST *h, int x)
{
SLIST *p, *q, *s;
s = (SLIST *)malloc(sizeof(SLIST));
s->data = 1 ;
q = h;
p = h->next;
while (p != NULL && x > p->data)
{
q = 2 ;
p = p->next;
}
s->next = p;
/********** found **********/
q->next = 3 ;
}
SLIST *crealist(int *a)
{
SLIST *h, *p, *q; int i;
h = p = (SLIST *)malloc(sizeof(SLIST));
for (i = 0; i < N; i++)
{
q = (SLIST *)malloc(sizeof(SLIST));
q->data = a[i]; p->next = q; p = q;
}
p->next = 0;
return h;
}
void outlist(SLIST *h)
{
SLIST *p;
p = h->next;
if (p == NULL)
printf("\nThe list is NULL!\n");
else
{
printf("\nHead");
do
{
printf("->%d", p->data);
p = p->next;
}
while (p != NULL);
printf("NULL");
printf("->End\n");
}
}
main( )
{
SLIST *head; int x;
int a[N] = (11, 12, 15, 18, 19, 22, 25, 29);
head = creatlist(a);
printf("\nThe list before inserting:\n");
oulist(head);
printf("\nEnter a number: "); scanf("%d", &x);
fun(head, x);
printf("\nThe list after intserting:\n");
outlist(head);
}
5、
内联函数在运行时是将该函数的目标代码插入每个调用该函数的地方
内联函数在编译时是将该函数的目标代码插入每个调用该函数的地方
类的内联函数必须在类体内定义
类的内联函数必须在类体外通过关键字inline定义
没有区别
++p更好一些
p++更好一些
和编译器有关
{
int elem;
node* next;
};
void difference(node** LA , node* LB)
{
node *pa , *pb , *pre , *q;
pre = NULL;
(1) //1
while(pa) {
pb = LB;
while( 2 ) //2
pb = pb->next;
if ( 3 ) //3
{
if(!pre)
*LA = ( 4 ) ; //4
else
( 5 )= pa->next; //5
q = pa;
pa = pa->next;
free(q);
}
else {
( 6 ); //6
pa = pa->next;
}
}
}
若有以下程序
1
2
3
4
5
6
7
8
9
|
#include <stdio. h>
main( )
{
int
a =
0
,b =
0
,c =
0
,d;
c = (a + = b,,b + = a); / * 第
4
行 * /
d = c; / * 第
5
行 * /
; / * 第
6
行 * /
;printf(
"%d,%d,%d\n"
,a,b,c);/ * 第
7
行 * /
}
|
第4行
第5行
第6行
第7行
int add(int a ,int b ,int c)
int add(double a , double b)
double add(double a , double b)
int add(int a , int b)
1
2
3
4
5
6
|
int fun (char *s)
{
char *p=s;
while(*p++);
return p-s-1;
}
|
计算字符串的位(bit)数
复制一个字符串
求字符串的长度
求字符串存放的位置
A fun(int);
A*p;
int fun(A);
A obj;
try块不可以省略
可以使用多重catch块
finally块可以省略
catch块和finally块可以同时省略
虚函数是可以内联的,可以减少函数调用的开销提高效率
类里面可以同时存在函数名和参数都一样的虚函数和静态函数
父类的析构函数是非虚的,但是子类的析构函数是虚的,delete子类对象指针会调用父类的析构函数
以上都不对
flag&=~2
flag|=2
flag^=2
flag>>=2
基类的构造函数
派生类中子对象的初始化
基类的子对象初始化
派生类中一般数据成员的初始化
int *a;
extern const int array[256];
const int &ra;
typedef void (*FUN)();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
class
A
{
public
:
A()
{
printf(
"A "
);
}
/*virtual*/
~A()
{
printf(
"deA "
);
}
};
class
B
{
public
:
B()
{
printf(
"B "
);
}
~B()
{
printf(
"deB "
);
}
};
class
C:
public
A,
public
B
{
public
:
C()
{
printf(
"C "
);
}
~C()
{
printf(
"deC "
);
}
};
int
main()
{
A *a =
new
C();
delete a;
return
0
;
}
|
A B C deA
C A B deA
A B C deC
C A B deC
obj3.show3();
obj2.show2();
obj1.show1();
obj3.show1();
文件指针是程序中用FILE定义的指针变量
文件指针就是文件位置指针,表示当前读写数据的位置
文件指针指向文件在计算机中的存储位置
把文件指针传给fscanf函数,就可以向文本文件中写入任意的字符
1
2
3
|
int
a[
2
][
2
][
3
]= { {{
1
,
2
,
3
},{
4
,
5
,
6
}},{{
7
,
8
,
9
},{
10
,
11
,
12
}}};
int
*ptr=(
int
*)(&a+
1
);
printf(“%d %d”, *(
int
*)(a+
1
), *(ptr-
1
));
|
7 12
1 6
1 3
7 9
sizeof(str1)=4,因为str1是一个指针变量,在32位编译器中指针是4字节;sizeof(str2)=6,str2字符数组中有5个字符,再加一个结束符'\0',所以共占6个字节;
类的静态成员与类本身直接相关,而不是与类的各个对象保持关联。在成员的声明之前加上关键字static使得其与类关联在一起,和其他成员一样,静态成员可以是public的或private。我们使用作用域运算符直接访问静态成员。通常情况下,类的静态成员不应该在类的内部初始化,然而,我们可以为静态成员提供const整数类型的类内初始值,必须是常量表达值。
一、纯虚函数定义.纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0” 二、引入原因: 1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。 2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。 为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重载以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。 三、相似概念: 1、多态性 指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。 a.编译时多态性: 通过函数重载和运算符重载来实现的。 b 运行时多态性:通过继承和虚函数来实现的。 2、虚函数 虚函数是在基类中被声明为virtual,并在派生类中重新定义的成员函数,可实现成员函数的动态重载 纯虚函数的声明有着特殊的语法格式:virtual 返回值类型成员函数名(参数表)=0;
请注意,纯虚函数应该只有声明,没有具体的定义,即使给出了纯虚函数的定义也会被编译器忽略。
3、抽象类
包含纯虚函数的类称为抽象类。由于抽象类包含了没有定义的纯虚函数,所以不能定义抽象类的对象。 在C++中,我们可以把只能用于被继承而不能直接创建对象的类设置为抽象类(Abstract Class)。
之所以要存在抽象类,最主要是因为它具有不确定因素。我们把那些类中的确存在,但是在父类中无法确定具体实现的成员函数称为纯虚函数。纯虚函数是一种特殊的虚函数,它只有声明,没有具体的定义。抽象类中至少存在一个纯虚函数;存在纯虚函数的类一定是抽象类。存在纯虚函数是成为抽象类的充要条件。抽象类是不完整的,它只能用作基类。在 面向对象方法中,抽象类主要用来进行类型隐藏和充当全局变量的角色。抽象类具有以下特性:
抽象类不能实例化。 抽象类可以包含抽象方法和抽象访问器。 不能用 sealed 修饰符修饰抽象类,因为这两个修饰符的含义是相反的。 采用 sealed 修饰符的类无法继承,而 abstract 修饰符要求对类进行继承。 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实际实现。
说明:1.新建了一个结点s,那么把x放入s的data域中. 所以就是s->next = x;2.记住,单链表中插入一个结点一定要知道插入结点处的前驱结点.所以q,p实际上是构造了一个前(q指针),一个后(p指针)的两个相邻指针,所以 q = p; p = p->next; 但是因为在前面已经说明了q是指向头结点,而p是指向第一个数据结点,那么此时其实已经使得q,p构成了一前一后的两个相邻指针,所以q也可以按照自己的步伐一步步的走,即q = q->next;3.单链表结点插入操作
内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数。正确答案选B,C和D都不完全,如果将C和D中的“必须”换成“可以”,那么C和D也是对的。
指针++和i++是类似的。因为i++在计算时,会用到中间变量存储,会占用更多的内存和时间。所以++i更好。
(1) pa = *LA;
(2) pb && pa->elem != pb->elem
(3) pb
(4) pa->next
(5) pre->next
(6) pre = pa
#include<stdio.h>
struct
node{
int
elem;
struct
node* next;
};
/*
本题的解法思路较简单:
因为要求集合A和集合B的差集(A-B),结果保存在集合A中.
所以我们取出集合A中每一个元素,然后在集合B中寻找(代码22行所实现) 找到即删除此节点 否则保留
此时while循环跳出只有两种情况,pb为NULL或者 pa->elem==pb->elem
当pb不为null时,即找出集合A和集合B的公有元素,此时要删除这个元素
pre(实现删除节点之后的链接)
当pre为NULL时,说明是首次找到A和B的公有元素,此时 *LA指向pa->next 所以*LA仍然是头结点
当pre不为NULL时, pre指向pa->next,顺利实现删除节点的链接
*/
void
difference(node** LA,node* LB){
node*pa,*pb,*pre,*q;
pre=NULL;
pa=*LA;
/*LA是指向指针的指针,pa指向集合的元素*/
while
(pa){
pb=LB;
/*pb指向集合B的元素*/
while
(pb && pa->elem!=pb->elem)
/*在链表LB中寻找与pa所指元素相等的节点*/
pb=pb->next;
if
(pb){
/*pa所指元素与pb所指元素相等*/
if
(!pre){
*LA=pa->next;
}
else
{
pre->next=pa->next;
}
q=pa;
/*求差集 所以要删除pa节点*/
pa=pa->next;
free
(q);
}
else
{
pre=pa;
pa=pa->next;
}
}
}
构造函数是不可继承的。因此,派生类的构造函数必须通过调用基类的构造函数初始化基类成员,不能够在派生类初始化列表直接初始化基类的成员,“越级初始化”。派生类的构造函数的一般格式为:
派生类名(形参表):基类名1(形参表1),基类名2(形参表2)···
{···}
注意事项:
(1)在创建派生类对象时,先调用基类的构造函数,然后调用派生类的构造函数;撤销对象时,析构函数被调用的顺序则相反。
(2)若派生类中包含对象成员,则派生类的构造函数初始化成员列表中既要列出基类的构造函数也要列出对象的构造函数。派生类定义对象时,先调用基类的构造函数,再调用对象的构造函数,最后调用派生类的构造函数。
16.
typedef void (*FUN)(); 定义FUN为一个函数指针,指向一个函数,该函数返回值为void,参数为空
17.如果按题中所说 加入virtual,那么输出的顺序是ABC deC deB deA。由于析构函数是虚函数,动态调用,那么会调用C的析构函数,由于C继承与A和B,所以先调用A B的析构,最后调用自己的。
如果A的析构函数不是虚函数,那么只会调用A的析构函数。
18.
19.文件指针指向的是一块内存区域,这块区域存储着打开的文件的相关信息,包括文件读取指针当前位置、文件读取缓冲区大小等信息,并不是指向文件的。fscanf是从文件中格式化读取,fprintf才是向文件中格式化写入。
20.
答案:A
*(int*)(a+1) 指向数组 a[2] 的第二个元素中的第一个,也就是内部第二层大括号的第一个元素
*(ptr-1)整个数组的最后一个元素,因为 (int *)(&a+1); 指向整个数组的下一个位置