经典c语言笔试题和面试题答案(一)
编程区:《《《《冒泡排序,二分查找,筛选法,的考察》》》》
100、
有两个磁盘文件A和B,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中.
#include
#include
int main(int argc,char* argv[])
{
FILE* fp;
int i,j,k,num,NUM;
char c[50],t,ch;
if((fp=fopen("A","r"))==NULL)
/*can be replaced by open
* int fd=open("A",O_RDONLY|O_CREAT);*/
{
printf("fileA cannot be opened\n");
exit(0);
}
printf("\nA contents are:\n");
for(i=0;(ch=fgetc(fp))!=EOF;i++)/*一个字符一个字符读*/
{
c[i]=ch;
putchar(c[i]);
}
num=i+1;
fclose(fp);
if((fp=fopen("B","r"))==NULL)
{
printf("fileB cannot be opened\n");
exit(0);
}
printf("\nB contents are :\n");
for(i=0;(ch=fgetc(fp))!=EOF;i++)
{
c[num+i]=ch;
putchar(c[num+i]);
}
fclose(fp);
NUM=num+i+1;
for(k=0;k
{
for(j=0;j
{
if(c[j]>c[j+1])
{
t=c[j];
c[j]=c[j+1];
c[j+1]=t;
}
}
}
printf("\nC fileis:\n");
fp=fopen("C","w");
for(i=0;i
{
putc(c[i],fp);/*将字符一个个写入文件中*/
putchar(c[i]);/*一个个输出字符*/
}
fclose(fp);
return 1;
}
86.有一浮点型数组A,用C语言写一函数实现对浮点数组A进行降序排序,并输出结果,要求要以数组A作为函数的入口.(建议用冒泡排序法)
#include
#include
void BubbleSort(int arr[], int n)
{
int i,j;
int exchange = 1;//交换标志,提高算法效率;
int temp;
for(i=0;i
{
exchange=0;//本趟排序开始前,交换标志应为假
for(j=0;j
{
if(arr[j+1] > arr[j])
{
temp=arr[j+1];
arr[j+1]=arr[j];
arr[j]=temp;
exchange=1; //发生了交换,故将交换标志置为真
}
}
if(!exchange) //本趟排序未发生交换,提前终止算法
return;
}
}
int main(int argc,char* argv[])
{
int arr[5]={1,4,2,6,5};
int i;
BubbleSort(arr, 5);
printf("after sort,arr is :\n");
for(i=0;i<5;i++)
{
printf("%3d",arr[i]);
}
return 1;
}
77.写出二分查找的代码:
Int binary_search(int* arr,int key,int size)
{
Intmid;
Intlow=0;
Int high=size-1;
While(low<=high)
{
Mid=(low+high)/2;
If(arr[mid]>key)
High=mid-1;
ElseIf(arr[mid]
Low=mid+1;
Else
Return mid;
}
Return -1;
}
补充1:用帅选法查找100之内的质数
#include
using namespace std;
#define N 100
int main()
{
/*0~100共101个数*/
int sieve[N + 1];
int i;
//step 1:初始化(sieve[i] = 0 表示不在筛中,即不是质数;1表示在筛中)
sieve[0]=sieve[1]=0;
for(int i = 2; i <= N; i++)
{
sieve[i] = 1;
}
//step 2:偶数(2的倍数)肯定不是质数,所以应该先筛除
for(i = 2; i <= N / 2; i++)
{
sieve[i * 2] = 0;
}
int p = 2; //第一个质数是2
//step 3:从sieve中删去P的倍数
while(p * p <= N)
{
p = p + 1; //选下一个p
while(sieve[p] == 0)
{
p++;
}
int t = p * p;
int s = 2 * p;/*质数与质数之和包含合数,但质数于合数之和必为质数,提高算法效率*/
while(t <= N)
{
sieve[t] = 0; //删除
t = t + s;
}
}
//step 4: 输出结果
for(i = 2; i <= N; i++)
{
if(sieve[i] != 0)
{
cout<
内存复制:
void* memcpy(void* pvTo, constvoid* pvFrom, size_tsize)
{
assert((pvTo!= NULL) &&(pvFrom!= NULL));
byte* pbTo= pvTo;
byte* pbFrom= pbFrom;
while (size--> 0)
{
*pbTo++ = *pbFrom++;
}
return pvTo;
}
注意:内存拷贝时要避免内存空间重叠的问题,(即pvfrom与pvto所指向的内存不能重叠)
为了防止内存空间重叠,若是目标地址高于源地址,从后往前复制;
若是源地址高于目标地址,从前往后复制;
《《《《查找字符串中的子串》》》》
84、请编写一个C 函数,该函数在一个字符串中找到可能的最长的子字符串,该字符串是由同一字符组成的。
#include
#include
#include
int ChildString(char*p)
{
char* q=p;
int stringlen=0, i=0,j=1,len=0,maxlen=1;
//stringlen=strlen(p);
while(*q!='\0') //不能用strlen,求得长stringlen
{
stringlen++;
q++;
}
while( i< stringlen)
{
if(*(p+i)==*(p+j)&&j< stringlen)
{
len++; //统计子串长度
i++;
j++;
}
else
{
if(len>=maxlen) //统计最大子串长度
{
maxlen=len+1;
len=0;
}
else
len=0;
i++;
j++;
}
}
return maxlen;
}
int main(int argc,char* argv[])
{
char arr[11];
int len;
printf("please input chararr(10):\n");
scanf("%s",arr);
len=ChildString(arr);
printf("the len of childarr is:%d\n",len);
return 1;
}
99. 计算字符串中子串出现的次数
方法1;
int main(int argc,char* argv[])
{
char str1[20],str2[20],*p1,*p2;
int sum=0;
printf("pleaseinput two strings\n");
scanf("%s%s",str1,str2);
p1=str1;
p2=str2;
while(*p1!='\0')
{
if(*p1==*p2)
{
while((*p1++==*p2++) && *p2!='\0'); /*不断比较字符串1与2,至字符串2到达‘\0’*/
}
else
p1++; /*如果,字符串2一次匹配已结束,或者 此刻*p1与*p2不等;*/
if(*p2=='\0') /*如果是字符串2结束,则成功找到一次,sum++*/
sum++;
p2=str2; /*p2始终指向str2;*/
}
printf("%d",sum);
return 1;
}
方法2:
#include
#include
#include
//判断两字符串是否相等,相等返回1,不等返回0
int Judge(char *movePt,char *tempPt)
#if 1
{
int ret=0 ;
while( !(*movePt-*tempPt) && *tempPt)
{
movePt++;
tempPt++;
}
if(*tempPt=='\0')
{
ret=1;
}
return ret;
}
#endif
#if 0
{
int i;
for(i=0; i
{
if(*movePt != tempPt[i])
return 0;
return 1;
}
}
#endif
//计算子串出现的次数,str为原字符串,sub为子串
int StrCount(char *str,char *sub)
{
int count = 0;
char *move = str;
if( strlen(str) < strlen(sub) )
{
return 0;
}
else
{
while( strlen(move) >= strlen(sub) )
{
printf("%s\n",move);
if(Judge(move,sub))
{
count++;
printf("count++");
}
move++;
}
}
return count;
}
int main(int argc,char* argv[])
{
char arr1[20];
char arr2[20];
int num;
printf("please input two arrs:");
scanf("%s%s",arr1,arr2);
num=StrCount(arr1,arr2);
printf("the num is :%d\n",num);
return 1;
}
90、输入一行字符,统计其中有多少个单词。
int main(int argc,char* argv[])
{
char string[81];
int i,num=0;//word=0;
char c;
gets(string); /*不能用scanf,视空格为终结*/
for(i=0;(c=string[i])!='\0';i++)
{
if(c==' ')
num++;
}
num++;
printf("Thereare %d words in theline\n",num);
return 1;
}
83、请编写一个C 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值。
intsearch(char* cpSource, int n, char ch) //起始地址,搜索长度,目标字符
{
int i;
for(i=0; i
return i;
}
《《《《数字问题,水仙花数,/和%的用法》》》》
98某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。
#include
#include
int main(int argc,char* argv[])
{
int a,i,aa[4],t;
scanf("%d",&a);
aa[0]=a%10;
aa[1]=a%100/10;
aa[2]=a%1000/100;
aa[3]=a/1000;
for(i=0;i<=3;i++)
{
aa[i]+=5;
aa[i]%=10;
}
for(i=0;i<=3/2;i++)
{
t=aa[i];
aa[i]=aa[3-i];
aa[3-i]=t;
}
for(i=3;i>=0;i--)
printf("%d",aa[i]);
return 1;
}
97、809*??=800*??+9*??+1其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数。求??代表的两位数,及809*??后的结果。
output(longb,long i)
{
printf("\n%ld/%ld=809*%ld+%ld",b,i,i,b%i);
}
int main()
{
long int a,b,i;
a=809;
for(i=10;i<100;i++)
{
b=i*a+1;
if(b>=1000&&b<=10000&&8*i<100&&9*i>=100)
output(b,i);
}
}
92、有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
#include "stdio.h"
Int main()
{
inti,j,k;
printf("\n");
for(i=1;i<5;i++) /*以下为三重循环*/
for(j=1;j<5;j++)
for (k=1;k<5;k++)
{
if (i!=k&&i!=j&&j!=k) /*确保i、j、k三位互不相同*/
printf("%d,%d,%d\n",i,j,k);
}
}
水仙花束问题:
#include
int main()
{
int i;
int num=0;
for(i=100;i<=999;i++)
{
int H,T,G,A;
H =i/100;
T=i/10%10;
G =i%10;
A =H*H*H +T*T*T + G*G*G;
if(A==i )
{
printf("%5d",i);
num++;
}
}
printf("thenum is %d\n",num);
return 1;
}
《《《《有关位操作的问题》》》》
93.取一个整数a从右端开始的4~7位。
Int main()
{
unsigned a,b,c,d;
scanf("%o",&a); /*scanf("%x",&a);16进制*/
b=a>>4;
c=~(~0<<4);// ~的优先级大于<<;
/*~0,11111111->11110000->括号外面00001111,保证低4位为1111*/
d=b&c;
printf("%o\n%o\n",a,d);
}
运行结果:输入:1234
输出:
1234
11(8进制)
78、请编写一个C 函数,该函数给出一个字节中被置1 的位的个数。
#include
#include
unsigned char CheckSetBitNum(unsigned char ucNumber)
{
unsigned char i;
unsigned char iResult=0;
for(i=0;i<8;i++)
{
iResult+= (ucNumber>>i) & 0x01; //第i位是1则加1,否则加0,位移动操作不改变原值
printf("ucNumber>>%d=%d\n",i,ucNumber>>i);
printf("iResult=%d\n",iResult);
}
return iResult;
}
int main(int argc,char* argv[])
{
unsigned char a;
int num;
scanf("%c",&a);
num=CheckSetBitNum(a);
printf("%d",num);
return 1;
}
方法2:
int count(int x)
{
int i,y,sum=0;
for (i=0;i<8;i++)
{
y=x%2; /*这是移出去的值*/
x=x/2; /*对于整数右移一次后x的值相当于右移前的值除以2*/
if (y==1) sum+=1;
}
return sum;
}
int main(int argc,char* argv[])
{
int x;
scanf("%d",&x);
printf("%d",count(x));
return 0;
}
《《《《字符串与整数互换》》》》
79、请编写一个C 函数,该函数将给定的一个字符串转换成整数。
int main(int argc,char* argv[])
{
char arr[20];
char* str=arr;
int num=0;
int digital;
printf("please input a string");
scanf("%s",arr);
while(*str!='\0')
{
digital=*str-48;
num=num*10+digital;
str=str+1;
}
printf("the result is %d",num);
return 1;
}
字符串倒置
int main(int argc,char*argv[])
{
char* str="hello world";
char* des=NULL;
int len=strlen(str);
des=(char*)malloc(len+1);//结尾封口添0;
char* d=des;
char* s=&str[len-1];//指向最后一个字符;
while(len--!=0)
*d++=*s--;
*d='\0';//封口
printf("%s\n",des);
free(des);
return 1;
《《《《数组》》》》
94. 打印出杨辉三角形
int main()
{
int i,j,arr[11][11];
for(i=1;i<=10;i++)
for(j=1;j<=i;j++)
{
if(j==1||i==j)
arr[i][j]=1;
else
arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
}
for(i=1;i<=10;i++)
for(j=1;j<=i;j++)
{
printf("%5d",arr[i][j]);
if(i==j)
printf("\n");
} return 1;
}
71.一语句实现x是否为2的若干次幂的判断。
void main()
{
int a;
scanf(“%d”,&a); printf(“%c”,(a)&(a-1)?’n’:’y’);
// 若是打印y,否则n
**
2的n次幂用2进制表示一定是10,100,1000,10000......
对应的i-1就是1,11,111,1111....
i &(i-1)为false(也就是0)时就是返回true
*****
程序分析题
class A
{
public:
A(int a)
{
printf("%d ",a);
}
};
A a(1);
int main(void)
{
printf("main ");
A c(2);
static A b(3);
return 0;
}
答案:、1 main 2 3
【函数体外】
只能存在声明语句或定义语句(实际上函数体外的声明语句都是定义语句,如果没有初始化,会隐式的初始化,对于基本类型初始化为零,对于类类型则调用相应的构造函数),
不能存在表达式语句,包括函数调用语句。
2.
struct Test
{
unsigned short int a:5;
unsigned short int b:5;
unsigned short int c:6;
};
int main(intargc,char* argv[])
{
struct Test test;
test.a=16;
test.b=4;
test.c=0;
int j=sizeof(test);
int i=*(short*)&test;
printf("%d\n",i);
printf("sizeof %d\n",j);
return 0;
}
0000 0000 1001 0000
小端机器结果将是:16+128=144,选B
60.main()
{
Int a[5]={1,2,3,4,5};
int*ptr=(int*)(&a+1);
int* ptr2=(int*)((int*)a+1);
printf(“%d,%d,%d”,*(a+1),*(ptr-1),*ptr2); 结果:2,5,2
}
地址 0-3 4-7 8-11 12-15 16-19 20-23
数值 1 2 3 4 5
&a+1 就是地址为20的地方
*ptr1[-1]就是20-4=16这个地方 一个Int 占用4个地址
(int)a+1 跟(int*)a+1不一样 前者地址为1 后者为4,
所以,int *ptr2=(int*)((int)a+1);*ptr2表示的是指向地址为1的指针地址
要点:指针进行运算,加数与指针类型相关,一般(char*),一个字节;(int*),4个字节;
若是指向结构体,或者是数组的指针,由具体(sizeof)长度决定;
详见:点击打开链接
#include
#include
int main()
{
int a[4]={1,2,3,4};
int *ptr1=(int *)(&a+1);
int *ptr2=(int *)((int)a+1);
printf("%x,%x",ptr1[-1],*ptr2);
return 0;
}
小端字节:*ptr2=0x2000000;
大端字节:*ptr2=0x100;
62
#define SQUARE(a)((a)*(a))
int a=5;
int b;
b=SQUARE(a++);
在同一个式子中有两次以上修改变量内容的副作用时,是未定义行为。
C语言规定a++的自增副作用应该发生在下一个序列点之前,但是乘法、括号和赋值都不是序列点,只有整个表达式结束时才是。在此之前a自增副作用发生的时机是未定义的。 每个编译器的结果不同,结果是25或者36(不提倡在一个表达式中对变量进行两次后自增操作)
63、#define Max_CB500
void LmiQueryCSmd(StructMSgCB* pmsg)
{
unsigned char ucCmdNum;
......
for(ucCmdNum=0;ucCmdNum
{
......;
}
}这段代码执行有什么问题?
【标准答案】死循环
unsigned char //无符号字符型表示范围0~255
char //有符号字符型表示范围-128~127