C程序设计教程与实验(第3版)习题解答--第5章

第五章 数组

1.选择题

(1)已定义“int i; char x[10];”,为了给x数组赋值,以下正确的语句是(D)。

        A.x[10]= "Hello! ";     
        B.x="Hello! ";
        C.x[]="Hello! "; 
        D.for(i=0; i<6; i++)  x[i]=getchar();

        A中,x[10]不存在,A错误;B中,不可用数组名对数组整体赋值,B错误;C中,只能在初始化时进行整体赋值,C错误;D正确。

(2)若有以下的数组定义:“char a[ ]="abcd"; char b[]={'a','b','c','d','e'};”,则以下正确的描述是(A)。

        A.a数组和b数组长度相同
        B.a数组长度大于b数组长度
        C.a数组长度小于b数组长度
        D.两个数组中存放相同的内容

        用字符串给字符数组赋值比用字符逐个赋值多占一个字节,用于存放字符串结束标志' \0 '。故选择A。

(3)若有定义“int i; int x[3][3]={2,3,4,5,6,7,8,9,10};”,则执行语句“for(i=0;i<3;i++)  printf("%4d",x[i][2-i]);”的输出结果是(D)。

        A.2 5 8
        B.2 6 10 
        C.4 7 10
        D.4 6 8

        依次输出x[0][2],x[1][1],x[2][0],即4,6,8,D正确。

(4)下列对二维数组a进行正确初始化的是(B)。

        A.int a[2][3] = {{1,2},{3,4},{5,6}};    
        B.int a[ ][3]  = {1,2,3,4,5,6};
        C.int a[2][ ]  = {1,2,3,4,5,6}; 
        D.int a[2][ ]  = {{1,2},{3,4}};

        A中,第一维和第二维位置错误。定义二维数组并进行初始化时,允许省略对第一维的长度的说明,不可省略第二维,故C、D错误,选择B。

(5)下列说法正确的是(D)。

        A.数组的下标可以是float类型
        B.数组元素的类型可以不同
        C.初始化列表中初始值的个数多于数组元素的个数也是可以的
        D.区分数组的各个元素的方法是通过下标

        数组下标不可为float类型,A错误;数组元素的类型应相同,B错误;初始化列表中初始值的个数不可多于于数组元素的个数,可少于,C错误;选择D。

(6)若有定义“char str1[30],str2[30];”,则输出较大字符串的正确语句是(C)。

        A.if(strcmp(str1,str2))  printf("%s",str1);
        B.if(str1>str2)  printf("%s",strl);
        C.if(strcmp(str1,str2)>0)  printf("%s",str1);  else printf("%s",str2); 
        D.if( strcmp(str1)>strcmp(str2)) printf("%s",str1);   

        strcmp(str1, str2),若str1大于str2,函数返回 值大于0,等于时返回 0,小于时返回值小于0。A、B、D无法覆盖所有情况,选择C。

(7)下列程序段的输出结果是(B)。

int aa[4][4] = { {1,2,3,4},{5,6,7,8},{3,9,10,2},{4,2,9,6} };
int i, s = 0;
for (i = 0; i < 4; i++)
   s += aa[i][1];
printf("%d\n", s);  

        A. 11  
        B. 19    
        C. 13    
        D. 20

        s 累加的值依次为aa[0][1]、aa[1][1]、aa[2][1]、aa[3][1],即2、6、9、2,s值为19,选择B。

(8)下列程序段的输出结果是(D)。

char str[15] = "hello!";
printf("%d\n", strlen(str));

        A.15   
        B.14    
        C.7    
        D.6

        strlen() 函数统计字符串所包含的实际字符个数(不包括' \0 '),字符数组未赋初值部分通常为 '\0',故 str仅6个实际字符,选择D。

(9)有以下程序段,当输入为happy!时,程序运行后输出结果是(B)。

