C/C++面试题(二)

来源:互联网 发布:中信淘宝v卡积分规则 编辑:程序博客网 时间:2024/05/16 15:25

1、写一个“ 标准” 宏 MIN

#define MIN(a,b) ((a)<=(b)?(a):(b))
注意:在调用时一定要注意这个宏定义的副作用,如下调用:
((++*p)<=(x)?(++*p):(x)。
p 指针就自加了两次,违背了 MIN 的本意。

2、一个指针可以是 volatile 吗

可以,因为指针和普通变量一样,有时也有变化程序的不可控性。常见例:子中断服务子程序修改
一个指向一个 buffer 的指针时,必须用 volatile 来修饰这个指针。
说明:指针是一种普通的变量,从访问上没有什么不同于其他变量的特性。其保存的数值是个整型
数据,和整型变量不同的是,这个整型数据指向的是一段内存地址。

3、a 和&a 有什么区别
请写出以下代码的打印结果,主要目的是考察 a 和&a 的区别。
#include<stdio.h>
void main( void )
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
return;
}
输出结果: 2, 5。
注意:数组名 a 可以作数组的首地址,而&a 是数组的指针。思考,将原式的 int *ptr=(int *)(&a+1);
改为 int *ptr=(int *)(a+1);时输出结果将是什么呢?(2,1)

4、简述 C、 C++程序编译的内存分配情况
C、 C++中内存分配方式可以分为三种:
( 1) 从静态存储区域分配:
内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在。 速度快、 不容易出错,
因为有系统会善后。 例如全局变量, static 变量等。
( 2) 在栈上分配:
在执行函数时,函数内局部变量的存储单元都在栈上创建,函数执行结束时这些存储单元自动被释
放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
( 3) 从堆上分配:
即动态内存分配。程序在运行的时候用 malloc 或 new 申请任意大小的内存,程序员自己负责在何
时用 free 或 delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活。 如果在堆上分配了空间,
就有责任回收它,否则运行的程序会出现内存泄漏, 另外频繁地分配和释放不同大小的堆空间将会产生
堆内碎块。
一个 C、 C++程序编译时内存分为 5 大存储区:堆区、栈区、全局区、文字常量区、程序代码区。
详解:http://blog.csdn.net/u012942555/article/details/48876447

5、简述 strcpy、 sprintf 与 memcpy 的区别
三者主要有以下不同之处:
(1) 操作对象不同, strcpy 的两个操作对象均为字符串, sprintf 的操作源对象可以是多种数据类型,
目的操作对象是字符串, memcpy 的两个对象就是两个任意可操作的内存地址,并不限于何种数据类型。
(2) 执行效率不同, memcpy 最高, strcpy 次之, sprintf 的效率最低。
(3) 实现功能不同, strcpy 主要实现字符串变量间的拷贝, sprintf 主要实现其他数据类型格式到字
符串的转化, memcpy 主要是内存块间的拷贝。
说明: strcpy、 sprintf 与 memcpy 都可以实现拷贝的功能,但是针对的对象不同,根据实际需求,来
选择合适的函数实现拷贝功能。
6、如何定义一个int类型的指针数组,数组元素个数为10个:(C)
  • int a[10];
  • int (*a)[10];
  • int *a[10];
  • int (*a[10])(int);
A为int类型的数组
B为int类型的数组的指针
C为int类型的指针的数组

D为函数指针的数组,[]有限级高于*,说明a是一个数组,数组元素的类型为函数指针

A:一个长度为10的数组,数组内部放着10个int数据
C:一个长度为10的数组,数组内部放着10个int*数据,就是A中数组内部存储的不是数据而是指针就是地址
B:a是指向一个长度为10的数组整体的指针,a的指针步长就是这个数组的长度
D:首先 *a[10]为一个和C一样的数组里面存储了10个指针数据,只是这里的这些指针数据是一个返回值为int,参数为int的的函数的入口地址,
总共是10个函数的地址存储在数组中

7、什么是平衡二叉树?

平衡二叉树又称AVL树。平衡二叉树或者是空树,或者是具有如下特征的二叉排序树。

(1)左子树和右子树的深度之差的绝对值不超过1.

(2)左子树和右子树也是平衡二叉树。

8、冒泡排序算法的时间复杂度和空间复杂度是什么?

时间复杂度是O(n^2)。空间复杂度是O(1)。

详解:http://blog.csdn.net/u012942555/article/details/48323979

9、Internet物理地址和IP地址转换采用什么协议?

 ARP (Address Resolution Protocol)(地址解析协议)

10、IP地址的编码分为哪俩部分?

IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。

11、C中不能做switch()的参数类型是:

switch的参数类型不能为实型。switch 后面的表达式不能跟double,float,long,String ,boolean,可以接int,short,byte,char!

使用switch语句必须注意一下几个方面:

(1)其中常量表达式的值必须是整型、字符型或者枚举类型,各语句序列允许有多条语句,按复合语句处理,但不需{}界定,这是与if的区别。

(2)对于满足条件之后执行的语句,执行完后必须用break跳出,否则继续往下执行,直到碰到break或switch语句结束。

(3)特殊情况下,如果switch表达式对应的多个值都需要执行相同的语句,多个case可共用一组执行语句。

12、局部变量能否和全局变量重名?

答:能,局部会屏蔽全局。要用全局变量,需要使用"::",局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。

13、如何引用一个已经定义过的全局变量?

答:extern
可以用引用头文件的方式,也可以用 extern 关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变写错了,那么在编译期间会报错,如果你用 extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
14、全局变量可不可以定义在可被多个.C 文件包含的头文件中?为什么?
答:可以,在不同的 C 文件中以 static 形式来声明同名全局变量。可以在不同的 C 文件中声明同名的全局变量,前提是其中只能有一个 C 文件中对此变量赋初值,此时连接不会出错。
15、语句for(;1;) for(;;)  for(;0;)有什么问题?它是什么意思?
答:for(;1;)和for(;;)和 while(1)相同,是死循环。for(;0;)体内语句没有执行的机会。
16、do……while 和 while……do 有什么区别?
答:do……while循环一遍再判断,while……do判断以后再循环。
17、请写出下列代码的输出内容
#include<stdio.h>
main()
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;
}
答:10,12,120如果d=10*(++a);结果为10,12,130如果d=10*(a++);结果为10,12,120

18、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static 函数与普通函数有什么区别?
全局变量(外部变量)的说明之前再冠以 static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时, 非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。static 函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件static 全局变量与普通的全局变量有什么区别:static 全局变量只初使化一次,防止在其他文件单元中被引用;
static 局部变量和普通局部变量有什么区别:static 局部变量只被初始化一次,下一次依据上一次结果值;
static 函数与普通函数有什么区别:static 函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。
详解:http://blog.csdn.net/u012942555/article/details/48876447
19、设有以下说明和定义:
typedef union {long i; int k[5]; char c;} DATE;
struct data { int cat; DATE cow; double dog;} too;
DATE max;
则语句 printf("%d",sizeof(struct date)+sizeof(max));的执行结果是:___52____
答:DATE 是一个 union, 变量公用空间. 里面最大的变量类型是 int[5], 占用 20 个字节. 所以它的大小是 20。data 是一个 struct, 每个变量分开占用空间. 依次为 int4 + DATE20 + double8 = 32.所以结果是 20 + 32 = 52.

20、队列和栈有什么区别?
队列先进先出,栈后进先出
21、在VC6.0编译器中
#include <iostream>
using namespace std;
void main()
{
int INT=0;
cout<<"int:"<<sizeof(INT)<<endl;
short SHORT=0;
cout<<"short:"<<sizeof(SHORT)<<endl;
long LONG=0;
cout<<"long:"<<sizeof(LONG)<<endl;
unsigned UNSIGNED=0;
cout<<"unsigned:"<<sizeof(UNSIGNED)<<endl;
unsigned short UNSIGNEDSHORT=0;
cout<<"unsigned short:"<<sizeof(UNSIGNEDSHORT)<<endl;
unsigned long UNSIGNEDLONG=0;
cout<<"unsigned long:"<<sizeof(UNSIGNEDLONG)<<endl;
char CHAR=0;
cout<<"char:"<<sizeof(CHAR)<<endl;
unsigned char UNSIGNEDCHAR=0;
cout<<"unsigned char:"<<sizeof(UNSIGNEDCHAR)<<endl;
float FLOAT=0;
cout<<"float:"<<sizeof(FLOAT)<<endl;
double DOUBLE=0;
cout<<"double:"<<sizeof(DOUBLE)<<endl;
long double LONGDOUBLE=0;
cout<<"long double:"<<sizeof(LONGDOUBLE)<<endl;
}

22、写出下列代码的输出内容
#include <iostream>
using namespace std;
int inc(int a) 

return(++a); 

int multi(int *a,int *b,int *c) 

return(*c=*a**b); 

