C语言期末复习练习及解析(2)

文档请见http://t.csdnimg.cn/99eA4

期末复习练习解析02

1、选择题

1.1 一个 C 程序的执行是从: (A)

A、main 函数开始,到 main 函数结束。

B、第一个函数开始,到最后一个函数结束。

C、main 函数开始,到最后一个函数结束。

D、第一个函数开始,到 main 函数结束。

解析: main函数时程序的入口,一个工程只能有一个main函数。正常情况下,程序从main进入,到main函数结束为止。

1.2 x、y 和 z 是 int 型变量,且 x=3, y=4, z=5; 则下面表达式中值为 0 的是:(D)

Ax&&y

Bx<=y

Cx||y+z&&y–z

D!((x<y)&&!z||1)

解析: 选项A中,两个字符取逻辑与,为真。选项B中3<=4为真。选项C中,根据优先级x||(y+z&&y–z),逻辑与取到真,x=3为非0值,表达式为真。

1.3 以下语句的执行结果是: (C)

    char s[20]="2022杭州欢迎你!";

    printf("%d",strlen(s));

A20       B14       C15       D10

解析: 汉字占2个字节,数字占一个字符,感叹号占一个字符。

1.4 用宏名定义一个字符串,下列表述中哪一个是正确的: (C)

A#define pi=3.14159     Bdefine pi=3.14159

C#define pi 3.14159D#define pi(3.14159)

解析:宏定义,define定义常量

1.5 能正确表示 a 和 b 同时为正或同时为负的逻辑表达式是: (D)

A、(a>=0‖b>=0)&&(a<0‖b<0)

B、(a>=0&&b>=0)&&(a<0&&b<0)

C、(a+b>0)&&(a+b<=0)

D、a*b>0 

解析: B改成(a>=0&&b>=0)||(a<0&&b<0)才正确

1.6 数组定义为 int a[4][5],下列引用中错误的是: (B)

A、*a       B、++a          C、&a[2][3]        D、 *(*(a+2)+3)

解析:数组名为constant pointer,不能被修改

1.7 若 ch 是大写字母则转换为对应的小写字母,下列语句中正确的是: (B)

A、if(ch>='A'&ch<='Z') ch=ch-32

B、if(ch>='A'&&ch<='Z')ch=ch+32 

C、ch=(ch>='A'&&ch<='Z')?ch+32:''

D、ch=(ch>'A'&&ch<'Z')?ch+32:ch

解析:常用字母的ASCII值:A-->65, Z-->90, a-->97, z-->122, 0-->48, 9-->57。小写字母在大写字母的后面。

1.8 能够将变量 a、b 中最大值赋值到变量 c 的是:  (B)

A、if(a>b)c=a;c=b B、c=a; if(b>a)c=b

C、a>b? a:b D、a>=b? a:b

解析:选项B中,a首先赋值给c,如果b>a,则把b赋值给 c,这样c取到了a,b中国的大值。

1.9 若有解析语句: int a[ ][3]={1,2,3,4,5,6,7,8,9,10}; ,则 a 数组的行数为:(A)

A、4    B、3   C、不确定   D、5

解析:二维数组中,列下标界不能省,因为二维数组按行保存。在题目中,列下标界为3,取三个为一行,最后不足三个的用0补。

1.10 下列语句定义 p 为指向 float 类型变量 d 的指针,其中正确的是: (D)

A、float d,*p=d;

B、float d,p=d;

C、float *p=&d,d;

Dfloat d,*p=&d;

解析:d需要先声明,才能执行取地址操作,并赋值给指针p。

  1. 程序阅读题

2.1 switch/case,do-while

#include <stdio.h>

int main(){

    int k=0,n=0;

    char c='A';

    do{

        switch (c++){

        case 'A':

            k++;

            break;

        case 'B':

            k--;

        case 'C':

            k+=2;

            break;

        case 'D':

            k=k%2;

            break;

        case 'E':

            k=k*10;

            break;

        default:

            k=k/3;

        }

        n++;

    }

    while(c<'G');

    printf("n=%d\n", n);

    printf("c=%c\n", c);

    return 0;

}

解析:执行次序如下:

--> 进入case A,k= 1,n = 1;c需要后置自增,变为B,满足c<G

--> 进入case B, 因为case B中没有break,连续执行case B和case C,k=2,n = 2;此时c为C,满足c<G

--> 进入case C,k= 4,n = 3;此时c为D,满足c<G

--> 进入case D,k= 0,n = 4;此时c为E,满足c<G

--> 进入case E,k= 0*10=0,n = 5;此时c为F,满足c<G

--> 进入default,k= 0/3=0,n = 6;此时c为G,不满足c<G退出while循环,输出结果。

通过本题,熟练switch/case的使用。

输出:

n=5

C=G

可以练习下面的程序的运行结果:

