c语言笔试题,C++笔试题汇总(4)


已经n 次倒在c 语言面试的问题上,总结了一下,是由于基础知识不扎实。痛定思痛,决定
好好努力!
1.引言
本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题
的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。
许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一
个最简单的strcpy 函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好一
个strcpy 函数吗?我们都觉得自己能,可是我们写出的strcpy 很可能只能拿到10 分中的2
分。读者可从本文看到strcpy 函数从2 分到10 分解答的例子,看看自己属于什么样的层次。
此外,还有一些面试题考查面试者敏捷的思维能力。
分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的
深入剖析则可进一步增强自身的内功。
2.找错题
试题1:
void test1()
{
char string[10];
char* str1 = "0123456789";
strcpy( string, str1 );
}
试题2:
void test2()
{
char string[10], str1[10];
int i;
for(i=0; i<10; i++)
{
str1[i] = 'a';
}
strcpy( string, str1 );
}
试题3:
void test3(char* str1)
{
char string[10];
if( strlen( str1 ) <= 10 )
{
strcpy( string, str1 );
}
}
解答:
试题1 字符串str1 需要11 个字节才能存放下(包括末尾的’ 0’),而string 只有10 个字
节的空间,strcpy 会导致数组越界;
对试题2,如果面试者指出字符数组str1 不能在数组内结束可以给3 分;如果面试者指
出strcpy(string, str1)调用使得从str1 内存起复制到string 内存起所复制的字节数具有不确定
性可以给7 分,在此基础上指出库函数strcpy 工作方式的给10 分;
对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen 的结果未统计’
0’所占用的1 个字节。
剖析:
考查对基本功的掌握:
(1)字符串以’ 0’结尾;
(2)对数组越界把握的敏感度;
(3)库函数strcpy 的工作方式,如果编写一个标准strcpy 函数的总分值为10,下面给出
几个不同得分的答案:
2 分
void strcpy( char *strDest, char *strSrc )
{
while( (*strDest++ = * strSrc++) != ‘ 0’ );
}
4 分
void strcpy( char *strDest, const char *strSrc )
//将源字符串加const,表明其为输入参数,加2 分
{
while( (*strDest++ = * strSrc++) != ‘ 0’ );
}
7 分
void strcpy(char *strDest, const char *strSrc)
{
//对源地址和目的地址加非0 断言,加3 分
assert( (strDest != NULL) && (strSrc != NULL) );
while( (*strDest++ = * strSrc++) != ‘ 0’ );
}
10 分
//为了实现链式操作,将目的地址返回,加3 分!
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) && (strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘ 0’ );
return address;
}
从2 分到10 分的几个答案我们可以清楚的看到,小小的strcpy 竟然暗藏着这么多玄机,
真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy 啊!
(4)对strlen 的掌握,它没有包括字符串末尾的' 0'。
读者看了不同分值的strcpy 版本,应该也可以写出一个10 分的strlen 函数了,完美的
版本为:
int strlen( const char *str ) //输入参数const
{
assert( strt != NULL ); //断言字符串地址非0
int len;
while( (*str++) != ' 0' )
{
len++;
}
return len;
}
试题4:
void GetMemory( char *p )
{
p = (char *) malloc( 100 );
}
void Test( void )
{
char *str = NULL;
GetMemory( str );
strcpy( str, "hello world" );
printf( str );
}
试题5:
char *GetMemory( void )
{
char p[] = "hello world";
return p;
}
void Test( void )
{
char *str = NULL;
str = GetMemory();
printf( str );
}
试题6:
void GetMemory( char **p, int num )
{
*p = (char *) malloc( num );
}
void Test( void )
{
char *str = NULL;
GetMemory( &str, 100 );
strcpy( str, "hello" );
printf( str );
}
试题7:
void Test( void )
{
char *str = (char *) malloc( 100 );
strcpy( str, "hello" );
free( str );
... //省略的其它语句
}
解答:
试题4 传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并
不能真正的改变传入形参的值,执行完
char *str = NULL;
GetMemory( str );
后的str 仍然为NULL;
试题5 中
char p[] = "hello world";
return p;
的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序
员常犯的错误,其根源在于不理解变量的生存期。
试题6 的GetMemory 避免了试题4 的问题,传入GetMemory 的参数为字符串指针的指
针,但是在GetMemory 中执行申请内存及赋值语句
*p = (char *) malloc( num );
后未判断内存是否申请成功,应加上:
if ( *p == NULL )
{
...//进行申请内存失败处理
}
试题7 存在与试题6 同样的问题,在执行
char *str = (char *) malloc(100);
后未进行内存是否申请成功的判断;另外,在free(str)后未置str 为空,导致可能变成一
个“野”指针,应加上:
str = NULL;
试题6 的Test 函数中也未对malloc 的内存进行释放。
剖析:
试题4~7 考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回
答其中50~60 的错误。但是要完全解答正确,却也绝非易事。
对内存操作的考查主要集中在:
(1)指针的理解;
(2)变量的生存期及作用范围;
(3)良好的动态内存申请和释放习惯。
再看看下面的一段程序有什么错误:
swap( int* p1,int* p2 )
{
int *p;
*p = *p1;
*p1 = *p2;
60
*p2 = *p;
}
在swap 函数中,p 是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++
中DEBUG 运行时提示错误“Access Violation”。该程序应该改为:
swap( int* p1,int* p2 )
{
int p;
p = *p1;
*p1 = *p2;
*p2 = p;
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.内功题
试题1:分别给出BOOL,int,float,指针变量与“零值”比较的if 语句(假设变量名
为var)
解答:
BOOL 型变量:if(!var)
int 型变量: if(var==0)
float 型变量:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
指针变量: if(var==NULL)
剖析:
考查对0 值判断的“内功”,BOOL 型变量的0 判断完全可以写成if(var==0),而int 型变
量也可以写成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运
行,但是未能清晰地表达程序的意思。
一般的,如果想让if 判断一个变量的“真”、“假”,应直接使用if(var)、if(!var),表明其
为“逻辑”判断;如果用if 判断一个数值型变量(short、int、long 等),应该用if(var==0),表
明是与0 进行“数值”上的比较;而判断指针则适宜用if(var==NULL),这是一种很好的编程
习惯。
浮点型变量并不精确,所以不可将float 变量用“==”或“!=”与数字比较,应该设法转化
成“>=”或“<=”形式。如果写成if (x == 0.0),则判为错,得0 分。
试题2:以下为Windows NT 下的32 位C++程序,请计算sizeof 的值
void Func ( char str[100] )
{
sizeof( str ) = ?
}
void *p = malloc( 100 );
sizeof ( p ) = ?
解答:
sizeof( str ) = 4
sizeof ( p ) = 4
剖析:
Func ( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了本身的
内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自
减等操作,可以被修改。
数组名的本质如下:
(1)数组名指代一种数据结构,这种数据结构就是数组;
例如:
char str[10];
cout << sizeof(str) << endl;
输出结果为10,str 指代数据结构char[10]。
(2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、
自减等操作,不能被修改;
char str[10];
str++; //编译出错,提示str 不是左值
(3)数组名作为函数形参时,沦为普通指针。
Windows NT 32 位平台下,指针的长度(占用内存的大小)为4 字节,故sizeof( str ) 、
sizeof ( p ) 都为4。
试题3:写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。另外,当你写
下面的代码时会发生什么事
least = MIN(*p++, b);
解答:
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
MIN(*p++, b)会产生宏的副作用
剖析:
这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是
它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进
行的是一对一的替换。
程序员对宏定义的使用要非常小心,特别要注意两个问题:
(1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。所以,严格地讲,下述解
答:
#define MIN(A,B) (A) <= (B) ? (A) : (B)
#define MIN(A,B) (A <= B ? A : B )
都应判0 分;
(2)防止宏的副作用。
宏定义#define MIN(A,B) ((A) <= (B) ? (A) : (B))对MIN(*p++, b)的作用结果是:
((*p++) <= (b) ? (*p++) : (*p++))
这个表达式会产生副作用,指针p 会作三次++自增操作。
除此之外,另一个应该判0 分的解答是:
#define MIN(A,B) ((A) <= (B) ? (A) : (B));
这个解答在宏定义的后面加“;”,显示编写者对宏的概念模糊不清,只能被无情地判0
分并被面试官淘汰。
试题4:为什么标准头文件都有类似以下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus
extern "C" {
#endif
解答:
头文件中的编译宏
#ifndef __INCvxWorksh
#define __INCvxWorksh
#endif
的作用是防止被重复引用。
作为一种面向对象的语言,C++支持函数重载,而过程式语言C 则不支持。函数被C++
编译后在symbol 库中的名字与C 语言的不同。例如,假设某个函数的原型为:
void foo(int x, int y);
该函数被C 编译器编译后在symbol 库中的名字为_foo,而C++编译器则会产生像
_foo_int_int 之类的名字。_foo_int_int 这样的名字包含了函数名和函数参数数量及类型信息,
C++就是考这种机制来实现函数重载的。
为了实现C 和C++的混合编程,C++提供了C 连接交换指定符号extern "C"来解决名字
匹配问题,函数声明前加上extern "C"后,则编译器就会按照C 语言的方式将该函数编译为
_foo,这样C 语言中就可以调用C++的函数了。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
试题5:编写一个函数,作用是把一个char 组成的字符串循环右移n 个。比如原来是
“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”
函数头是这样的:
//pStr 是指向以' 0'结尾的字符串的指针
//steps 是要求移动的n
void LoopMove ( char * pStr, int steps )
{
//请填充...
}
解答:
正确解答1:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
strcpy ( tmp, pStr + n );
strcpy ( tmp + steps, pStr);
*( tmp + strlen ( pStr ) ) = ' 0';
strcpy( pStr, tmp );
}
正确解答2:
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) - steps;
char tmp[MAX_LEN];
memcpy( tmp, pStr + n, steps );
memcpy(pStr + steps, pStr, n );
memcpy(pStr, tmp, steps );
}
剖析:
这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大
程度上简化程序编写的工作量。
最频繁被使用的库函数包括:
(1) strcpy
(2) memcpy
(3) memset
试题6:已知WAV 文件格式如下表,打开一个WAV 文件,以适当的数据结构组织WAV
文件头并解析WAV 格式的各项信息。
WAVE 文件格式说明表
1 #i nclude “filename.h”和#i nclude 的区别?
答:对于#i nclude 编译器从标准库开始搜索filename.h
对于#i nclude “filename.h”编译器从用户工作路径开始搜索filename.h
2 头文件的作用是什么?
答:一、通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提
供头文件和二进制的库即可。用户只需
要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的
代码。
二、头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,
编译器就会指出错误,这一简单的规
则能大大减轻程序员调试、改错的负担。
3 C++函数中值的传递方式有哪几种?
答:C++函数的三种传递方式为:值传递、指针传递和引用传递。
4 内存的分配方式的分配方式有几种?
答:一、从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期
间都存在。例如全局变量。
二、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这
些存储单元自动被释放。栈内
存分配运
算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
三、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,
程序员自己负责在何时用free
或delete 释放
内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
5 实现双向链表删除一个节点P,在节点P 后插入一个节点,写出这两个函数;
答:双向链表删除一个节点P
template void list::delnode(int p)
{
int k=1;
listnode *ptr,*t;
ptr=first;
while(ptr->next!=NULL&&k!=p)
{
ptr=ptr->next;
k++;
}
t=ptr->next;
cout<<"你已经将数据项"ptr->next=ptr->next->next;
length--;
delete t;
}
在节点P 后插入一个节点:
template bool list::insert(type t,int p)
{
listnode *ptr;
ptr=first;
int k=1;
while(ptr!=NULL&&k{
ptr=ptr->next;
k++;
}
if(ptr==NULL&&k!=p)
return false;
else
{
listnode *tp;
tp=new listnode;
tp->data=t;
tp->next=ptr->next;
ptr->next=tp;
length++;
return true;
}
}
6 写一个函数,将其中的\t 都转换成4 个空格。
void change(char* pstr)
{
while(*pstr++ != '\0')
{
if (*pstr == '\t')
}
}
7 Windows 程序的入口是哪里?写出Windows 消息机制的流程.
答:Winmain(),它定义窗口界面和消息循环。设置全局资源->登记实例->调入全局资源->初始化
应用->消息循环(解释消息,分发消息)
8 如何定义和实现一个类的成员函数为回调函数?
1). 不使用成员函数,直接使用普通C 函数,为了实现在C 函数中可以访问类的成员变量,可以使
用友元操作符(friend),在C++中将该C 函数说明为类的友元即可。这种处理机制与普通的C 编程
中使用回调函数一样。
2). 使用静态成员函数,静态成员函数不使用this 指针作为隐含参数,这样就可以作为回调函数了。
9 C++里面是不是所有的动作都是main()引起的?如果不是,请举例.
答:在运行c++程序时,通常从main()函数开始执行。因此如果没有main(),程序将不完整,编译
器将指出未定义main()函数。
例外情况:如, 在windows 编程中,可以编写一个动态连接库(dll)模块,这是其他windows 程
序可以使用的代码。由于
DLL 模块不是独立的程序,因此不需要main().用于专用环境的程序--如机器人中的控制器芯片--
可能不需要main().但常规的
独立程序都需要main().
10 C++里面如何声明const void f(void)函数为C 程序中的库函数?
11 下列哪两个是等同的
int b;
A const int* a = &b;
B const* int a = &b;
C const int* const a = &b;
D int const* const a = &b;
12 内联函数在编译时是否做参数类型检查
13 三个float:a,b,c
问值
(a+b)+c==(b+a)+c
(a+b)+c==(a+c)+b
14 把一个链表反向填空
void reverse(test* head)
{
test* pe = head;
test* ps = head->next;
while(ps)
{
pe->next = ps->next;
ps->next = head;
head = ps;
ps = pe->next;
}
}
15 设计一个重采样系统,说明如何anti-alias
16 某个程序在一个嵌入式系统(200M 的CPU,50M 的SDRAM)中已经最化了,换到另一个系统
(300M 的CPU,50M 的SDRAM)中运行,还需要优化吗?
17. 下面哪种排序法对12354 最快
a quick sort
b.buble sort
c.merge sort
18. 哪种结构,平均来讲,获取一个值最快
a. binary tree
b. hash table
c. stack
19 请问C++的类和C 里面的struct 有什么区别?
答:c++的类的成员默认情况下是私有的,c 的struct 的成员默认情况下是公共的.
20 请讲一讲析构函数和虚函数的用法和作用?
答:析构函数的作用是当对象生命期结束时释放对象所占用的资源。析构函数用法:析构函数是特
殊的类成员函数
它的名字和类名相同,没有返回值,没有参数不能随意调用也没有重载。只是在类对象生命期结束时
有系统自动调用。
虚函数用在继承中,当在派生类中需要重新定义基类的函数时需要在基类中将该函数声明为虚函数,
作用为使程序支持动态联遍。
21 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?
答:一些变量整个程序中都是可见的,它们称为全局变量,一些变量在函数内部定义且只在函数中可
知,则称为局部变量。
全局变量由编译器建立且存放在内存的全局数据区,局部变量存放在栈区
22 一些寄存器的题目,主要是寻址和内存管理等一些知识。
23 8086 是多少尉的系统?在数据总线上是怎么实现的?
24 多态。overload 和override 的区别。
答:重载在相同范围(同一个类中),函数名字相同,参数不同,virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,不同的范围,函数名字相同,参数相同,基类函数必须有virtual
关键字。
<>
25.完成下列程序
*
*.*.
*..*..*..
*...*...*...*...
*....*....*....*....*....
*.....*.....*.....*.....*.....*.....
*......*......*......*......*......*......*......
*.......*.......*.......*.......*.......*.......*.......*.......
#i nclude
using namespace std;
const int n = 8;
main()
{
int i;
int j;
int k;
for(i = n; i >= 1; i--)
{
for(j = 0; j < n-i+1; j++)
{
cout<<"*";
for(k=1; k < n-i+1; k++)
{
cout<<".";
}
}
cout< }
system("pause");
}
26 完成程序,实现对数组的降序排序
#i nclude
using namespace std;
void sort(int* arr, int n);
int main()
{
int array[]={45,56,76,234,1,34,23,2,3};
sort(array, 9);
for(int i = 0; i <= 8; i++)//曾经在这儿出界
cout<}
void sort(int* arr, int n)
{
int temp;
for(int i = 1; i < 9; i++)
{
for(int k = 0; k < 9 - i; k++)//曾经在这儿出界
{
if(arr[k] < arr[k + 1])
{
temp = arr[k];
arr[k] = arr[k + 1];
arr[k + 1] = temp;
}
}
}
}
27 费波那其数列,1,1,2,3,5……编写程序求第十项。可以用递归,也可以用其他方法,但要
说明你选择的理由。
非递归
#i nclude
using namespace std;
int Pheponatch(int n);
main()
{
int Ph = Pheponatch(10);
cout< system("pause");
}
int Pheponatch(int n)
{
int elem;
int n1 = 1;
int n2 = 1;
if(n == 1 || n ==2)
return 1;
else
{
for(int i = 3; i <= n; i++)
{
elem = n1 + n2;
n1 = n2;
n2 = elem;
}
return elem;
}
}
递归
#i nclude
using namespace std;
int Pheponatch(int n);
main()
{
int n;
cin>>n;
int ph = Pheponatch(n);
cout< system("pause");
}
int Pheponatch(int n)
{
if(n <= 0)
exit(-1);
else
if(n == 1 || n ==2)
return 1;
else
return Pheponatch(n - 1) + Pheponatch(n - 2);
}
28 下列程序运行时会崩溃,请找出错误并改正,并且说明原因。
#i nclude
#i nclude
typedef struct{
TNode* left;
TNode* right;
int value;
} TNode;
TNode* root=NULL;
void append(int N);
int main()
{
append(63);
append(45);
append(32);
append(77);
append(96);
append(21);
append(17); // Again, 数字任意给出
}
void append(int N)
{
TNode* NewNode=(TNode *)malloc(sizeof(TNode));
NewNode->value=N;
if(root==NULL)
{
root=NewNode;
return;
}
else
{
TNode* temp;
temp=root;
while((N>=temp.value && temp.left!=NULL) || (N
))
{
while(N>=temp.value && temp.left!=NULL)
temp=temp.left;
while(N
temp=temp.right;
}
if(N>=temp.value)
temp.left=NewNode;
else
temp.right=NewNode;
return;
}
}
29. A class B network _disibledevent=>if n>1 otherwise 1 the order of
this algorithm is .
a. log (n) b. n c. n^2 d. n^n
36. The number of 1’s in the binary representation of 3*4096+ 15*256+5*16+3 are .
a. 8 b. 9 c. 10 d. 12
37.设计函数int atoi(char *s)。
38.int i=(j=4,k=8,l=16,m=32); printf(“%d”, i); 输出是多少?
39.解释局部变量、全局变量和静态变量的含义。
40.解释堆和栈的区别。
栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似
于数据结构中的栈。
堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS 回收。注意它与数据结构中
的堆是两回事,分配方式倒是类似于
链表.
41.论述含参数的宏与函数的优缺点。
42. 以下三条输出语句分别输出什么?[C 易]
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; // 输出什么?
43. 非C++内建型别A 和B,在哪几种情况下B 能隐式转化为A?[C++中等]
答:
a. class B : public A { ……} // B 公有继承自A,可以是间接继承的
b. class B { operator A( ); } // B 实现了隐式转化为A 的转化
c. class A { A( const B& ); } // A 实现了non-explicit 的参数为B(可以有其他带默认值的参数)
构造函数
d. A& operator= ( const A& ); // 赋值操作,虽不是正宗的隐式类型转换,但也可以勉强算一个
44. 以下代码中的两个sizeof 用法有问题吗?[C 易]
void UpperCase( char str[] ) // 将str 中的小写字母转换成大写字母
{
for( size_t i=0; i if( 'a'<=str[i] && str[i]<='z' )
str[i] -= ('a'-'A' );
}
char str[] = "aBcDe";
cout << "str 字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;
UpperCase( str );
cout << str << endl;
45. 以下代码有什么问题?[C 难]
void char2Hex( char c ) // 将字符以16 进制表示
{
char ch = c/0x10 + '0'; if( ch > '9' ) ch += ('A'-'9'-1);
char cl = c%0x10 + '0'; if( cl > '9' ) cl += ('A'-'9'-1);
cout << ch << cl << ' ';
}
char str[] = "I love 中国";
for( size_t i=0; i char2Hex( str[i] );
cout << endl;
46. 以下代码有什么问题?[C++易]
struct Test
{
Test( int ) {}
Test() {}
void fun() {}
};
void main( void )
{
Test a(1);
a.fun();
Test b();
b.fun();
}
*** Test b();//定义了一个函数
47. 以下代码有什么问题?[C++易]
cout << (true?1:"1") << endl;
8. 以下代码能够编译通过吗,为什么?[C++易]
unsigned int const size1 = 2;
char str1[ size1 ];
unsigned int temp = 0;
cin >> temp;
unsigned int const size2 = temp;
char str2[ size2 ];
48. 以下代码中的输出语句输出0 吗,为什么?[C++易]
struct CLS
{
int m_i;
CLS( int i ) : m_i(i) {}
CLS()
{
CLS(0);
}
};
CLS obj;
cout << obj.m_i << endl;
49. C++中的空类,默认产生哪些类成员函数?[C++易]
答:
class Empty
{
public:
Empty(); // 缺省构造函数
Empty( const Empty& ); // 拷贝构造函数
~Empty(); // 析构函数
Empty& operator=( const Empty& ); // 赋值运算符
Empty* operator&(); // 取址运算符
const Empty* operator&() const; // 取址运算符const
};
50. 以下两条输出语句分别输出什么?[C++难]
float a = 1.0f;
cout << (int)a << endl;
cout << (int&)a << endl;
cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?
float b = 0.0f;
cout << (int)b << endl;
cout << (int&)b << endl;
cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?
51. 以下反向遍历array 数组的方法有什么错误?[STL 易]
vector array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 3 );
for( vector::size_type i=array.size()-1; i>=0; --i ) // 反向遍历array 数组
{
cout << array[i] << endl;
}
52. 以下代码有什么问题?[STL 易]
typedef vector IntArray;
IntArray array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 2 );
array.push_back( 3 );
// 删除array 数组中所有的2
for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor )
{
if( 2 == *itor ) array.erase( itor );
}
53. 写一个函数,完成内存之间的拷贝。[考虑问题是否全面]
答:
void* mymemcpy( void *dest, const void *src, size_t count )
{
char* pdest = static_cast( dest );
const char* psrc = static_cast( src );
if( pdest>psrc && pdest {
for( size_t i=count-1; i!=-1; --i )
pdest[i] = psrc[i];
}
else
{
for( size_t i=0; i pdest[i] = psrc[i];
}
return dest;
}
int main( void )
{
char str[] = "0123456789";
mymemcpy( str+1, str+0, 9 );
cout << str << endl;
system( "Pause" );
return 0;
}
54 线程与进程的区别
进程:(在批处理系统中)是资源分配的最小单位
线程:最独立运行的最小单位。
一个进程中可以一个或多个线程。当系统的资源分配给进程,线程从所属的进程中得到保证能运行的
很少的资源,线程完成后把资源“还”给进程,只有当进程中的线程全都完成后,进程才把占有的系统
的资源释放(进程挂起除外)。
Top
55:请你分别划划OSI 的七层网络结构图,和TCP/IP 的五层结构图?
56:请你详细的解释一下IP 协议的定义,在哪个层上面,主要有什么作用? TCP 与UDP 呢?
IP 协议是网络层的协议,它实现了Internet 中自动路由的功能,即寻径的功能,TCP 协议是一个传
输性的协议它向下屏蔽了IP 协议不可靠传输的特性,向上提供一个可靠的点到点的传输,UDP 提供
的是一种无连接的服务,主要考虑到很多应用不需要可靠的连接,但需要快速的传输
57:请问交换机和路由器分别的实现原理是什么?分别在哪个层次上面实现的?
交换机用在局域网中,交换机通过纪录局域网内各节点机器的MAC 地质(物理地址)就可以实现传递
报文,无需看报文中的IP 地质。路由器识别不同网络的方法是通过识别不同网络的网络ID 号(IP 地
址的高端部分)进行的,所以为了保证路由成功,每个网络都必须有一个唯一的网络编号。路由器通
过察看报文中IP 地址,来决定路径,向那个子网(下一跳)路由,也就是说交换机工作在数据链路层
看MAC 地址,路由器工作在网际层看IP 地质
但是由于现在网络设备的发展,很多设备既有交换机的功能有由路由器的功能(交换试路由器)使得两
者界限越来越模糊。
58:请问C++的类和C 里面的struct 有什么区别?
59:请讲一讲析构函数和虚函数的用法和作用?
60:全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?
全局变量是整个程序都可访问的变量,谁都可以访问,生存期在整个程序从运行到结束(在程序结束
时所占内存释放),而局部变量存在于模块(子程序,函数)中,只有所在模块可以访问,其他模块不
可直接访问,模块结束(函数调用完毕),局部变量消失,所占据的内存释放。
全局变量分配在全局数据段并且在程序开始运行的时候被加载. 局部变量则分配在堆栈里面。
61:一些寄存器的题目,主要是寻址和内存管理等一些知识。
2、交换机用在局域网中,交换机通过纪录局域网内各节点机器的MAC 地质(物理地址)就可以实现
传递报文,无需看报文中的IP 地质。路由器识别不同网络的方法是通过识别不同网络的网络ID 号(IP
地址的高端部分)进行的,所以为了保证路由成功,每个网络都必须有一个唯一的网络编号。路由器
通过察看报文中IP 地址,来决定路径,向那个子网(下一跳)路由,也就是说交换机工作在数据链路
层看MAC 地址,路由器工作在网际层看IP 地质
但是由于现在网络设备的发展,很多设备既有交换机的功能有由路由器的功能(交换试路由器)使得两
者界限越来越模糊。
3、IP 协议是网络层的协议,它实现了Internet 中自动路由的功能,即寻径的功能,TCP 协议是一
个传输性的协议它向下屏蔽了IP 协议不可靠传输的特性,向上提供一个可靠的点到点的传输,UDP
提供的是一种无连接的服务,主要考虑到很多应用不需要可靠的连接,但需要快速的传输
4、
Test b();//定义了一个函数
62:8086 是多少位的系统?在数据总线上是怎么实现的?
<>
63.怎样用最快的方法判断链表是否有环?
64.c++中引用和指针有什么不同?指针加上什么限制等于引用?
答:1 引用被创建的时候必须被初始化,而指针不是必需的。2 引用在创建后就不能改变引用的关
系,而指针在初始化后可以随时指向
其它的变量或对象。3 没有NULL 引用,引用必须与合法的存储单元关联,而指针可以是NULL。
65.做的项目,遇到的困难,怎样解决?
69.操作符重载
class CMyObject:pulic CObject
{
Public:
CMyObject();
CMyObject &operator=(const CMyObject &my);
private:
CString strName;
int nId:
};
请重载赋值操作符
70.链表
Struct structList
{
int value;
structList *pHead;
}
Struct LinkedList *pMyList;
请编写删除链表的头、尾和第n 个节点的程序
71.用Socket API 制作一个聊天程序,通讯协议使用tcp/ip。要求有简单界面即可,支持多人聊天。
72.如果有过工作经验,请说明在先前公司的工作以及离职原因(如无,请说明毕业后的个人展望)
********************************************************************
*******
73 对于C++中类(class) 与结构(struct)的描述正确的为:
A,类中的成员默认是private 的,当是可以声明为public,private 和protected,结构中定义的成员
默认的都是public;
B,结构中不允许定义成员函数,当是类中可以定义成员函数;
C,结构实例使用malloc() 动态创建,类对象使用new 操作符动态分配内存;
D,结构和类对象都必须使用new 创建;
E,结构中不可以定义虚函数,当是类中可以定义虚函数.
F,结构不可以存在继承关系,当是类可以存在继承关系.
答:A,D,F
74,两个互相独立的类:ClassA 和ClassB,都各自定义了非静态的公有成员函数PublicFunc() 和
非静态的私有成员函数PrivateFunc();
现在要在ClassA 中增加定义一个成员函数ClassA::AdditionalPunction(ClassA a,ClassB b);
则可以在AdditionalPunction(ClassA x,ClassB y)的实现部分(函数功能体内部)
出现的合法的表达是最全的是:
A,x.PrivateFunc();x.PublicFunc();y.PrivateFunc();y.PublicFunc();
B,x.PrivateFunc();x.PublicFunc();y.PublicFunc();
C,x.PrivateFunc();y.PrivateFunc();y.PublicFunc();
D,x.PublicFunc();y.PublicFunc();
答:B
75,C++程序下列说法正确的有:
A,对调用的虚函数和模板类都进行迟后编译.
B,基类与子类中函数如果要构成虚函数,除了要求在基类中用virtual 声名,而且必须名字相同且参数
类型相同返回类型相同
C,重载的类成员函数都必须要:或者返回类型不同,或者参数数目不同,或者参数序列的类型不同.
D,静态成员函数和内联函数不能是虚函数,友员函数和构造函数也不能是虚函数,但是析构函数可以
是虚函数.
答:A
********************************************************************
*******
76,C++中的类与结构的区别?
77,构造函数和析构函数是否可以被重载,为什么?
答:构造函数可以被重载,析构函数不可以被重载。因为构造函数可以有多个且可以带参数,而析构
函数只能有一个,且不能带参数。
78,一个类的构造函数和析构函数什么时候被调用,是否需要手工调用?
答:构造函数在创建类对象的时候被自动调用,析构函数在类对象生命期结束时,由系统自动调用。
1 #i nclude “filename.h”和#i nclude 的区别?
答:#i nclude “filename.h”表明该文件是用户提供的头文件,查找该文件时从当前文件目录开始;
#i nclude 表明这个文件是一个工程或标准头文件,查找过程会检查预定义的目录。
2 头文件的作用是什么?
答:一、通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提
供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎
么实现的。编译器会从库中提取相应的代码。
二、头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,
编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。
3 C++函数中值的传递方式有哪几种?
答:C++函数的三种传递方式为:值传递、指针传递和引用传递。
4 内存的分配方式的分配方式有几种?
答:一、从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期
间都存在。例如全局变量。
二、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这
些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量
有限。
三、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,
程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,
但问题也最多。
5 实现双向链表删除一个节点P,在节点P 后插入一个节点,写出这两个函数;
答:双向链表删除一个节点P
template void list::delnode(int p)
{
int k=1;
listnode *ptr,*t;
ptr=first;
while(ptr->next!=NULL&&k!=p)
{
ptr=ptr->next;
k++;
}
t=ptr->next;
cout<<"你已经将数据项"ptr->next=ptr->next->next;
length--;
delete t;
}
在节点P 后插入一个节点:
template bool list::insert(type t,int p)
{
listnode *ptr;
ptr=first;
int k=1;
while(ptr!=NULL&&k{
ptr=ptr->next;
k++;
}
if(ptr==NULL&&k!=p)
return false;
else
{
listnode *tp;
tp=new listnode;
tp->data=t;
tp->next=ptr->next;
ptr->next=tp;
length++;
return true;
}
}
Tags:  中兴c语言笔试题 华为c语言笔试题 华为c笔试题 c笔试题 c语言笔试题

延伸阅读

最新评论

发表评论