错题改错及分析

孤街浪徒 提交于 2020-01-26 03:46:44

选择题部分

(1)下述程序的输出结果是( )

main()
{
int x=-1,y=4,k;
k=x++<=0&&!(y–<=0);
printf("%d,%d,%d",k,x,y);
}

A: 0,0,3
B: 0,1,2
C: 1,0,3
D: 1,1,2
正确答案:C
我的选择:D
解析:
j=++i;(i的值先加1,再赋给j,j在输出)
j=i++;(先将i的值赋给j,j的值不变,i的值加一)
所以x++<=0;是真的所以k=1;
x=0;y=3;
故结果选C.

(2)设有:int a=1,b=2,c=3,d=4,m=2,n=2; 执行(m=a>b)&&(n=c>d)后n的值是( )。

A: 0
B: 2
C: 3
D: 4
正确答案:B
我的选择:A
解析:有运算符的优先来看,>比=要先进行,又因为c<d所以为假
故可以得出n=0

(3)执行语句for(i=1;i++<4;) ;后变量i的值是( )。

A: 3
B: 4
C: 5
D: 不定
正确答案:C
我的选择:A
解析:明确i++的含义,然后再利用循环求出执行完语句最后的变量的值。

(4)若有定义:int a=7; float x=2.5,y=4.7; 则表达式x+a%3*(int)(x+y)%2/4的值是( )。

A: 2.500000
B: 2.750000
C: 3.500000
D: 0.000000
正确答案:A
我的选择:B
解析:根据运算符的法则来算。

总结以上题知识点

C语言中规定了运算符的优先级,还规定了运算符的结合性
(1)、在表达式求值时,先按运算符的优先级别顺序执行。
(2)、如果在一个运算对象的两侧的运算符的优先级别相同,则按规定的“结合方向”处理。
(3)、算数运算符时自左至右,赋值运算符是自右至左。其他复杂的在遇到的时候可以适当的查一下表。

(5)下面程序段的运行结果是__________。

char *s=“abcde”;
s+=2; printf(“%s”,s);

A: cde
B: 字符’c’
C: 字符’c’的地址
D: 无确定的输出结果
正确答案:A
我的选择:B
解析:

(6) 若有以下定义和赋值语句,则对b数组的第i行第j列(假设i,j已正确说明并赋值)元素的非法引用为______________。

int b[2][3]={0}, (*p)[3];
p=b;

A: ((p+i)+j)
B: *(p[i]+j)
C: (p+i)+j
D: (
(p+i))[j]
正确答案:C
我的选择:D
解析:指针如何表示数组,及其互换的。

(7)请读程序:

main()
{
int x=1, y=0, a=0, b=0;
switch(x)
{
case 1:
switch(y)
{case 0:a++;break;
case 1:b++;break;
}
case 2:
a++; b++; break;
}
printf(“a=%d, b=%d\n”, a, b);
}
上面程序的输出结果是( )。

A: a=2,b=1
B: a=1,b=1
C: a=1,b=0
D: a=2,b=2
正确答案:A
我的选择:C
解析:注意后面的分号,看是否有语句结束。

(8)错误的转义字符是()

A: ‘\091’
B: ‘\’
C: ‘\0’
D: ‘’’
正确答案:A
我的选择:B
解析:A项只是个单纯的斜杠,转义符一般成对出现或者后面有0且无其他数字。

判断题

(1)数组定义后,数组名表示该数组所分配连续内存空间中第一个单元的地址,即首地址。(正确)

(2)数组定义后,只能引用单个的数组元素,而不能一次引用整个数组。(正确)

思路解析: 数组定义后,每个位置上都有相应的数组元素了。

(3)若有定义int a[]={2,4,6,8,10},a[1]和a++表示的含义相同。(错误)

**思路解析:**不相同的,a[1]=4而,a++=2

(4)数组初始化时,初始值个数小于数组元素的个数,C语言自动将剩余的元素初始化为初始化列表中的最后一个初始值。(错误)

思路解析: 初始值的个数小于数组元素的个数,C语言不会自动将剩余元素初始值化为初始值列表中的最后一个初始值,而是自动补零。

(5)对于定义int a[5];可以通过语句scanf("%d",a);输入全部元素的值。(错误)

思路解析: %d是表示整型,但若要输入全部数组元素不能用此方式。

(6)在C语言中能逐个地使用下标变量,也能一次引用整个数组。(错误)

思路解析:不能一次引用整个数组

(7)数组名就是一个指针常量,指向数组的首元素(或者说代表了数组的首地址)。(错误)

思路解析:数组名不是指针,是元素首地址

编程题

(1)求因子