char str[14] = {"I am "};
strcat(str, "sad!");
scanf("%s", str);
printf("%s", str);

        A.I am sad!         
        B.happy!    
        C.I am happy!    
        D.happy!sad!

        scanf()读取时,会将目标字符串已有内容覆盖,所以str值为输入值。

10.下列关于数组的描述中错误的是(D)。

        A.一个数组只允许存储同种类型的数据
        B.数组名是数组在内存中的首地址
        C.数组必须先定义,后使用
        D.如果在对数组进行初始化时,给定的数据元素个数比数组元素少,多余的数组元素自动初始化为最后一个给定元素的值

        如果在对数组进行初始化时,给定的数据元素个数比数组元素少,多余的数组元素自动初始化为0值,字符数组初始化为' \0 '。

2.填空题

(1)有定义语句“int i=3,x[4]={1,2,3};”,则数组元素x[i]的值是 0

        初始化时,剩余的数组元素赋 0 值。

(2)有定义语句“char a[ ]={ "I am a student"};”,该字符串的长度是  14  ,a[3]=  m  

        字符数组赋值包含空格,数组从下标 0 开始。

(3)有二维数组定义“int k[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};”,则其中元素k[2][1]的值是 10 ,k[1][2] 的值是  7  

        题中的初始化属于按行赋初值,{9,10,11,12}对应 k[2],其中的 10 对应 k[2][1]。

(4)若有定义“int a[4][4];”,则a数组中行下标的下限为  0  ,列下标的上限为   3   

        a[4][4],无论行或列,下标下限都为 0,上限都为 3。

(5)若有定义“char a[]="abcdef";”,则执行语句“printf("%d,%d\n",sizeof(a),strlen(a));”后的输出结果是  7,6   

        sizeof() 返回字节大小,a含有 '\0' 字符;strlen() 返回字符串长度。

(6)下列程序段的运行结果是  4  

char str[20] = "This is my book";
str[4] = '\0';
str[9] = '\0';
printf(" %d", strlen(str));

        '\0' 为字符串结束标志,strlen() 读取至 '\0' 结束。

(7)下列程序段的运行结果是  Tony  

char name[3][20] = { "Tony", "Join", "Mary" };
int m = 0, k;
for (k = 1; k <= 2; k++)
     if (strcmp(name[k], name[m]) > 0)
         m = k;
puts(name[m]);

        strcmp() 函数比较两个字符串的大小。程序意在选取数组 name 中较大的数组,其为name[0],故为Tony。

(8)下列程序运行时输入:20 30 5 85 40,运行结果为:

        max=85
        min=5
        sum=180
        aver=30.00 

#include<stdio.h>
#define N 5
int main(void)
{
    int a[N], max, min, sum, i;
    for (i = 0; i < N; i++)
        scanf("%d", &a[i]);
    sum = max = min = a[0];
    for (i = 1; i < N; i++)
    {
        sum += a[i];
        if (a[i] > max)  max = a[i];
        if (a[i] < min)  min = a[i];
    }
    printf("max=%d\nmin=%d\nsum=%d\naver=%4.2f\n", max, min, sum, (float)(sum - max - min) / (N - 2));
    return 0;
}

        程序将输入读入数组a,寻找a中最大值、最小值、各项和、去最大值最小值的平均值。其中均值数据最小宽度为4,输出两位小数。

(9)下列程序运行时输入:This_is_a_C_Program! 运行结果为:
        Ti_saCPorm
        Tss_Pgm   

#include<stdio.h>
#include<string.h>
int main(void)
{
    char str[81], a[81], b[81];
    int n, i, j = 0, k = 0;
    gets(str);
    n = strlen(str);
    for (i = 0; i < n; i++)
    {
        if (i % 2 == 0)  a[j++] = str[i];
        if (i % 3 == 0)  b[k++] = str[i];
    }
    a[j] = b[k] = '\0';
    puts(a);
    puts(b);
    return 0;
}

        程序意在取第 2n+1 (n为大于等于0的整数)位字符至数组 a,取第 3n+1 (n为大于等于0的整数)位字符至数组 b。

