PS:今天上午,非常郁闷,有很多简略基础的问题搞得我有些迷茫,哎,代码几天不写就忘。目前又不当COO,还是得用心记代码哦!
一、选择题
1. 若用数组名作为函数调用时的实参,则实际上传递给形参的是( A )
A. 数组首地址
B. 数组的第一个元素值
C. 数组中全部元素的值
D. 数组元素的个数
2. 有关函数重载的正确说法是( B )
A. 函数名不同,但参数的个数和类型相同
B. 函数名相同,但参数的个数不同或参数的类型不同
C. 函数名相同,参数的个数和类型相同
D. 函数名相同,函数的返回值不同,而与函数的参数和类型无关
3. 已知int a[3][2]={3,2,1}; 则表达式“a[0][0]/a[0][1]/a[0][2]”的值是(B)
A. 0.166667
B. 1
C. 0
D. 错误的表达式
4. 要制止修改指针p本身,又要制止修改p所指向的数据,这样的指针应定义为( D )
A. const char *p="ABCD";
B. char const *p="ABCD";
C. char *const p="ABCD";
D. const char * const p="ABCD";
5. 对静态成员的不正确描述是( C )
A. 静态成员不属于对象,是类的共享成员
B. 静态数据成员要在类外定义和初始化
C. 调用静态成员函数时要通过类或对象激活,所以静态成员函数拥有this指针
D. 非静态成员函数也可以操作静态数据成员
6. 下面函数原型声明中,( B )声明了fun为纯虚函数
A. void fun()=0;
B. virtual void fun()=0;
C. virtual void fun();
D. virtual void fun(){};
7. 在排序方法中,关键码比较次数与记载地初始排列无关的是( D )
A. Shell排序
B. 归并排序
C. 直接插入排序
D. 选择排序
8. 一个栈的入栈序列是A,B,C,D,E,则栈的弗成能的输出序列是( C )
A. EDCBA;
B. DECBA;
C. DCEAB;
D. ABCDE
二、填空题
1.求下面函数的返回值 _____
int func(x)
{
int countx = 0;
while(x)
{
countx ++;
x = x&(x-1);
}
return countx;
}
假设x = 9999。 答案:8
思绪:将x转化为2进制,看含有的1的个数。
2. 以下三条输出语句分离输出什么 _____
char str1[] = "abc";
char str2[] = "abc";
const char str3[] = "abc";
const char str4[] = "abc";
const char* str5 = "abc";
const char* str6 = "abc";
cout << boolalpha << ( str1==str2 ) << endl; // 输出什么?
cout << boolalpha << ( str3==str4 ) << endl; // 输出什么?
cout << boolalpha << ( str5==str6 ) << endl; // 输出什么?
答:分离输出false,false,true。str1和str2都是字符数组,每一个都有其自己的存储区,它们的值则是各存储区首地址,不等;str3和str4同上,只是按const语义,它们所指向的数据区不能修改。str5和str6并非数组而是字符指针,其实不分配存储区,其后的“abc”以常量情势存于静态数据区,而它们自己仅是指向该区首地址的指针,相称。
3.请给出如下程序的结果
int a = 3;
int b = a << 3;
a = __3__ , b = __24__ 。
4.请给出如下程序的结果
#define MAX_NUM 100+200
int nTemp = MAX_NUM*10;
则 Temp = __2100__ 。
5. 程序的运行结果为___
void Func(char str[100])
{
printf("%d\n", sizeof(str));
}
答:4
分析: 指针长度
6. 程序的运行结果为____
int sum(int a)
{
auto int c=0;
static int b=3;
c+=1;
b+=2;
return(a+b+c);
}
void main()
{
int I;
int a=2;
for(I=0;I<5;I++)
{
printf("%d,", sum(a));
}
}
// static会保存上次结果,记住这一点,剩下的自己写
输出:8,10,12,14,16,
7. 程序的运行结果为____
unsigned short array[]={1,2,3,4,5,6,7};
int i = 3;
*(array + i) = ?
答: 4
8.写出以下程序的执行结果:
static char *s[]= {"black","white","yellow","violet"};
char **ptr[]={s+3,s+2,s+1,s},***p=ptr;
**++p;
printf("%s\n",*++*++p+3);
答:low
分析:注意指针++的区分,以及*p+1与*(p+1)的区分
三、问答题
1、头文件中的 ifndef/define/endif 干什么用?
答:避免该头文件被重复引用。
2. C++中为什么用模板类。
答:(1)可用来创立动态增长和减小的数据结构
(2)它是类型无关的,因此具有很高的可复用性。
(3)它在编译时而不是运行时检查数据类型,保障了类型安全
(4)它是平台无关的,可移植性
(5)可用于基本数据类型
3. 说一说C与C++的内存分配方法?
(1)从静态存储区域分配。内存在程序编译的时候就已分配好,这块内存在程序的全部运行期间都存在,如全局变量,static变量。
(2)在栈上创立。在执行函数时,函数内局部变量的存储单元都可以在栈上创立,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令会合,效率很高,但是分配的内存容量无限。
(3)从堆上分配(动态内存分配)程序在运行的时候用malloc或new申请恣意多少的内存,程序员担任在何时用free或delete释放内存。动态内存的生存期自己决定,应用非常灵巧。
4. 关键字static的作用是什么?
这个简略的问题很少有人能回答完整。在C语言中,关键字static有三个显著的作用:
(1)在函数体,一个被声明为静态的变量在这一函数被调用过程当中维持其值稳定。
(2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数拜访,但不能被模块外其它函数拜访。它是一个当地的全局变量。
(3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被制约在声明它的模块的当地范围内应用。
大多数应试者能正确回答第一部分,一部分能正确回答第二部分,同是很少的人能懂得第三部分。这是一个应试者的严峻的缺点,因为他明显不懂得当地化数据和代码范围的好处和重要性。
5. 面向对象的三个基本特征,并简略叙述之?
如果说生命是一座庄严的城堡,如果说生命是一株苍茂的大树,如果说生命是一只飞翔的海鸟。那么,信念就是那穹顶的梁柱,就是那深扎的树根,就是那扇动的翅膀。没有信念,生命的动力便荡然无存;没有信念,生命的美丽便杳然西去。(划线处可以换其他词语)
(1)封装:将客观事物抽象成类,每一个类对自身的数据和方法实行protection(private, protected,public)
(2) 继承:广义的继承有三种实现情势:实现继承(指应用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体应用父窗体的外观和实现代码)、接口继承 (仅应用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方法。
(3)多态:是将父对象设置成为和一个或更多的他的子对象相称的技术,赋值之后,父对象就可以根据以后赋值给它的子对象的特性以不同的方法运作。简略的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
6. 局部变量是否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,须要应用"::" ;局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
7. 重载(overload)和重写(overried,有的书也叫做“覆盖”)的区分?
答:从定义上来说:
重载:是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
重写:是指子类重新定义复类虚函数的方法。
从实现道理上来说:
重载:编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。
重写:当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。
8. New delete 与malloc free 的联系与区分?
答案:都是在堆(heap)上进行动态的内存操作。用malloc函数须要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor.
9. 什么是死锁?其条件是什么?怎样避免死锁?
答案:死锁的概念:在两个或多个并发进程中,如果每一个进程持有某种资源而又都等待别的进程释放它或它们现在保持着的资源,在未转变这类状态之前都不能向前推动,称这一组进程产生了死锁。艰深地讲,就是两个或多个进程被无限期地阻塞、相互等待的一种状态。
死锁产生的原因主要是:? 系统资源不足;? 进程推动次序合法。
产生死锁的必要条件:
(1)互斥(mutualexclusion),一个资源每次只能被一个进程应用;
(2)弗成抢占(nopreemption),进程已获得的资源,在未应用完之前,不能强行褫夺;
(3)占有并等待(hold andwait),一个进程因请求资源而阻塞时,对已获得的资源保持不放;
(4)环形等待(circularwait),若干进程之间构成一种首尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必定建立,而只要上述条件之一不满足,就不会发生死锁。
死锁的消除与防备:理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、防备和消除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件建立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要避免进程在处于等待状态的情况下占用资源。因此,对资源的分配要赐与合理的计划。
死锁的处理策略:鸵鸟策略、防备策略、避免策略、检测与恢复策略。
10. ARP 是地址解析协议,简略语言解释一下工作道理。
答:
( 1 )首先,每一个主机都会在自己的 ARP 缓冲区中建立一个 ARP 列表,以表现 IP 地址和 MAC 地址之间的对应关系。
( 2 )当源主机要发送数据时,首先检查 ARP 列表中是不是有对应 IP 地址的目标主机的 MAC 地址,如果有,则直接发送数据,如果没有,就向本网段的所有主机发送 ARP 数据包,该数据包包括的内容有:源主机 IP 地址,源主机 MAC 地址,目标主机的 IP 地址。
( 3 )当本网络的所有主机收到该 ARP 数据包时,首先检查数据包中的 IP 地址是不是是自己的 IP 地址,如果不是,则疏忽该数据包,如果是,则首先从数据包中掏出源主机的 IP 和 MAC 地址写入到 ARP 列表中,如果已存在,则覆盖,然后将自己的 MAC 地址写入 ARP 响应包中,告知源主机自己是它想要找的 MAC 地址。
( 4 )源主机收到 ARP 响应包后。将目标主机的 IP 和 MAC 地址写入 ARP 列表,并利用此信息发送数据。如果源主机一直没有收到 ARP 响应数据包,表现 ARP 查询失败。
广播发送 ARP 请求,单播发送 ARP 响应。
11、请定义一个宏,比较两个数a、b的大小,不能应用大于、小于、if语句
#define Max(a,b) ( a/b)?a:b
12. 分离写出BOOL,int,float,指针类型的变量a 与“零”的比较语句。
答案:
BOOL : if ( !a ) or if(a)
int : if ( a == 0)
float : const EXPRESSION EXP = 0.000001
if ( a < EXP && a >-EXP)
pointer : if ( a != NULL) or if(a == NULL)
13. 已知strcpy的函数原型:char *strcpy(char *strDest, const char *strSrc)其中strDest 是目标字符串,strSrc 是源字符串。不调用C++/C 的字符串库函数,请编写函数 strcpy。
答案:
/*
编写strcpy函数(10分)
已知strcpy函数的原型是
char *strcpy(char *strDest, const char *strSrc);
其中strDest是目标字符串,strSrc是源字符串。
(1)不调用C++/C的字符串库函数,请编写函数 strcpy
(2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?
答:为了 实现链式表达式。 // 2分
例如 int length = strlen( strcpy( strDest, “hello world”) );
*/
#include <assert.h>
#include <stdio.h>
char*strcpy(char*strDest, constchar*strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL)); // 2分
char* address = strDest; // 2分
while( (*strDest++=*strSrc++) !='\0' )// 2分
NULL;
return address ; // 2分
}
14. 已知链表的头结点head,写一个函数把这个链表逆序
Node * ReverseList(Node *head) //链表逆序
{
if ( head == NULL || head->next == NULL )
return head;
Node *p1 = head ;
Node *p2 = p1->next ;
Node *p3 = p2->next ;
p1->next = NULL ;
while ( p3 != NULL )
{
p2->next = p1 ;
p1 = p2 ;
p2 = p3 ;
p3 = p3->next ;
}
p2->next = p1 ;
head = p2 ;
return head ;
}
15. 写个函数交换两个指针的值。
答案
:
#include
using namespace std;
void ex(char **a,char **b)
{
char *c;
c=*a;
*a=*b;
*b=c;
}
int main()
{
char *pt=”pt\n”;
char *pt_another=”pt_another\n”;
cout<<pt<<pt_another;
ex(&pt,&pt_another);
cout<<pt<<pt_another;
system(“pause”);
}
文章结束给大家分享下程序员的一些笑话语录: 《诺基亚投资手机浏览器UCWEB,资金不详或控股》杯具了,好不容易养大的闺女嫁外国。(心疼是你养的吗?中国创业型公司创业初期哪个从国有银行贷到过钱?)