要求:键盘输入一个正整数,输出该正整数的所有因子,每行一个,隔一行输出一个。输出的因子从小到大。
样例输入:
10
样例输出:
1

2

5

10
正确代码:

#include<stdio.h>
int main()
{
	int a,i,b;
	scanf("%d",&a);
	for(i=1;i<=a;i++)
	{
		if(0==a%i)
		{	printf("%d\n",i);
		}
	}
	return 0;
}

思路
首先应该明白因子是什么?
其次如何能确保输出的是循环,循环的要求又是什么;
然后就是这样算出来,考虑限制条件,i的初值一定不能是0;

(2)求一个给定的m×n矩阵各行元素之和。

输入格式
输入第一行给出两个正整数m和n(1≤m,n≤6)。随后m行,每行给出n个整数,其间

以空格分隔。

输出格式:
每行输出对应矩阵行元素之和。

输入样例:
3 2
6 3
1 -8
3 12

输出样例:
9
-7
15
正确代码:

#include<stdio.h>

int main()
{

    int m,n,i,j;
    scanf("%d%d",&m,&n);
    int a[m][n],sum[m]={0};

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

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

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

        }

    }

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

        printf("%d\n",sum[i]);

    }

    return 0;

 } 

思路分析:
先输入两个数,然后在利用循环使其相加,最后就可以得出结果了。
主要利用数组和循环的的知识。

(3)任意输入 3 个整数,编程实现对这 3 个整数由小到大进行排序。

正确代码:

#include <stdio.h>
int main()
{
    int a,b,c,t;   
    printf("Please input a,b,c:\n");   
    scanf("%d,%d,%d",&a,&b,&c);   
    if(a>b)  
    {
        t = a;
        a = b;
        b = t;
    }
    if(a>c)    
    {
        t = a;
        a = c;
        c = t;
    }
    if(b>c)   
    {
        t = b;
        b = c;
        c = t;
    }
    printf("The order of the number is:\n");
    printf("%d,%d,%d",a,b,c);   
    return 0;
}

思路解析:
(1)定义数据类型,本实例中 a、b、c、t 均为基本整型。

(2) 使用输入函数获得任意 3 个值赋给 a、b、c。

(3) 使用 if 语句进行条件判断,如果 a 大于 b,则借助于中间变量 t 互换 a 与 b 值, 依此类推比较 a 与 c、b 与 c,最终结果即为 a、b、c 的升序排列。

(4) 使用输出函数将 a、b、c 的值依次输出。

(4)将一个从键盘输入的整数存放到一个数组中,通过程序的运行按照数组中的逆序输出该整数,利用递归的方法解决问题。

正确代码:

#include <stdio.h>
int fun(char s[],int n)
{
    int i;
    if((i=n/10)!=0)
         fun(s+1,i);
    *s=n%10+'0';
    return 0;
}
int main()
{
    int num;
    char str[10]=" ";
    printf("input integer data:");
    scanf("%d",&num);
    fun(str,num);
    printf("output string:\n");
    puts(str);
    return 0;
}

思路分析:
(1)设计函数实现数据的逆序存放,设定形参数组接收实参数组的地址,来存储数据的每一位。
(2)函数体采用递归的方式解决问题,因此考虑递归进行的条件。例如,把数据 n 存放到数组 s 中,若 n 是一位数,则存放 n 到数组中;若 n 不是一位数,则存放 n/10 到数组中。
(3)问题解决的难点在于找到数据的存放地址,通过不断地取余和整除 10 来得到数据的每一位。为了实现数据的逆序存放,每一次整除 10 的时候,同时把存放数据的数组地址后移,这样得到的第一位数存放在数组的最后一位……通过依次前移,即递归的回归,实现整个数据的存放。通过函数 fun() 实现字符串中的数字的逆序转换。

(5)如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。求3000以内的全部亲密数。

正确代码:

#include<stdio.h>
int main()
{
    int a, i, b, n;
    printf("There are following friendly--numbers pair smaller than 3000:\n");
    for( a=1; a<3000; a++ ) 
    {
        for( b=0, i=1; i<=a/2; i++)  
            if(!(a%i))
                b+=i;
        for( n=0, i=1; i<=b/2; i++ ) 
            if(!(b%i))
                n+=i;
        if(n==a && a<b)  
            printf("%4d--%4d    ", a, b);  
    }
   
    return 0;
}

思路解析:
根据问题描述,该问题可以转化为:给定整数A,判断A是否有亲密数。
为解决该问题,首先定义变量a,并为其赋初值为某个整数。则按照亲密数定义,要判断a中存放的整数是否有亲密数,只要计算出该整数的全部因子的累加和,并将该累加和存放到另一个变量b中,此时b中存放的也是一个整数。再计算b中存放整数的全部因子的累加和,将该累加和存放到变量n中。
若n等于a则可判定变量a和b中所存放的整数是亲密数