(10)下列程序的运行结果为:  1 1 1 5  

#include<stdio.h>
int main(void)
{
    char s[] = "12345678";
    int c[4] = { 0 }, k, i;
    for (k = 0; s[k]; k++)
    {
        switch (s[k])
        {
            case'1': i = 0; break;
            case'2': i = 1; break;
            case'3': i = 2; break;
            case'4': i = 3;
        }
        c[i]++;
    }
    for (k = 0; k < 4; k++)
        printf("%d ", c[k]);
    return 0;
}

 switch中,遍历数组 s,每遇到指定字符,就改变 i 值,使指定的 c[i] 值加 1,而遍历至 '5' 时,switch没有case与之对应,i 值为 3 不变,数组 s 中的“5678”都为 c[3] 服务。故运行为“1 1 1 5 ”。

3.编程题

(1)从键盘输入15个整数,存放在数组中,找出其中最小数并指出其所在的位置。

#include<stdio.h>
int main(void)
{
	int s[15], k = 0;

	for (int i = 0; i < 15; i++)
	{
		scanf("%d", &s[i]);
	}
	for (int i = 1; i < 15; i++)
	{
		if (s[i] < s[k])
		{
			k = i;//选取最小值所在下标
		}
	}
	printf("最小值为:%d,位置为:%d", s[k], k);

    return 0;
}

(2)将输入的十进制正整数化为十六进制数。

#include<stdio.h>
int main(void)
{
	int a, i = 0, res[16];

	while (1)
	{
		scanf("%d", &a);
		if (a < 0)
			printf("重新输入正整数:\n");
		else break;
	}
	while (a)
	{
		res[i] = a % 16;
		a /= 16;
		i++;
	}
	for (int j = i-1; j >= 0; j--)
	{
		if (res[j] < 10) printf("%d", res[j]);//根据 res 的内容输出
		else printf("%c", 'A' + res[j] - 10);
	}

    return 0;
}

(3)从键盘输入一行字符,统计其中有多少单词,假设单词之间以逗号分隔。

#include <stdio.h>
int main(void)
{
    char str[100], c;
    int num = 0, flag = 0;//flag记录当前是否在处理单词

    gets(str);
    for (int i = 0; (c = str[i]) != '\0'; i++)
        if (c == ',') flag = 0;
        else if (flag == 0)
        {
            flag = 1;
            num++;
        }
    printf("有%d个单词\n", num);
    return 0;
}

(4)从键盘输入一字符串,放在字符数组a中,将字符数组a中下标值为偶数的元素按从小到大排序。例如:原始字符串为zabkam,则排序后字符串为aabkzm。

#include<stdio.h>
#include<string.h>
int main(void)
{
    char a[100];
    int k;
    gets(a);

    for (int i = 0; i < strlen(a) - 2; i += 2)
    {
        k = i;
        for (int j = i + 2; j < strlen(a); j += 2)
        {
            if (a[j] < a[k]) k = j;
        }
        if (k != i)
        {
            a[k] += a[i];
            a[i] = a[k] - a[i];
            a[k] -= a[i];
        }
    }
    puts(a);

    return 0;
}

(5)编写程序输出以下杨辉三角形(要求输出10行)。

1      
1    1
1    2    1
1    3    3    1
1    4    6    4    1
1    5    10  10   5    1
…    …  …   …   …   …

#include<stdio.h>
int main(void)
{
    int i, j;
    int a[10][10];
    for (i = 0; i < 10; i++)
    {
        a[i][0] = 1;
        a[i][i] = 1;
    }
    for (i = 2; i < 10; i++)
        for (j = 1; j < i; j++)
            a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
    for (i = 0; i < 10; i++)
    {
        for (j = 0; j <= i; j++)
            printf("%4d", a[i][j]);
        printf("\n");
    }
    return 0;
}

(6)编程将s数组中的字符串的正序和反序进行连接,形成一个新串放在t数组中。例如,当s数组中字符串为"ABCD" 时,则t数组中的内容应为:"ABCDDCBA"。

