C 2012年笔试题(保)

时间:2020-04-01
本文章向大家介绍C 2012年笔试题(保),主要包括C 2012年笔试题(保)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

 

1 程序改错

1.1 下面程序段的功能是交换两个字符数组的内容(每个字符串字符数均不超过100)  (8)   【 见2012年笔试题1.1】

void StrSwap(char *pa,char *pb)
{		char *temp;
		temp = pa;
		pa = pb;
		pb = temp;
}

分析:该程序中pa,pb两个字符指针变量只是形式参数,刚开始pa指向数组pa[100]的的首元素,指向pb[100]首元素;交换后pa指向数组pb[100]的的首元素,指向pa[100]首元素;而且该程序段运行结束后pa,pb两个变量由内存回收,因此最后两个字符数组的内容没有改变。

改正:

方法一:

void copy(char *pa,char *pb)
{
    while(*pb!=0)
    {
        *pa=*pb;
         pa++;
         pb++;
    }
    *pa=0;
}
void StrSwap(char *pa,char *pb)
{
    char temp[100];
    copy(temp,pa);
    copy(pa,pb);
    copy(pb,temp);
}

方法二:

void swap (char *pa ,char *pb )
{
    if(strlen(pa)!=strlen(pb))exit(-1);  //若长度不一致,则返回
    char tmp;
    int i=-1;
    while(pa[++i])
    {
        tmp=pa[i];
        pa[i]=pb[i];
        pb[i]=tmp;
    }
}

方法三:

void swap (char *pa ,char *pb )
{
    if(strlen(pa)!=strlen(pb))exit(-1);
    char tmp[100];
    strcpy(tmp,pa);
    strcpy(pa,pb);
    strcpy(pb,tmp);
}

1.2 程序段如下  【 见2012年笔试题1.2】

char a[] = “House”;
char *b = “House”;
b[2] = ‘r’; 
a[2] = ‘r’;
b = a;
b[2] = ‘r’;

分析: 

b[2] = ‘r’; //不能对字符常量赋值

a = b;  a是一个地址常量,不能把地址赋给一个常量

2 简答题

2.1下面程序中,arr[]numbitem分别是整型数组、数组元素个数、某一整数,程序功能是遍历数组arr,查找与item相等的元素,并输出该元素的下标。但是此程序不严谨,请问它可能导致什么样的异常结果?为什么?(5)    【 见2012年笔试题2.1】

for(numb = 0;arr[numb] != item;numb --);
printf(“%d”,numb);

问题:只能遍历首元素,之后数组下标会越界,而且最多只能找到一个。

修改:

for(  ; numb>0 ; numb--)
     if( arr[numb-1] == item)
        printf("%d ",numb-1);

2.2 下面程序段中各个常量、变量分别存储在内存中的什么位置、各按什么样的顺序存储、各占多少个字节?(提示:整型变量占2个字节,字符占1个字节,指针占4个字节)(10)

【见2015年笔试题】

int k;  //全局未初始化区
void main()  //栈区(stack),存放函数的参数值,局部变量的值等
{
char *p = “hello”;  //hello\0 在常量区, p在栈区
char q[]= ”hello”;  //hello 在常量区, q在栈区

char ch;   // 栈
int k;   // 栈
func(k); 
}
void func(int m) // 栈
{
int n; // 栈
	 ……
}

2.3在调用函数时,如果形参和实参分别是下列情况,则相应的调用方式是什么?(5)   【见2012年笔试题2.3】

(1) 实参和形参都是数组元素   //传值调用(值传递)

(2) 形参是指针  //传地址调用(地址传递)

(3) 实参和实参都是数组  //传地址调用(地址传递)

3  编程题(60)

3.1 编写一个函数,使之能完成以下功能:把一个字符串逆序排列。(10)

 方法一:

#include "stdio.h"
#include "string.h"
void reverse(char str[])
{
    char ch;
    int i,l=strlen(str);
    for(i=0; i<l/2; i++)
    {
        ch=str[i];
        str[i]=str[l-i-1];
        str[l-i-1]=ch;
    }
}
int main()
{
    char ss[]="abcdefg";
    reverse(ss);
    printf("%s",ss);
    return 0;
}

方法二:

# include <stdio.h>
# include <string.h>

int  change(char *str)
{
    int i,len=0;
    char c;
    for( ; str[len]!='\0'; len++); //求字符串长度
    for(i=0; i<len/2; i++)
    {
        c=str[i];
        str[i]=str[len-i-1];
        str[len-i-1]=c;
    }
    return len;
}