typedef int(FUNC1)(int in); //FUNC1是函数类型 (注意不是指向函数的指针)  
typedef int(FUNC2)(int*,int*,int*);//FUNC2是函数类型(注意不是指向函数的指针) 
void show(FUNC2 fun,int arg1,int *arg2) 
{                                      
//1.函数名前加&表示函数的返回值是引用类型
//2.取地址前函数名前加&与不加&无所谓,函数名本来就代表了函数的入口地址
//3.调用时函数名前不加&
//FUNC1 *p=&inc;//定义一个函数指针(有&)
FUNC1 *p=inc;//定义一个函数指针(无&)
int temp=p(arg1);//temp=11                                           
fun(&temp,&arg1,arg2);//arg1=10 temp=11 arg2=110
printf("%d\n",*arg2); 

main() 

int a; 
show(multi,10,&a);                                               
return 0; 

答:110

23、请找出下面代码中的所以错误
说明:以下代码是把一个字符串倒序,如abcd倒序后变为dcba
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main()
{
char *src="hello,world";
char *dest=NULL;
int len=strlen(src);
dest=(char*)malloc(len);
char *d=dest;
char *s=src[len];
while(len--!=0)
d++=s--;
printf("%s",dest);
return 0;
}
答:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
main()
{
char *src="hello,world";
char *dest=NULL;
int len=strlen(src);
dest=(char*)malloc(len+1);//要为'\0' 分配一个空间
char* d=dest;
char* s=&src[len-1];//指向最后一个字符
while(len--!=0)
*d++=*s--;
*d='\0';//尾部要加\0   或*d=0;
printf("%s\n",dest);
free(dest);// 使用完,应当释放空间,以免造成内存汇泄露
return 0;
}
24、在 C 语言库函数中将一个字符转换成整型的函数是 atool()吗,这个函数的原型是什么?
函数名: atol
功 能: 把字符串转换成长整型数
用 法: long atol(const char *nptr);
程序例:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
long l;
char *str = "98765432";
l = atol(str);
printf("string = %s integer = %ld\n", str, l);
return(0);
}
25、对于一个频繁使用的短小函数,在 C 语言中应用什么实现,在 C++中应用什么实现?
C用宏定义,C++用 inline
26、直接链接两个信令点的一组链路称作什么?
PPP 点到点连接
27、接入网用的是什么接口?
FDDI ADSL 局域网接入
28、voip 都用了那些协议?
29、软件测试都有那些种类?
黑盒:针对系统功能的测试 白合:测试函数功能,各函数接口
30、确定模块的功能和模块的接口是在软件设计的那个队段完成的?
概要设计阶段
31、enum string
{
x1,
x2,
x3=10,
x4,
x5,
}x;
问 
x= 0x801005,0x8010f4 ;//没明白什么意思
32、请问p1+5=? ;p2+5=? ;
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
答案:p1+5=0x801005 ;p2+5=0x810014 ;
33、Ethternet 链接到 Internet 用到以下那个协议?A.HDLC;B.ARP;C.UDP;D.TCP;E.ID
答案:BD(不确定)
34、属于网络层协议的是:A.TCP;B.IP;C.ICMP;D.X.25
答案:
35、Windows 消息调度机制是:A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈;
答案:http://www.docin.com/p-1147959474.html
36、
unsigned short hash(unsigned short key)
{
return (key>>)%256
}
请问 hash(16),hash(256)的值分别是:A.1.16;B.8.32;C.4.16;D.1.32

答案:A,右移4
37、请问下面程序有什么错误?
(1)
int a[60][250][1000],i,j,k;
for(k=0;k<=1000;k++)
for(j=0;j<250;j++)
for(i=0;i<60;i++)
a[i][j][k]=0;
答案:把循环语句内外换一下

(2)
#define Max_CB 500
void LmiQueryCSmd(Struct MSgCB * pmsg)
{
unsigned char ucCmdNum;
......
for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)
{
......;
}
}
答案:一个char是1个字节,用无符号整型来表示范围为0~2^8-1,到不了500,所以死循环。
(3)以下是求一个数的平方的程序,请找出错误:
#define SQUARE(a) ((a)*(a))
int a=5;
int b;
b=SQUARE(a++);
答案:这种垃圾题目,在不同的编译器下结果应该是不一样的,在VC6.0下并没有错误,可以得到正确结果。
(4)
typedef unsigned char BYTE
int examply_fun(BYTE gt_len; BYTE *gt_code)
{
BYTE *gt_buf;
gt_buf=(BYTE *)MALLOC(Max_GT_Length);
......
if(gt_len>Max_GT_Length)
{
return GT_Length_ERROR;
}
.......
}

38、IP Phone 的原理是什么?
IPV6
39、