c语言笔试题.docx
- 文档编号:9091681
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:20
- 大小:22.64KB
c语言笔试题.docx
《c语言笔试题.docx》由会员分享,可在线阅读,更多相关《c语言笔试题.docx(20页珍藏版)》请在冰豆网上搜索。
c语言笔试题
试题:
写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)
解答:
intSum(intn)
{
return((long)1+n)*n/2; //或return(1l+n)*n/2;
}
=========================================
用变量a给出下面的定义
a)一个整型数(Aninteger)inta;
b)一个指向整型数的指针(Apointertoaninteger)int*a;
c)一个指向指针的的指针,它指向的指针是指向一个整型数(Apointertoapointertoaninteger)int**a;
d)一个有10个整型数的数组(Anarrayof10integers)inta[10];
e)一个有10个指针的数组,该指针是指向一个整型数的(Anarrayof10pointerstointegers)int*a[10];
f)一个指向有10个整型数数组的指针(Apointertoanarrayof10integers)int(*a)[10];
g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数(Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger)int(*a)(int);
h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger)int(*a[10])(int);
=========================================
inta[3];
a[0]=0;a[1]=1;a[2]=2;
int*p,*q;
p=a;
q=&a[2];
则a[q-p]=?
a[2]
=========================================
给定一个整型变量a,写两段代码,第一个设置a的bit3,第二个清除a的bit3。
在以上两个操作中,要保持其它位不变。
解答:
采用#defines和bitmasks操作。
这是一个有极高可移植性的方法,是应该被用到的方法。
最佳的解决方案如下:
#defineBIT3(0x1
staticinta;
voidset_bit3(void){
a|=BIT3;
}
voidclear_bit3(void){
a&=~BIT3;
}
一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数,这也是可以接受的。
主要考点:
说明常数、|=和&=~操作。
======================================================
访问固定的内存位置(Accessingfixedmemorylocations)
嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。
在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。
编译器是一个纯粹的ANSI编译器。
写代码去完成这一任务。
这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。
这一问题的实现方式随着个人风格不同而不同。
典型的类似代码如下:
int*ptr;
ptr=(int*)0x67a9;
*ptr=0xaa55;
一个较晦涩的方法是:
*(int*const)(0x67a9)=0xaa55;
建议采用第一种方法;
=========================================================
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]的赋值操作是不合法的。
===============================================
有以下表达式:
inta=248;b=4;intconstc=21;constint*d=&a;
int*conste=&b;intconst*fconst=&a;
请问下列表达式哪些会被编译器禁止?
为什么?
*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;
*c这是个什么东东,禁止
*d说了是const,禁止
e=&a说了是const禁止
const*fconst=&a;禁止
=======================================
交换两个变量的值,不使用第三个变量。
即a=3,b=5,交换之后a=5,b=3;
有两种解法,一种用算术算法,一种用^(异或)
a=a+b;
b=a-b;
a=a-b;
or
a=a^b;//只能对int,char..
b=a^b;
a=a^b;
or
a^=b^=a;
============================================
#include
#include
voidgetmemory(char*p)
{
p=(char*)malloc(100);
strcpy(p,"helloworld");
}
intmain()
{
char*str=NULL;
getmemory(str);
printf("%s/n",str);
free(str);
return0;
}
程序崩溃,getmemory中的malloc不能返回动态内存,free()对str操作很危险
===========================================
linux系统:
6.列举几种进程的同步机制,并比较其优缺点。
原子操作
信号量机制
自旋锁
管程,会合,分布式系统
7.进程之间通信的途径
共享存储系统
消息传递系统
管道:
以文件系统为基础
11.进程死锁的原因
资源竞争及进程推进顺序非法
12.死锁的4个必要条件
互斥、请求保持、不可剥夺、环路
13.死锁的处理
鸵鸟策略、预防策略、避免策略、检测与解除死锁
15.操作系统中进程调度策略有哪几种?
FCFS(先来先服务),优先级,时间片轮转,多级反馈
8.类的静态成员和非静态成员有何区别?
类的静态成员每个类只有一个,非静态成员每个对象一个
9.纯虚函数如何定义?
使用时应注意什么?
virtualvoidf()=0;
是接口,子类必须要实现
10.数组和链表的区别
数组:
数据顺序存储,固定大小
连表:
数据可以随机存储,大小可动态改变
===============================
1:
(void*)ptr和(*(void**))ptr的结果是否相同?
其中ptr为同一个指针
.(void*)ptr和(*(void**))ptr值是相同的
2:
intmain()
{
intx=3;
printf("%d",x);
return1;
}
问函数既然不会被其它函数调用,为什么要返回1?
mian中,c标准认为0表示成功,非0表示错误。
具体的值是某中具体出错信息
============================
1,要对绝对地址0x100000赋值,我们可以用
(unsignedint*)0x100000=1234;
那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
*((void(*)())0x100000)();
首先要将0x100000强制转换成函数指针,即:
(void(*)())0x100000
然后再调用它:
*((void(*)())0x100000)();
用typedef可以看得更直观些:
typedefvoid(*)()voidFuncPtr;
*((voidFuncPtr)0x100000)();
2,已知一个数组table,用一个宏定义,求出数据的元素个数
#defineNTBL
#defineNTBL(sizeof(table)/sizeof(table[0]))
=================================
unsignedshortA=10;
printf("~A=%u\n",~A);
charc=128;
printf("c=%d\n",c);
输出多少?
并分析过程
第一题,~A=0xfffffff5,int值为-11,但输出的是uint。
所以输出4294967285
第二题,c=0x10,输出的是int,最高位为1,是负数,所以它的值就是0x00的补码就是128,所以输出-128。
这两道题都是在考察二进制向int或uint转换时的最高位处理。
=============================
分析下面的程序:
voidGetMemory(char**p,intnum)
{
*p=(char*)malloc(num);
}
intmain()
{
char*str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
free(str);
if(str!
=NULL)
{
strcpy(str,"world");
}
printf("\nstris%s",str);
getchar();
}
问输出结果是什么?
希望大家能说说原因,先谢谢了
输出strisworld。
free只是释放的str指向的内存空间,它本身的值还是存在的.
所以free之后,有一个好的习惯就是将str=NULL.
此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,
尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚了),但是通常会打印出world来。
这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。
当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存前面一点),并将可用内存的地址返回。
但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的,只不过。
。
。
。
。
。
。
。
楼上都说过了,最好别这么干。
==================================
chara[10],strlen(a)为什么等于15?
运行的结果
#include"stdio.h"
#include"string.h"
voidmain()
{
charaa[10];
printf("%d",strlen(aa));
}
sizeof()和初不初始化,没有关系;
strlen()和初始化有关。
==========================
求函数返回值,输入x=9999;
intfunc(x)
{
intcountx=0;
while(x)
{
countx++;
x=x&(x-1);
}
returncountx;
}
结果呢?
知道了这是统计9999的二进制数值中有多少个1的函数,且有
9999=9×1024+512+256+15
9×1024中含有1的个数为2;
512中含有1的个数为1;
256中含有1的个数为1;
15中含有1的个数为4;
故共有1的个数为8,结果为8。
1000-1=0111,正好是原数取反。
这就是原理。
用这种方法来求1的个数是很效率很高的。
不必去一个一个地移位。
循环次数最少
========================================
inta,b,c请写函数实现C=a+b,不可以改变数据类型,如将c改为longint,关键是如何处理溢出问题
booladd(inta,intb,int*c)
{
*c=a+b;
return(a>0&&b>0&&(*ca||*c>b)));
}
=============================
Heap与stack的差别。
Heap是堆,stack是栈。
Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。
Stack空间有限,Heap是很大的自由存储区
C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。
程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行
=================================
下面这个程序执行后会有什么错误或者效果:
#defineMAX255
intmain()
{
unsignedcharA[MAX],i;//i被定义为unsignedchar
for(i=0;i
输出和为一个给定整数的所有组合
例如n=5
5=1+4;5=2+3(相加的数不能重复)
则输出
1,4;2,3。
#include
intmain(void)
{
unsignedlonginti,j,k;
printf("pleaseinputthenumber\n");
scanf("%d",&i);
if(i%2==0)
j=i/2;
else
j=i/2+1;
printf("Theresultis\n");
for(k=0;k
voidmain()
{
unsignedlonginta,i=1;
scanf("%d",&a);
if(a%2==0)
{
for(i=1;i
读文件file1.txt的内容(例如):
12
34
56
输出到file2.txt:
56
34
12
(逆序)
#include
#include
intmain(void)
{
intMAX=10;
int*a=(int*)malloc(MAX*sizeof(int));
int*b;
FILE*fp1;
FILE*fp2;
fp1=fopen("a.txt","r");
if(fp1==NULL)
{printf("error1");
exit(-1);
}
fp2=fopen("b.txt","w");
if(fp2==NULL)
{printf("error2");
exit(-1);
}
inti=0;
intj=0;
while(fscanf(fp1,"%d",&a)!
=EOF)
{
i++;
j++;
if(i>=MAX)
{
MAX=2*MAX;
b=(int*)realloc(a,MAX*sizeof(int));
if(b==NULL)
{
printf("error3");
exit(-1);
}
a=b;
}
}
for(;--j>=0;)
fprintf(fp2,"%d\n",a[j]);
fclose(fp1);
fclose(fp2);
return0;
}
============================================
一个递规反向输出字符串的例子,可谓是反序的经典例程.
voidinverse(char*p)
{
if(*p=='\0')
return;
inverse(p+1);
printf("%c",*p);
}
intmain(intargc,char*argv[])
{
inverse("abc\0");
return0;
}
=============================================
借签了楼上的“递规反向输出”
#include
voidtest(FILE*fread,FILE*fwrite)
{
charbuf[1024]={0};
if(!
fgets(buf,sizeof(buf),fread))
return;
test(fread,fwrite);
fputs(buf,fwrite);
}
intmain(intargc,char*argv[])
{
FILE*fr=NULL;
FILE*fw=NULL;
fr=fopen("data","rb");
fw=fopen("dataout","wb");
test(fr,fw);
fclose(fr);
fclose(fw);
return0;
}
==========================================
在对齐为4的情况下
structBBB
{
longnum;
char*name;
shortintdata;
charha;
shortba[5];
}*p;
p=0x1000000;
p+0x200=____;
(Ulong)p+0x200=____;
(char*)p+0x200=____;
希望各位达人给出答案和原因,谢谢拉
解答:
假设在32位CPU上,
sizeof(long)=4bytes
sizeof(char*)=4bytes
sizeof(shortint)=sizeof(short)=2bytes
sizeof(char)=1bytes
由于是4字节对齐,
sizeof(structBBB)=sizeof(*p)
=4+4+2+1+1/*补齐*/+2*5+2/*补齐*/=24bytes(经Dev-C++验证)
p=0x1000000;
p+0x200=____;
=0x1000000+0x200*24
(Ulong)p+0x200=____;
=0x1000000+0x200
(char*)p+0x200=____;
=0x1000000+0x200*4
你可以参考一下指针运算的细节
===========================================
写出程序运行结果:
voidg(int**);
intmain()
{
intline[10],i;
int*p=line;//p是地址的地址
for(i=0;i
======================================
写出程序运行结果
intsum(inta)
{
autointc=0;
staticintb=3;
c+=1;
b+=2;
return(a+b+c);
}
voidmain()
{
intI;
inta=2;
for(I=0;I
======================================
intfunc(inta)
{
intb;
switch(a)
{
case1:
30;
case2:
20;
case3:
16;
default:
0
}
returnb;
}
则func
(1)=?
//b定义后就没有赋值。
===================================
inta[3];
a[0]=0;a[1]=1;a[2]=2;
int*p,*q;
p=a;
q=&a[2];
则a[q-p]=a[2]
解释:
指针一次移动一个int但计数为1
=================================
用递归算法判断数组a[N]是否为一个递增数组。
递归的方法,记录当前最大的,并且判断当前的是否比这个还大,大则继续,否则返回false结束:
boolfun(inta[],intn)
{
if(n==1)
returntrue;
if(n==2)
returna[n-1]>=a[n-2];
returnfun(a,n-1)&&(a[n-1]>=a[n-2]);
}
==================================
请列举一个软件中时间换空间或者空间换时间的例子。
voidswap(inta,intb)
{
intc;c=a;a=b;b=a;
}
--->空优
voidswap(inta,intb)
{
a=a+b;b=a-b;a=a-b;
}
======
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 笔试