void main()
{
    int i,len;
    char str[20];
    printf("请输入一个字符串:");
    gets(str);
    len=change(str);
    printf("将字符串中的字符互换输出为:");

    for(i=0; i<len; i++)
    {
        printf("%c",str[i]);
    }
    printf("\n");
}

3.2  编写一个函数,使之能完成以下功能:利用递归方法找出一个数组中的最大值和最小值,要求递归调用函数的格式如下:MinMaxValue(arr,n,&max,&min),其中arr是给定的数组,n是数组的个数,maxmin分别是最大值和最小值。(15【见2015年笔试题【保】】 

方法一:

#include "stdio.h"
#define N 10

void MinMaxValue(int arr[],int n,int *max,int *min)
{
    if(n>=0)
    {
        if(*max<arr[n])
            *max=arr[n];

        if(*min>arr[n])
            *min=arr[n];

        MinMaxValue(arr,n-1,max,min);
    }
}

int main()
{
    int max=-32768,min=32767;  //int最小数就是 -32768最大数就是 32767
    int a[]= {1,54,23,65,87,12,54,87,98,233};
    MinMaxValue(a,N-1,&max,&min); //传入地址
    printf("Max=%d,Min=%d\n",max,min);
    return 0;
}

方法二:

#include "stdio.h"
#define N 10

void MinMaxValue(int arr[],int n,int *max,int *min)
{
    if(n>0)
    {
        if(*max<arr[n])
            *max=arr[n];

        if(*min>arr[n])
            *min=arr[n];

        MinMaxValue(arr,n-1,max,min);
    }
}

int main()
{
    int a[]= {1,-8,23,65,87,12,54,887,98,233};
    int max=a[0],min=a[0];
    MinMaxValue(a,N-1,&max,&min);
    printf("Max=%d,Min=%d\n",max,min);
    return 0;
}

方法三:

#include<stdio.h>
void MinMaxValue(int arr[],int n,int *max,int *min)
{
    if(n==0) return;
    if(arr[n-1]>*max)
        *max=arr[n-1];
    if(arr[n-1]<*min)
        *min=arr[n-1];
    MinMaxValue(arr,n-1,max,min);
}
void main()
{
    int arr[]= {1,3,4,2,56,5};
    int max=arr[0],min=arr[0];
    MinMaxValue(arr,sizeof(arr)/sizeof(int),&max,&min);  //sizeof(arr)/sizeof(int)指数组长度
    printf("%d-%d\n",max,min);
}

3.3 【文件】编写一个函数,使之能完成以下功能:把file1.doc的内容全部复制到file2.doc中,file1.doc中全部是字符(含空格),要求复制时,在file2.doc中的每一行都要加上行号,例如:行号*(其中“*”表示具体的数字)。最后该函数返回file1.doc中的字符个数(不包括空格)(10)

方法一:

#include <stdio.h>
#include <stdlib.h>

int exam()
{
    char ch;
    int count=0,row=0;
    FILE *fp1,*fp2;
    fp1=fopen("D:\file1.doc","r+");
    while(!feof(fp1))
    /*
feof是C语言标准库函数,其原型在stdio.h中,其功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返回0
    */
    {
        ch=getc(fp1);  //getc取一个字符
        fp2=fopen("D:\file2.doc ","a+");
        if(ch!=' ')
            count++;
        if(ch=='\n')
        {
            row++;
            fprintf(fp2,"行号:%d",row);
            fprintf(fp2,"\n");

        }
        else
        {
            putc(ch,fp2);
        }
        fclose(fp2);
    }
    fclose(fp1);
    return count;
}

int main()
{
    int sum=exam();
    printf("Sum=%d\n",sum);
    return 0;
}

方法二: 

# include <stdio.h>
# include <stdlib.h>

void main()
{
    FILE *fp1,*fp2;
    int count=0, row=0;
    char c;

    fp1=fopen("D:/file1.txt","r");
    fp2=fopen("D:/file2.txt","w");

    if(fp1== NULL)
    {
        printf("文件不能打开!\n"); // 当前目录不存在 file1.txt 文件 或者 该文件损坏
        exit(0);
    }
    if(fp2== NULL)
    {
        printf("文件不能打开!\n");
        exit(0);
    }

    while( (c=fgetc(fp1)) != EOF )
    {
        if(c!=' ')
            count++;
        if(c=='\n')
        {
            row++;
            fprintf(fp2,"行号:%d",row);
        }
        fputc(c,fp2);
    }
    
    fclose(fp1);
    fclose(fp2);
    printf("count=%d,row=%d\n",count,row);
}

方法三:

#include<stdio.h>
void main()
{
    FILE *fin,*fout;
    int count=0,line=0;
    if(!(fin=fopen("D:/file1.txt","r")))
        printf("error");
    if(!(fout=fopen("D:/file2.txt","w")))
        printf("error");
    fprintf(fout,"行号%d ",line++);
    while(!feof(fin))
    {
        char ch=fgetc(fin);
        putchar(ch); //输出字符到显示输出框
        if((ch!=' ')&& (ch!='\n'))
            count++;
        fputc(ch,fout); //复制到文件中
        if(ch=='\n')
            fprintf(fout,"行号%d ",line++); //一行结束时,重新在复制文件中打印行号
    }
    fprintf(fout,"总个数%d ",count--);  //最后在复制文件中打印总个数
    printf("总个数%d ",count--);  //输出总个数到显示输出框
    fclose(fin);
    fclose(fout);
}

3.4 编写一个完整的程序,使之能完成以下功能:从键盘中输入若干个整数,用链表储存这些输入的数,并要求存储的顺序与输入的顺序相反。(10) 【见2016年笔试题4.4】

方法一:

# include <stdio.h>
# include <malloc.h>

struct node
{
    int val;
    struct node *next;
};


//创建链表
struct node*  createList()
{
    struct node *head,*p;
    int i,len,val;

    //建立头结点
    head = (struct node*)malloc( sizeof(struct node) );

    if(head==NULL)
    {
        printf("空间申请失败!\n");
        return NULL;
    }

    head->val=NULL;
    head->next=NULL;

    printf("请输入结点数目:\n");

    scanf("%d",&len);

    printf("\n\n");

    for(i=0; i<len; i++)
    {
        p = (struct node*)malloc( sizeof(struct node) );

        if(p==NULL)
        {
            printf("空间申请失败!\n");
            return NULL;
        }

        printf("请输入第%d个结点的值:\n", i+1);

        scanf("%d",&val);
        // 头插法建表
        p->val=val;

        p->next = head->next;

        head->next=p;

    }

    return head;
}
//链表输出
void  traverse(struct node *head)
{
    struct node *p=head->next;
    if(p == NULL)
    {
        printf("链表为空!\n");
        return ;
    }

    while(p!=NULL)
    {
        printf("%d ",p->val);
        p=p->next;
    }

    printf("\n");
}


void main()
{
    struct node *head;

    head = createList();

    printf("\n链表创建完成并遍历输出:\n\n");

    traverse(head);

}

方法二:

#include "stdio.h"
#include "stdlib.h"
struct sList
{
    int data;
    struct sList *next;
};
struct sList *head=NULL;
struct sList *creat() //创建链表
{
    int n;
    struct sList *p,*q;//q new
    head=(struct sList *)malloc(sizeof(struct sList));
    head->next=NULL;
    p=head;
    while(1)
    {
        printf("(0结束)n=");
        scanf("%d",&n);
        if(n<=0) break;
        else
        {
            //尾插法,顺序接收
            q=(struct sList *)malloc(sizeof(struct sList));
            q->data=n;
            p->next=q;
            q->next=NULL;
            p=q;
        }
    }
    return head;
}
void ShowList(struct sList *head) //显示链表
{
    struct sList *p=head->next;
    while(p!=NULL)
    {
        printf("%d\t",p->data);
        p=p->next;
    }
}
int main()
{
    struct sList *p,*newhead,*p1;
    ShowList(creat());
    printf("\n");
    p=head->next;
    newhead=head;
    //链表倒置
    newhead->next=NULL;
    while(p!=NULL)
    {
        p1=p;
        p=p->next;
        p1->next=newhead->next;
        newhead->next=p1;
    }
    head=newhead;
    printf("\n");
    ShowList(head);
    return 0;
}

方法三:

#include<stdio.h>
#include<malloc.h>
struct Node
{
    struct Node*next;
    int data;
};
void main()
{
    int i=0,n;
    struct Node *head,*p;
    printf("格式:第一行数据的个数,第二行,输入数据空格隔开\n");
    scanf("%d",&n);
    head=malloc(sizeof(struct Node));
    head->next=NULL;
    for(; i<n; i++)
    {
        int temp;
        scanf("%d",&temp);
        p=malloc(sizeof(struct Node));
        p->data=temp;
        //头插法
        p->next=head->next;
        head->next=p;
    }
    //打印输出
    p=head->next;
    while(p)
    {
        printf("%d\n",p->data);
        p=p->next;
    }
}

3.5 【文件+堆栈】编写一个完整的程序,使之能完成以下功能:一段名为file.c的程序,该程序中含有括号,现要检查程序中的括号是否配对,提示:利用堆栈实现。(15 【见2015年笔试题【保】6】

代码:

#include <stdio.h>
#define Stack char
#define Max 999
int judge(char p[])
{
    int len=strlen(p);
    int top=-1,i;
    Stack s[Max];
    for(i=0; i<len; i++)
    {
        switch(p[i])
        {
        case '(':
        case '[':
        case '{':
            s[++top]=p[i];
            break;
        case ')':
            if(s[top]=='(')
                top--;
            else return 0;
            break;
        case ']':
            if(s[top]=='[')
                top--;
            else return 0;
            break;
        case '}':
            if(s[top]=='{')
                top--;
            else return 0;
            break;
        }
    }
    if(top==-1)
        return 1;  //输出1表示匹配成功
    else
        return 0;   //输出0表示匹配失败
}
void main()
{
    char p[Max];
    FILE * fin;
    if(!(fin=fopen("D:/file1.txt","r")))
        printf("failed");
    while(!feof(fin))
    {
        fscanf(fin,"%s",p);
    }
    printf("%d\n",judge(p));
    fclose(fin);
}

3.6  将输入的一个数质因分解,如Input 90Print:90=2*3*3*5.

方法一:

#include <stdio.h>
#include <math.h>
int a[100];
//判断是否是质数
int isPrime(int n)
{
    int i;
    for(i=2; i<=sqrt(n); i++)
        if(n%i==0)
            return 0;
    return 1;
}
int main()
{
    int i,j,in;
    while(scanf("%d",&in)&&in>-1)
    {
        if(in==0||in==1)
            printf("没有质因数");
        else
        {
            j=0;
            printf("%d=",in);
            while(in>3)
            {
                //质数从2开始,判断i是否是质数
                for(i=2; i<=in; i++)
                {
                    if(isPrime(i)&&in%i==0)
                        break;
                }
                in=in/i;
                //把满足的质数存于数组中
                a[j++]=i;
            }
            if(in>1)
                a[j++]=in;
            //输出
            for(i=0; i<j; i++)
            {
                printf("%d",a[i]);
                if(i<j-1)
                    printf("*");
            }
            printf("\n");
        }
    }
    return 0;
}

方法二:

# include <stdio.h>

void main()
{
    int i,j,k,val;
    printf("请输入一个正整数:");
    scanf("%d",&val);

    printf("将该正整数分解质因数输出为: ");
    printf("%d=",val);
    //以下为算法
    for(i=2 ; i<=val; i++)
    {
        while(val!=i)
        {
            if(val%i == 0)
            {
                printf("%d*",i);
                val=val/i;
            }
            else
                break ;
        }
    }
    printf("%d",val);
    printf("\n");
}

3.7  

方法一:

# include <stdio.h>

void main()
{
    float sum=1, sum1=1, sum2=1, sum3, x;

    int i, n, flag=-1;

    printf("请输入x的值:\n");
    scanf("%f", &x);

    printf("请输入n的值:\n");
    scanf("%d", &n);

    for(i=1; i<=n; i++)
    {
        sum1 = sum1*x;  //sum1为x^n
        sum2 = sum2*i;  //sum2为n!
        sum3 = sum1/sum2 * flag;  //sum3为 x^n/n!
        flag = -flag;  //变号
        sum = sum + sum3;
    }
    printf("Sum=%f\n", sum );

}

方法二:

#include "stdio.h"
#include "math.h"
int nJie(int a);
int main()
{
    int i,n,sign;
    float ex=1,temp,x,fenmu,fenzi;
    printf("n=");
    scanf("%d",&n);
    printf("x=");
    scanf("%f",&x);
    for(i=1; i<=n; i++)
    {
        fenzi=pow(x,i);//计算以x为底的i次方值
        fenmu=nJie(i);
        temp=fenzi/fenmu;
        //变号
        if(i%2==0)
            sign=1;
        else
            sign=-1;
        ex+=sign*temp;
    }
    printf("ex=%6.2f",ex);
    return 0;
}
//求a!
int nJie(int a)
{
    int i,ex=1;
    for(i=1; i<=a; i++)
        ex*=i;
    return ex;
}

#include "stdio.h"

#include "math.h"

int nJie(int a);

int main()

{

int i,n,sign;

float ex=1,temp,x,fenmu,fenzi;

printf("n=");

scanf("%d",&n);

printf("x=");

scanf("%f",&x);

for(i=1;i<=n;i++){

fenzi=pow(x,i);

fenmu=nJie(i);

temp=fenzi/fenmu;

if(i%2==0) sign=1;

else sign=-1;

ex+=sign*temp;

}

printf("ex=%6.2f",ex);

return 0;

}

int nJie(int a)

{

int i,ex=1;

for(i=1;i<=a;i++)

ex*=i;

return ex;

}

$flag 上一页 下一页