#include<stdio.h>
#include<string.h>
int main(void)
{
    char s[100], t[100];
    int i, d;

    scanf("%s", s);
    d = strlen(s);
    for (i = 0; i < d; i++)
        t[i] = s[i];
    for (i = 0; i < d; i++)
        t[d + i] = s[d - 1 - i];
    t[2 * d] = '\0';
    printf("%s\n", t);
    return 0;
}

(7)某公司在传输数据过程中为了安全要对数据进行加密,若传递的是四位的整数,对其进行加密的规则为:每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。如:输入数字7659,则加密后的数字为4012。

#include<stdio.h>

int main(void)
{
    int r, j, sum = 0, res[4];
    scanf("%d", &r);

    for (int i = 3; i >= 0; i--)
    {
        j = abs(i - 3);//提前处理位置的交换
        res[j] = (r % 10 + 5) % 10;
        sum = sum * 10 + res[j];//求得结果 sum
        r /= 10;
    }
    printf("结果:%d", sum);

    return 0;
}

(8)编写程序查找数值18在以下二维数组中第一次出现的位置。    

3

4

5

18

8

12

16

54

43

34

18

7

#include <stdio.h>
int main(void)
{
    int i, j, a[3][4] = { {3,4,5,18}, {8,12,16,54}, {43,34,18,7} };
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
            if (a[i][j] == 18) break;//找到则退出当前行的循环
        if (j < 4)break;//意为若找到则退出循环
    }
    printf("数值18第一次出现的位置在%d行,第%d列\n", i + 1, j + 1);
    /*运行结果
    数值18第一次出现的位置在1行,第4列*/
    return 0;
}

(9)设有4行4列的数组a,其元素a[i][j]=3*i+2*j-6。编写程序,实现如下功能:

        1. 求第二行4元素的累加和;

        2. 求第四列4元素的平均值;

        3. 求主对角线4元素中负数的个数。

#include <stdio.h>
int main(void)
{
	int a[4][4], r1 = 0, r3 = 0;
	float r2 = 0;

	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 4; j++)
			a[i][j] = 3 * i + 2 * j - 6;
	}
	for (int i = 0; i < 4; i++)
		r1 += a[1][i];
	for (int i = 0; i < 4; i++)
		r2 += a[i][3];
	r2 /= 4;
	for (int i = 0; i < 4; i++)
	{
		if (a[i][i] < 0)
			r3++;
	}
	printf("第二行4元素的累加和:%d\n", r1);
	printf("第四列4元素的平均值:%f\n", r2);
	printf("主对角线4元素中负数的个数:%d\n", r3);
/*运行结果
    第二行4元素的累加和:0
    第四列4元素的平均值:4.500000
    主对角线4元素中负数的个数:2*/
	return 0;
}

(10)编号为1,2,3,...,n的n个人按顺时针方向围坐一圈,每人持有一个正整数密码。一开始任选一个正整数m作为报数上限值,从第一个人开始按顺时针报数,报到m时停止,报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计程序求出出列顺序。

#include <stdio.h>
int main(void)
{
    int a[100];  /* 数组a中保存n个人的密码*/
    int i, j, m, n, k = 0;
    printf("输入人数n和报数上限m:");
    scanf("%d%d", &n, &m);
    printf("输入%d个人的密码: ", n);
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);
    printf("\n出列顺序为: ");
    for (i = 0; i < n; i++)
    {
        j = 1;
        while (j < m)
        {
            while (a[k] == 0)  /*跳过已出列的人*/
                k = (k + 1) % n;
            j++;
            k = (k + 1) % n;
        }
        while (a[k] == 0)  /*跳过已出列的人*/
            k = (k + 1) % n;
        printf("%d ", k + 1);
        m = a[k];
        a[k] = 0;
    }
    return 0;
}

如有错误不足之处,恳请批评指正。

题目来源:C程序设计教程与实验(第3版)        吉顺如主编

答案参照微信公众号:程序设计及信息技术学习平台

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值