#include <stdio.h>
    void main( )
   {  int k=0;
      char c='A';
      do { 
        switch (c++) {
          case 'A': k++; break; 
          case 'B': k--;
          case 'C': k+=2; break;
          case 'D': k=k%2; break;
          case 'E': k=k*10; break;
          default: k=k/3;
        }
        k++;
      } while(c<'G');
      printf("k=%d\n", k); 
    }

输出:k=8

初始值k=0, c = A

--> 进入case A,k= 1;退出switch执行k++后,此时c为B,k=2,满足c<G

--> 进入case B, 因为case B中没有break,连续执行case B和case C,k=3;退出switch执行k++后,此时c为C,k=4,满足c<G

--> 进入case C,k= 6;退出switch执行k++后,此时c为D,k=7,满足c<G

--> 进入case D,k= 1;退出switch执行k++后,此时c为E,k=2,满足c<G

--> 进入case E,k= 2*10=20;退出switch执行k++后,此时c为F,k=21,满足c<G

--> 进入default,k= 21/3=7;退出switch执行k++后,此时c为G,k=8,不满足c<G退出while循环,输出结果,k=8。

2.2 字符串处理

#include <stdio.h>

#include <string.h>

#include <ctype.h>

void f(char *s){

    int i=0;

    while(s[i]!='\0')

        if (s[i]==s[i+1]&&(!isalpha(s[i])))

        {

            strcpy(s+i,s+i+1);

            puts(s);

        }

        else

            i++;

}

int main(){

    char x[20]="a*bb*ccc***def";

    f(x);

    return 0;

}

输出:a*bb*ccc*def

解析:本题的功能是,如果字符串中非字母字符重复多次,只保留一个。

  isalpha()判断是否为字母。strcpy()字符串复制

通过本题,熟悉字符串的操作

2.3 二维数组的处理

#include <stdio.h>

int main(){

    int a[4][4]= {{2,5,7,9},{4,3,1,2},{6,9,8,7},{0,5,4,2}},i,j,ii;

    for(j=0; j<4; j++){

        ii=0; 

        for(i=1; i<4; i++) if(a[i][j]>a[ii][j]) ii=i;

        printf("(%d,%d)\n",ii,j);

}

    return 0;

}

解析:ii用来记录当前列中的最大值得行坐标。代码功能:输出每一列中的最大值的下标。通过本题,熟悉二维数组的元素操作。

输出:

(2,0)

(2,1)

(2,2)

(0,3)

 2.4 static变量、全局变量、局部变量

#include <stdio.h>

int k=1;

void f(int c){

    static int a=0;

    a+=2;

    c-=2;

    k*=2;

    printf("a=%d,",a);

}

int main(){

    int i,n,b=5;

    for (i=0; i<2; i++)    {

        f(b);

        printf("b=%d,k=%d\n",b,k);

    }

    return 0;

}

解析:k为全局变量,a为静态变量,b为局部变量。k与a在两次函数调用过程中,值保留下来了,b值保持不变。通过本题,熟悉static变量与全局变量的使用,此知识点要考。

输出:

a=2,b=5,k=2

a=4,b=5,k=4

2.5 结构

#include <stdio.h>

int main(){

    struct student    {

        char name[10];

        int k1;

        int k2;

    } a[3]= {{"he",90,80,},{"wang",95,80},{"wu",90,98}},*p=a;

    printf("name:%s scr:%d\n",p->name,p->k1+p->k2);

    printf("total:%d\n", a[0].k2+a[1].k2+a[2].k2);

    return 0;

}

解析:指针p指向数组的第一个元素,因此,第一个printf输出的是第一位学生的姓名和成绩总和;第二个printf输出所有学生第二门成绩总和。

输出:

name:he scr:170

total:258

3、程序填空

3.1 输出一个[3,1000]范围内的整数,判断其是否是素数。

#include <stdio.h>

   #include <math.h>   

int main(){

    int n,i;

    while(scanf("%d",&n),   n<3 || n>1001   );

    for(i=2; i<=sqrt(n); i++)

        if(     n%i==0    )

            break;

    if(   i>sqrt(n)    )

        printf("%d 是素数\n",n);

    else

        printf("%d 不是素数\n",n);

    return 0;

}

解析:熟悉素数的判断方法、break的使用、sqrt的使用

本代码功能是判断一个数是不是素数。

第一个空在main函数前面,这个位置可能是定义一个全局变量,也可能是包含头文件。分析代码,后面用到了sqrt函数,因此需要包含math.h头文件。

第二个空在循环读数中,在while中包含一个逗号表达式,第一个表达式为读数,第二个表达式为判断是否满足范围条件。题目要求输入的数为[3,1000]范围,因此需要对输入的n进行判断是否属于该范围,如果不在这个范围,继续读数,直到满足范围要求为止。因此填入n<3 || n>1001

第三空if的逻辑体为break,因此属于找到了n的某个因子的情况,即n%i==0

第四空if逻辑题为输出结论:n为素数。说明通过for循环,没有找到任何一个因子,即循环是在循环上限退出的,即i>sqrt(n)。

3.2 下列程序求 n(n 的值由运行时确定)个正整数的最小公倍数。

#include <stdio.h>

