经典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

中国点击率最高的一篇文章 !