C软件工程师笔试题整理.docx
- 文档编号:20117909
- 上传时间:2023-04-25
- 格式:DOCX
- 页数:27
- 大小:26.72KB
C软件工程师笔试题整理.docx
《C软件工程师笔试题整理.docx》由会员分享,可在线阅读,更多相关《C软件工程师笔试题整理.docx(27页珍藏版)》请在冰豆网上搜索。
C软件工程师笔试题整理
一、请填写BOOL,float,指针变量与“零值”比较的if语句。
(10分)
提示:
这里“零值”可以是0,0.0,FALSE或者“空指针”。
例如int变量n与“零值”比较的if语句为:
if(n==0)if(n!
=0)
以此类推。
请写出BOOLflag与“零值”比较的if语句:
标准答案:
if(flag)if(!
flag)如下写法均属不良风格,不得分。
if(flag==TRUE)if(flag==1)if(flag==FALSE)if(flag==0)
请写出floatx与“零值”比较的if语句:
标准答案示例:
constfloatEPSINON=0.00001。
if((x>=-EPSINON)&&(x<=EPSINON)不可将浮点变量用“==”或“!
=”与数字比较,应该设法转化成“>=”或“<=”此类形式。
如下是错误的写法,不得分。
if(x==0.0)if(x!
=0.0)
请写出char*p与“零值”比较的if语句:
标准答案:
if(p==NULL)if(p!
=NULL)如下写法均属不良风格,不得分。
if(p==0)if(p!
=0)if(p)if(!
)
二、以下为WindowsNT下的32位C++程序,请计算sizeof的值(10分)
charstr[]=“Hello”。
char*p=str。
intn=10。
sizeof(str)=6sizeof(p)=4sizeof(n)=4
voidFunc(charstr[100])
{请计算sizeof(str)=4}
void*p=malloc(100)。
请计算sizeof(p)=4
三、简答题(25分)
1、头文件中的ifndef/define/endif干什么用?
防止该头文件被重复引用
2、#include
答:
对于#include
对于#include “filename.h”,编译器从用户的工作路径开始搜索filename.h
3、const有什么用途?
(请至少说明两种)
答:
(1)可以定义const常量
(2)const可以修饰函数的参数、返回值,甚至函数的定义体。
被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。
4、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”声明?
答:
C++语言支持函数重载,C语言不支持函数重载。
函数被C++编译后在库中的名字与C语言的不同。
假设某个函数的原型为:
voidfoo(intx,inty)。
该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。
C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
5、请简述以下两个for循环的优缺点
for(i=0。
i i++) {if(condition) DoSomething()。 elseDoOtherthing()。 } //第二个 if(condition){ for(i=0。 i i++) DoSomething()。 } else{for(i=0。 i i++) DoOtherthing()。 }优点: 程序简洁 缺点: 多执行了N-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。 优点: 循环的效率高 缺点: 程序不简洁 四、有关内存的思考题(20分) voidGetMemory(char*p) {p=(char*)malloc(100)。 } voidTest(void) {char*str=NULL。 GetMemory(str)。 strcpy(str,"helloworld")。 printf(str)。 } 请问运行Test函数会有什么样的结果? 答: 程序崩溃,getmemory中的malloc不能返回动态内存,free()对str操作很危险 博主: getmemory中p是形参,是一个指针变量,getmemory(str)调用后,传入的是指针变量保存的对象地址,p=(char*)malloc(100)实际上是把申请的动态内存空间的首地址付给p指向的地址(即str指向的地址null),这个是错误的。 应该修改成指向指针的指针voidgetmemory(char**p),这样malloc返回的地址付给*p(即str变量本身)。 char*GetMemory(void) {charp[]="helloworld"。 returnp。 } voidTest(void){char*str=NULL。 str=GetMemory()。 printf(str)。 } 请问运行Test函数会有什么样的结果? 答: 可能是乱码。 因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是NULL,但其原现的内容已经被清除,新内容不可知。 RetMenory执行完毕,p资源被回收,指向未知地址。 返回地址,str的内容应是不可预测的,打印的应该是str的地址 VoidGetMemory2(char**p,intnum) {p=(char*)malloc(num)。 }voidTest(void) {char*str=NULL。 GetMemory(&str,100)。 strcpy(str,"hello")。 printf(str)。 } 请问运行Test函数会有什么样的结果? 答: (1)能够输出hello (2)内存泄漏 voidTest(void){char*str=(char*)malloc(100)。 strcpy(str,“hello”)。 free(str)。 if(str! =NULL) {strcpy(str,“world”)。 printf(str)。 }} 请问运行Test函数会有什么样的结果? 答: 篡改动态内存区的内容,后果难以预料,非常危险。 因为free(str)。 之后,str成为野指针, if(str! =NULL)语句不起作用。 五、 已知strcpy函数的原型是char*strcpy(char*strDest,constchar*strSrc)。 其中strDest是目的字符串,strSrc是源字符串。 (1)不调用C++/C的字符串库函数,请编写函数strcpy 答: char*my_strcpy(char*strdest,constchar*strsrc) { assert(strdest! =NULL)&&(strsrc! =NULL)) char*address=strdest。 while((*strdest++=*strsrc++)! =NULL) returnaddress。 } (2)strcpy能把strSrc的内容复制到strDest,为什么还要char*类型的返回值? 答: 为了实现链式表达式。 //2分 例如intlength=strlen(strcpy(strDest,“helloworld”))。 六、编写类String的构造函数、析构函数和赋值函数(25分) 已知类String的原型为: classString {public: String(constchar*str=NULL)。 //普通构造函数 String(constString&other)。 //拷贝构造函数 ~String(void)。 //析构函数 String&operate=(constString&other)。 //赋值函数 private: char*m_data。 //用于保存字符串 }。 请编写String的上述4个函数。 //普通构造函数 String: : String(constchar*str) { if(str==NULL) { m_data=newchar[1]。 //得分点: 对空字符串自动申请存放结束标志'\0'的空 //加分点: 对m_data加NULL判断 *m_data='\0'。 } else { intlength=strlen(str)。 m_data=newchar[length+1]。 //若能加NULL判断则更好 strcpy(m_data,str)。 } } //String的析构函数 String: : ~String(void) { delete[]m_data。 //或deletem_data。 } //拷贝构造函数 String: : String(constString&other) //得分点: 输入参数为const型 { intlength=strlen(other.m_data)。 m_data=newchar[length+1]。 //加分点: 对m_data加NULL判断 strcpy(m_data,other.m_data)。 } //赋值函数 String&String: : operate=(constString&other)//得分点: 输入参数为const型 { if(this==&other) //得分点: 检查自赋值 return*this。 delete[]m_data。 //得分点: 释放原有的内存资源 intlength=strlen(other.m_data)。 m_data=newchar[length+1]。 //加分点: 对m_data加NULL判断 strcpy(m_data,other.m_data)。 return*this。 //得分点: 返回本对象的引用 } 编写一个函数,要求输入年月日时分秒,输出该年月日时分秒的下一秒。 如输入2004年12月31日23时59分59秒,则输出2005年1月1日0时0分0秒。 voidResetTheTime(int*year,int*month,int*date,int*hour,int*minute,int*second) { intdayOfMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31}。 if(*year<0 ||*month<1||*month>12|| *date<1 ||*date>31||*hour<0 ||*hour>23|| *minute<0||*minute>59||*second<0||*second>60) return。 if(*year%400==0||*year%100! =0&&*year%4==0) dayOfMonth[1]=29。 if(*second>=60) { *second=0。 *minute+=1。 if(*minute>=60) { *minute=0。 *hour+=1。 if(*hour>=24) { *hour=0。 *date+=1。 if(*date>dayOfMonth[*month-1]) { *date=1。 *month+=1。 if(*month>12) { *month=1。 *year+=1。 } } } } } return。 } 1.全局变量和局部变量在内存中是否有区别? 如果有,是什么区别? 全局变量储存在静态数据库,局部变量在堆栈 2.static有什么用途? (请至少说明两种) 1.限制变量的作用域2.设置变量的存储域 不能做switch()的参数类型是: switch的参数不能为实型。 如何引用一个已经定义过的全局变量? 答: extern 可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错 全局变量可不可以定义在可被多个.C文件包含的头文件中? 为什么? 答: 可以,在不同的C文件中以static形式来声明同名全局变量。 可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错 char*ss="0123456789"。 sizeof(ss)结果4===》ss是指向字符串常量的字符指针,sizeof获得的是一个指针的之所占的空间,应该是长整型的,所以是4 sizeof(*ss)结果1===》*ss是第一个字符其实就是获得了字符串的第一位'0'所占的内存空间,是char类型的,占了1位 请找出下面代码中的所以错误 说明: 以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba” 1、#include"string.h" 2、main() 3、{ 4、char*src="hello,world"。 5、char*dest=NULL。 6、intlen=strlen(src)。 7、dest=(char*)malloc(len)。 8、char*d=dest。 9、char*s=src[len]。 10、while(len--! =0) 11、d++=s--。 12、printf("%s",dest)。 13、return0。 14、} 答: 方法1: intmain(){ char*src="hello,world"。 intlen=strlen(src)。 char*dest=(char*)malloc(len+1)。 //要为\0分配一个空间 char*d=dest。 char*s=&src[len-1]。 //指向最后一个字符 while(len--! =0) *d++=*s--。 *d=‘\0’。 //尾部要加\0 printf("%s\n",dest)。 free(dest)。 //使用完,应当释放空间,以免造成内存汇泄露 return0。 } 方法2: #include #include main() { charstr[]="hello,world"。 intlen=strlen(str)。 chart。 for(inti=0。 i i++) { t=str[i]。 str[i]=str[len-i-1]。 str[len-i-1]=t。 } printf("%s",str)。 return0。 } .用两个栈实现一个队列的功能? 要求给出算法和思路! 设2个栈为A,B,一开始均为空. 入队: 将新元素push入栈A。 出队: (1)判断栈B是否为空; (2)如果不为空,则将栈A中所有元素依次pop出并push到栈B; (3)将栈B的栈顶元素pop出; char*constp。 //常量指针,p的值不可以修改 charconst*p;//指向常量的指针,指向的常量值不可以改 constchar*p;//和charconst*p main() { inta[5]={1,2,3,4,5}。 int*ptr=(int*)(&a+1)。 printf("%d,%d",*(a+1),*(ptr-1))。 }输出: 2,5 *(a+1)就是a[1],*(ptr-1)就是a[4],执行结果是2,5 &a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int) int*ptr=(int*)(&a+1)。 则ptr实际是&(a[5]),也就是a+5 原因如下: &a是数组指针,其类型为int(*)[5]。 而指针加1要根据指针类型加上一定的值, 不同类型的指针+1之后增加的大小不同 a是长度为5的int数组指针,所以要加5*sizeof(int) 所以ptr实际是a[5] 但是prt与(&a+1)类型是不一样的(这点很重要) 所以prt-1只会减去sizeof(int*) a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5]. char*s="AAA"。 printf("%s",s)。 s[0]='B'。 printf("%s",s)。 有什么错? "AAA"是字符串常量。 s是指针,指向这个字符串常量,所以声明s的时候就有问题。 cosntchar*s="AAA"。 然后又因为是常量,所以对是s[0]的赋值操作是不合法的。 int(*s[10])(int)函数指针数组,每个指针指向一个intfunc(intparam)的函数。 .交换两个变量的值,不使用第三个变量。 即a=3,b=5,交换之后a=5,b=3。 有两种解法,一种用算术算法,一种用^(异或) a=a+b。 b=a-b。 a=a-b。 ora=a^b。 //只能对int,char.. b=a^b。 a=a^b。 3.c和c++中的struct有什么不同? c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。 c++中struct和class的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private 1: (void*)ptr和(*(void**))ptr的结果是否相同? 其中ptr为同一个指针 .(void*)ptr和(*(void**))ptr值是相同的 改错: intmain(void){ int**p。 intarr[100]。 p=&arr。 return0。 } 解答: 搞错了,是指针类型不同, int**p。 //二级指针 &arr。 //得到的是指向第一维为100的数组的指针 #include intmain(void){ int**p,*q。 intarr[100]。 q=arr。 p=&q。 return0。 } 下面这个程序执行后会有什么错误或者效果: #defineMAX255 intmain() {unsignedcharA[MAX],i。 //i被定义为unsignedchar for(i=0。 i<=MAX。 i++) A[i]=i。 }解答: 死循环加数组越界访问(C/C++不进行数组越界检查) MAX=255数组A的下标范围为: 0..MAX-1,这是其一..其二.当i循环到255时,循环内执行: A[255]=255。 这句本身没有问题..但是返回for(i=0。 i<=MAX。 i++)语句时, 由于unsignedchar的取值范围在(0..255),i++以后i又为0了..无限循环下去. 设编号为1,2,…n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。 数组实现: #include #include intJosephu(intn,intm) { intflag,i,j=0。 int*arr=(int*)malloc(n*sizeof(int))。 for(i=0。 i ++i) arr[i]=1。 for(i=1。 i ++i) { flag=0。 while(flag { if(j==n) j=0。 if(arr[j]) ++flag。 ++j。 } arr[j-1]=0。 printf("第%4d个出局的人是: %4d号\n",i,j)。 } free(arr)。 returnj。 } intmain() { intn,m。 scanf("%d%d",&n,&m)。 printf("最后胜利的是%d号! \n
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件工程师 笔试 整理