#include <stdlib.h>

int main(){

    int *p,i,n,gbs;

      scanf("%d",&n)   ;

    p=    (int*)malloc(n*sizeof(int))    ;

    for(i=0; i<n; i++) scanf("%d",p+i);

    gbs=*p;

    do  {

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

            if(   gbs%*(p+i)!=0   )

            {

                gbs+=*p;

                  break    ;

            }

    }while (i!=n);

    printf("%d\n",gbs);

    return 0;

}

解析:熟悉动态内存分配方法、最小公倍数的求解方法。

第一空,读入n值。

第二空,动态分配内存。注意malloc函数的使用方法

第三空,求最小公倍数的基本思路是:以第一个数为基础,不断的扩大该数(1倍、2倍、3倍......),直到能被其他数整除。在这个过程中,一旦有一个不能整除,即刻停止剩下数的整除判断,再次扩大该数,重新判断整除性。

4编程题

#include <stdio.h>

int main()

{

    int a[10][10]= {{0}},i,j,n;

    while( scanf("%d",&n),n<1||n>10);

    for(i=0; i<n; i++)

        a[i][i]=a[i][0]=1;

    for(i=2; i<n; i++)

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

            a[i][j]=a[i-1][j]+ a[i-1][j-1];

    for(i=0; i<n; i++)

    {

        for(j=0; j<=i; j++) printf("%4d",a[i][j]);

        putchar('\n') ;

    }

}

解析:熟悉图形输出题型的分析方法(按行输出、逐步输出一行中的多个字符、需要分析每个字符的变化规律)、二维数组的定义、二维数组的元素操作。

整体思路:先用一个二维数组构造保存杨辉三角形的各行值,然后再输出该数组中元素。

(1)杨辉三角中,第一列(a[i][0])和对角线(a[i][i])上的元素都为1,单独设置。

(2)从第三行(i=2)开始,每一行中,中间的数字,为上一行正上方(a[i-1][j])、左上方(a[i-1][j-1])两个数字的和(a[i][j] = a[i-1][j-1]+a[i-1][j])

(3)按照上面的方法,构造杨辉三角形中每个元素,并保存在数组中。

(4)输出数组元素即可。

4.2 输入一串字符(长度不超过 80 个),把首字符及所有空格后面的第一个字符改成大写

后输出。如输入:“six months out of sight of land!”,输出:“Six Months Out Of

Sight Of Land!”。

#include <stdio.h>

#include<string.h>

#include<ctype.h>

int main(){

    int i=0,k=0;

    char c[81];

    gets(c);

    c[0]=toupper(c[0]);

    for (i=1; i<strlen(c); i++)

    {

        if ((c[i]==' ')&&(islower(c[i+1])) )

            c[i+1]=toupper(c[i+1]);

    }

    puts(c);

}

解析:

通过本题,可以熟悉字符串的操作:字符串保存在数组中、字符串的读取、如何循环取到字符串里的每一个字符。

toupper函数将字符转换为大写。islower函数用来判断字符是不是小写。

4.3 文件 e:\c.txt 中,每行存储:学号、成绩、交作业次数,各字段之间用空格间隔。编 程,将所有考试成绩小于 55 分且交作业次数少于 4 次的学生记录从文件中删除。

#include <stdio.h>

void main(){

    FILE *f1,*f2;

    char xh[9];

    int cj,cs;

    f1=fopen("e:\\c.txt","r");

    f2=fopen("e:\\d.txt","w");

    while(fscanf(f1,"%s%d%d",xh,&cj,&cs)!=EOF)

        if(cj>=55 && cs>=4 ) fprintf(f2,"%s %d %d\n",xh,cj,cs);

    fclose(f1);

    fclose(f2);

    remove("e:\\c.txt");

    rename("e:\\d.txt","e:\\c.txt");

}

解析:

文件操作相关知识:FILE *定义、fopen函数、fprintf输出、fclose关闭文件、remove删除文件、rename改文件名。

4.4 给定一个 4 行 5 列的整数二维数组,从键盘输入所有的数,编写一个从小到大的排序

函数(自定义函数原型 void px(int a[],int n),在主程序中,调用该排序函数,把每行

的整数分别排序后,输出该二维数组。

#include <stdio.h>

void px(int a[],int n){

    int i,j,k,t;

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

        k=i;

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

            if (a[k]>a[j]) k=j;

        }

        t=a[k];

        a[k]=a[i];

        a[i]=t;

    }

    for(i=0; i<n; i++)

        printf("%5d",a[i]);

    printf("\n");

}

int main(){

    int i,j,a[4][5], b[5],p=0;

    for(i=0; i<4; i++)

        for(j=0; j<5; j++)

            scanf("%d",&a[i][j]);

    for(i=0; i<4; i++){

        p=0;

        for(j=0; j<5; j++){

            b[p]=a[i][j];

            p++;

        }

        px(b,5);

    }

}

解析:熟练二维数组的定义、读入数据保存到数组中、数组元素的比较、排序算法

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Enza、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值