CC++典型题目总结Word下载.docx
- 文档编号:781462
- 上传时间:2023-04-29
- 格式:DOCX
- 页数:18
- 大小:22.56KB
CC++典型题目总结Word下载.docx
《CC++典型题目总结Word下载.docx》由会员分享,可在线阅读,更多相关《CC++典型题目总结Word下载.docx(18页珍藏版)》请在冰点文库上搜索。
static关键字是C,C++中都存在的关键字,它主要有三种使用方式,其中前两种在C/C++语言中使用,第三种只在C++中使用:
(1)局部静态变量(与auto变量的区别):
1.1存储空间分配不同
auto类型分配在栈上,属于动态存储类别,占用动态存储空间,函数调用结束后自动释放,而static分配在静态存储区,在程序整个运行期间都不释放.两者之间的作用域相同,但生存期不同.
1.2static局部变量在所处模块初次运行时进行初始化工作,且只初始化一次
1.3.对于局部静态变量,如果不赋初值,编译期会自动赋初值0或空字符,而auto类型的初值是不确定的.(对于C++中的class例外,class的对象实例如果不初始化,则会自动调用默认构造函数,不管是否是static类型
(2)外部静态变量/函数
为了限制全局变量/函数的作用域,函数或变量前加static,但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。
此时的static只是起作用域限制作用,限定作用域在本模块(文件)内部。
使用内部函数的好处是:
不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
(3)静态数据成员/成员函数
表示属于一个类而不是属于此类的任何特定对象的变量和函数,这是与普通成员函数的最大区别。
(1)引用必须被初始化,指针不必;
(2)引用初始化以后不能被改变,指针可以改变所指的对象;
(3)不存在指向空值的引用,但是存在指向空值的指针。
(4)由于没有所谓的空引用所以在使用前不需要进行测试其是否有值,而使用指针则需要测试其的有效性。
注释:
引用和指针的使用场所
一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。
如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。
还有一种情况,就是当你重载某个操作符时,你应该使用引用。
最普通的例子是操作符[]。
总之:
当你知道你必须指向一个对象并且不想改变其指向时,或者在重载操作符并为防止不必要的语义误解时,你不应该使用指针。
而在除此之外的其他情况下,则应使用指针。
全局变量储存在静态数据区,局部变量在堆栈。
一般来说,程序的局部变量存在于堆栈中,全局变量存在于静态区中,动态申请数据存在于堆中。
(1)程序的内存分配(一个由C/C++编译的程序占用的内存分为以下几个部分):
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。
注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区(.data),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bss)。
-程序结束后由系统释放。
4、文字常量区—常量字符串就是放在这里的(.rodata)。
程序结束后由系统释放。
5、程序代码区—存放函数体的二进制代码(.text)。
(2)例子程序
//main.cpp
inta=0;
//全局初始化区
char*p1;
//全局未初始化区
main()
{
intb;
//栈区
chars[]="
abc"
;
char*p2;
char*p3="
123456"
//"
123456\0"
在常量区,p3在栈区
staticintc=0;
//全局(静态)初始化区
p1=(char*)malloc(10);
p2=(char*)malloc(20);
//分配得来的10和20字节的区域就在堆区
strcpy(p1,"
);
//"
放在常量区,编译器可能会将它与p3所指向的"
优化成一个地方。
}
左右子树都是平衡二叉树且左右子树的深度差值的绝对值不大于1
堆栈溢出一般是由循环的递归调用导致的,如果使用大数据结构的局部变量,也可能导致堆栈溢出。
没有回收垃圾资源导致的是内存泄露最后内存耗尽。
堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据。
常见的不能声明为虚函数的有:
普通函数(非成员函数);
静态成员函数;
内联成员函数;
构造函数;
友元函数。
(1)普通函数(非成员函数)只能被overload,不能被override,因此编译器会在编译时邦定函数。
(2)构造函数不能被继承,因而不能声明为virtual函数;
构造函数一般是用来初始化对象,只有在一个对象生成之后,才能发挥多态作用,如果将构造函数声明为virtual函数,则表现为在对象还没有生成的情况下就使用了多态机制,因而是行不通的
(3)内联函数是为了在代码中直接展开,减少函数调用花费的代价,虚函数是为了在继承对象能够准确的执行自己的动作。
(再说了,inline函数在编译时被展开,虚函数在运行时动态绑定)
(4)静态成员函数不能被继承,只属于该类
(5)因为C++不支持友元函数的继承,对于没有继承特性的函数没有虚函数的说法。
7、写出floatx与“零值”比较的if语句
constfloatEPSINON=0.000001;
if((x<
=-EPSINON)&
&
(x>
=EPSINON)
returntrue;
else
returnfalse;
不可将浮点变量用“==”或“!
=”与数字比较,应该设法转化成“>
=”或“<
=”此类形式。
如下是错误的写法:
if(x==0.0)
if(x!
=0.0)
tcp/ip应用层/传输层/网络层/数据链路层/物理层
RARP协议(ReverseAddressResolutionProtocol),反向地址转换协议:
将局域网中某个主机的物理地址转换为IP地址;
ARP(AddressResolutionProtocol)地址解析协议用于将计算机的网络地址(IP地址32位)转化为物理地址(MAC地址48位)[RFC826]。
ARP协议是属于链路层的协议,在以太网中的数据帧从一个主机到达网内的另一台主机是根据48位的以太网地址(硬件地址)来确定接口的,而不是根据32位的IP地址。
内核(如驱动)必须知道目的端的硬件地址才能发送数据。
当然,点对点的连接是不需要ARP协议的。
答:
IP地址由两部分组成,网络号和主机号。
不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。
循环链表,用取余操作做
#include<
stdio.h>
#include<
memory>
conio.h>
#defineLENsizeof(structstu)
structstu
intdata;
structstu*next;
};
stu*line(intn)
intsum=1;
stu*head,*pf,*pb;
inti;
for(i=0;
i<
n;
i++)
pb=(stu*)malloc(LEN);
pb->
data=sum;
if(i==0)
pf=head=pb;
pf->
next=pb;
if(i==(n-1))
next=head;
pb->
next=NULL;
pf=pb;
sum++;
}
return(head);
intM,N,x,i;
stu*p,*q;
printf("
pleasescanfMandN(M<
N)"
scanf("
%d%d"
&
M,&
N);
p=line(N);
x=N;
while(x)
for(i=1;
M-1;
p=p->
next;
q=p->
%d\n"
q->
data);
p->
next=p->
next->
free(q);
x--;
getch();
return0;
switch(expression)中的expression必需是整型的或者是能准确转化为整型的类型。
eg:
byte,char,short,int或者枚举类型。
要求给出算法和思路
思路:
假设两个栈InStack和OutStack,且都为空。
可以认为栈InStack为提供入队列的功能,栈OutStack提供出队列的功能。
入队列:
入栈InStack
出队列:
1如果栈OutStack不为空,直接弹出栈OutStack的数据。
2如果栈OutStack为空
2.1若InStack不为空,则依次弹出栈InStack的数据,放入栈OutStack中,再弹出栈OutStack的数据。
2.2若InStack为空,则队列为空。
C++代码:
stack>
usingstd:
:
stack;
iostream>
cout;
endl;
template<
typenameT>
classQueue{
public:
boolempty()const{returnm_stack1.empty()&
m_stack2.empty();
size_tsize()const{returnm_stack1.size()+m_stack2.size();
}
voidpush(constT&
x);
//appendaelementtotail
voidpop();
//removeaelementfromhead
private:
stack<
T>
InStack;
OutStack;
//入队列
voidQueue<
push(constT&
x)
//入栈InStack
InStack.push(x);
//出队列
pop()
{
TOutData;
//如果栈OutStack为空:
若InStack不为空,则依次弹出栈InStack的数据,
//放入栈OutStack中,再弹出栈OutSatck的数据;
若InStack为空,则队列
//为空
if(OutStack.empty())
{
while(!
InStack.empty())
{
OutStack.push(InStack.top());
InStack.pop();
}
OutData=OutStack.top();
cout<
OutData<
//测试出队列
OutStack.pop();
//如果栈OutStack不为空,直接弹出栈OutStack的数据。
else
intmain()
Queue<
int>
q;
for(inti=1;
i<
=5;
++i)
q.push(i);
q.pop();
q.push(6);
q.push(7);
system("
pause"
return0;
--
用两个队列实现一个栈的功能
假设有两个队列m_queue1和m_queue2,且都为空。
入栈:
入队列m_queue1。
1、如果m_queue1不为空,则把m_queue1中的元素依次出队列并存入队列m_queue2中;
然后入队元素x进入队列m_queue1中;
判断m_queue2是否为空,不为空,则把m_queue2中的元素依次出队列并入队列m_queue1中。
这样既可以实现最后进来的元素能够放在对首,从而出队列时最先出队。
出栈:
将m_queue1的队头元素出队列即可。
示例代码如下
queue>
cassert>
usingnamespacestd;
classT>
classStack{
boolempty()const{returnm_queue1.empty()&
m_queue2.empty();
size_tsize()const{returnm_queue1.size()+m_queue2.size();
T&
top();
constT&
top()const;
queue<
m_queue1;
m_queue2;
T&
Stack<
top()
assert(!
m_queue1.empty());
returnm_queue1.front();
constT&
top()const
/*
*用队列实现栈的进栈操作:
队列m_queue1非空时,把其元素依次出队列
*并压入到队列m_queue2中,将进栈元素加入队列m_queue1中,然后判断
*m_queue2是否为空,不空的话把其元素依次出队列加入到队列m_queue2中
*,这样就可以实现后加入的元素总位于队首,也即后加入的元素总能够先出队列
*,即可成为栈顶元素!
*/
voidStack<
while(!
m_queue1.empty()){
constT&
val=m_queue1.front();
m_queue1.pop();
m_queue2.push(val);
m_queue1.push(x);
m_queue2.empty()){
val=m_queue2.front();
m_queue2.pop();
m_queue1.push(val);
m_queue1.pop();
s;
s.push(i);
cout<
s.top()<
endl;
s.pop();
s.push(6);
s.push(7);
system("
函数名:
atol
功能:
把字符串转换成长整型数
用法:
longatol(constchar*nptr);
黑盒:
针对系统功能的测试;
白合:
测试函数功能,各函数接口。
Eg:
unsignedchar*p1;
//p1是一个指向无符号字符型的指针
unsignedlong*p2;
//p2是一个指向无符号长整形的指针
p1=(unsignedchar*)0x801000;
//把0x80100作为指针的初值
p2=(unsignedlong*)0x810000;
//把0x81000作为指针的初值
请问p1+5=?
p2+5=?
代码分析见注释;
则:
p1+5=0x801000+5*sizeof(unsignedchar);
:
p2+5=0x810000=5*sizeof(unsignedlong);
Eg:
如果机器中unsignedchar为1字节,unsignedlong为4字节;
则,p1+5=0x801005;
p2+5=0x810014;
因为前者加1表示指针后移1个字节,后则加1表示后移4个字节。
解析:
删除运算是指删除单链表的第i个结点,即将第i-1个元素结点的指针域指向第i+1个元素结点。
要实现删除,首先要找到第i个元素结点前驱结点。
具体算法如下:
IntListDelete(SLNode*head,intI,DataType*x)
//删除带头结点单链表head的第i(0<
=i<
=size-1)个结点被删除结//点的数据域值由x带回,删除成功则返回1,失败则返回0
SLNode*p,*s;
intj=-1;
p=head;
while(p->
next!
=NULL&
j<
i-1)
//循环结束时指针p指向第i-1个结点
j++;
if(j!
=i-1)
{printf(“删除位置出错!
”);
return0;
s=p->
*x=s->
data;
next=p->
//删除
free(s);
//释放指针s所指结点的内存空间
return1;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CC 典型 题目 总结