(6)用冒泡排序法对任意输入的 10 个数按照从小到大的顺序进行排序。

正确代码:

#include <stdio.h>
int main()
{
    int i,j,t,a[11];    
    printf("请输入10个数:\n");
    for(i=1;i<11;i++)
        scanf("%d",&a[i]);    
    for(i=1;i<10;i++)    
        for(j=1;j<11-i;j++)    
            if(a[j]>a[j+1])
            {
                t=a[j];   
                a[j]=a[j+1];
                a[j+1]=t;
            }
            printf("排序后的顺序是:\n");
            for(i=1;i<=10;i++)
                printf("%5d",a[i]);    
        printf("\n");
    return 0;
}

思路解析:
通过两个 for 循环实现冒泡排序的全过程,外层 for 循环决定冒泡排序的趟数,内层 for 循环决定每趟所进行两两比较的次数。

(7)从键盘输入两个正整数 a 和 b,求其最大公约数和最小公倍数。

正确代码:

#include <stdio.h>
int main()
{
    int a,b,c,m,t;
    printf("请输入两个数:\n");
    scanf("%d%d",&a,&b);
    if(a<b)
    {
        t=a;
        a=b;
        b=t;
    }
    m=a*b;
    c=a%b;
    while(c!=0)
    {
        a=b;
        b=c;
        c=a%b;
    }
    printf("最大公约数是:\n%d\n",b);
    printf("最小公倍数是:\n%d\n",m/b);
    return 0}

思路解析:
利用格式输入语句将输入的两个数分别赋给 a 和 b,然后判断 a 和 b 的关系,如果 a 小于 b,则利用中间变量 t 将其互换。再利用辗转相除法求出最大公约数,进而求出最小公倍数。最后用格式输出语句将其输出。

(8)所有不超过n(取n<256)的其平方具有对称性质的数(也称回文数)。

正确代码:

#include<stdio.h>
int main()
{
    int m[16], n, i, t, count=0;
    long unsigned a, k;
    printf("No.    number     it's square(palindrome)\n");
    for( n=1; n<256; n++ ) 
    {
        k=0; t=1; a=n*n;  
        for( i=0; a!=0; i++ )  
        {
            m[i] = a % 10;
            a /= 10;
        }
        for(; i>0; i--)
        {
            k += m[i-1] * t;  
            t *= 10;
        }
        if(k == n*n)
            printf("%2d%10d%10d\n", ++count, n, n*n);
    }
    return 0;
}

思路分析:
对于要判定的数n计算出其平方后(存于a),按照“回文数”的定义要将最高位与最低位、次高位与次低位……进行比较,若彼此相等则为回文数。此算法需要知道平方数的位数,再一一将每一位分解、比较,此方法对于位数已知且位数不是太多的数来说比较适用。
此问题可借助数组来解决。将平方后的(a的)每一位进行分解,按从低位到高位的顺序依次暂存到数组中,再将数组中的元素按照下标从大到小的顺序重新将其组合成一个数众(如n=15,则a=225且k=522),若k等于n×n则可判定n为回文数。

(9)输出所有的“水仙花数”,所谓的“水仙花数”是指一个三位数其各位数字的立方和等于该数本身,例如153是“水仙花数”,因为:153 = 13 + 53 + 33。

正确代码:

#include <stdio.h>
int main()
{
    int hun, ten, ind, n;
    printf("result is:");
    for( n=100; n<1000; n++ )  
    {
        hun = n / 100;
        ten = (n-hun*100) / 10;
        ind = n % 10;
        if(n == hun*hun*hun + ten*ten*ten + ind*ind*ind) 
            printf("%d  ", n);
    }
    printf("\n");
   
    return 0;
}

思路解析:
根据“水仙花数”的定义,判断一个数是否为“水仙花数”,最重要的是要把给出的三位数的个位、十位、百位分别拆分,并求其立方和(设为s),若s与给出的三位数相等, 三位数为“水仙花数”,反之,则不是。

(10)如何又快、又准确地统计一篇英文文章中的单词数?

正确代码:

#include <stdio.h>
int main()
{
    printf("输入一行字符:\n");
    char ch;
    int i,count=0,word=0;
    while((ch=getchar())!='\n')
        if(ch==' ')
            word=0;
        else if(word==0)
        {
            word=1;
            count++;
        }
    printf("总共有 %d 个单词\n",count);
    return 0;
}

思路解析:
可以换一下就把单词数=空格数+1。,然后就这样求。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!