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

第六章 函数

1.选择题

(1)以下关于函数的说法中正确的是(A)。

        A.调用函数时,只能把实参的值传送给形参,形参的值不能传送给实参
        B.一个函数可以定义在其他函数中
        C.函数必须有返回值和参数
        D.一个函数只能调用定义在其之前的函数

        B中,不允许函数嵌套定义,B错误;C中,函数返回值和参数都可以为空,C错误;D中,调用定义在其后的函数,可以先声明再调用,D错误。

(2)C语言中函数返回值的类型是由以下( B )决定的。

        A.return语句中的表达式类型
        B.函数定义时指定的类型
        C.调用该函数时实参的数据类型
        D.形参的数据类型

        C语言中函数返回值的类型是由以下函数定义时指定的类型决定的。

(3)对于声明为void func(char ch, double x);的函数,以下能调用该函数的语句是(C)。

        A.func("abc", 3.0);       
        B.func('65',10.5);     
        C.func('A', 10.5);          
        D.int t = func('a', 65);

        A中,函数首个参数要求为char,"abc"不符合,A错误;B中,'65'为多字符字面量(multicharacter literal),以int储存,调用过程中在转换为char时会发生截断,只保留后面符合大小的部分,这里只保留'5',故部分编译器只会警告而不报错,然亦失其调用本意(将'65'作为'A'传入,这是我猜的 (●′ω`●) ),所以B错误;C正确;函数func无返回值,不能实现 t 的初始化,无法成功调用,D错误。

(4)已知整型数组a和b都只有一个元素0且函数f定义如下,则执行f(a,b[0])后数组a和b中的元素分别为(C)。

void f(int a[], int b)
{
      a[0]=1;
      b=1;
}

        A. 1和1     
        B. 0和0     
        C. 1和0     
        D. 0和1

        题中,实参a作为数组名传入,函数实际接受的为数组a的首地址,实参和形参指向同一数组,故函数体内对形参数组a的更改会产生实际作用。而实参b[0]作为变量值的传入,函数中形参b为b[0]的映射,b的变化,不会对b[0]产生作用。

(5)用数组名作为函数调用时的实参,则传递给形参的是(A)。

        A.数组首地址             
        B.数组的第一个元素值
        C.数组中全部元素的值     
        D.数组元素的个数

        用数组名作为函数调用时的实参,则传递给形参的是数组首地址。

(6)以下能够声明函数void fun(int arr[], int n){}的语句是(B)。

        A. fun(int arr[], int n);   
        B. void fun(int [], int);
        C. void fun(int arr[],n);   
        D. void fun(int, int);

        函数声明中的形参名可省略,B正确。A中未表明函数的返回值类型,B、C中未正确表明函数参数类型。

(7)关于函数的递归调用,以下说法错误的是(D)。

        A.递归可以分为直接递归和间接递归
        B.递归函数中一定有递归出口
        C.通常使用选择结构设置结束递归或继续递归的条件
        D.递归函数的效率比功能相同的非递归函数更高

        当计算量小或递归中存在大量的重复计算时,递归的效率可能比非递归低,D错误。

(8)以下说法中不正确的是(D)。

        A.在不同的函数中可以定义相同名字的变量
        B.形式参数是函数内的局部变量
        C.在函数内定义的变量只在该函数范围内可访问
        D.在函数内的复合语句中定义的变量在整个函数范围内都可访问

        在一个函数内定义的变量是局部变量,只在函数体内可以访问,D错误。

(9)已知:#define fun(a,b) a*b,则:fun(1+2,3+4)的值为(D)。

        A.21  
        B.15       
        C.13         
        D.11

        宏调用在编译之前把参数记号传递给程序,而非参数的值,故fun(1+2,3+4)的值为 1+2*3+4,计算结果为11,D正确。

(10)函数f定义如下,执行语句“sum=f(5)+f(3);”后,sum的值应为(C)。

int f( int m )
{
    static int i=0;
    int s=0;
    for( ; i<=m; i++)
        s+=i;
    return s;
}

        A.21
        B.16 
        C.15 
        D.8

      i为静态变量,只进行一次初始化,即二次调用时,i值不会被赋予0,在f(3)调用时,i值为6,故f(3)值为0,sum值为15,C正确。

2.填空题

(1)程序执行的入口点、不能被其他函数调用的是  main()  函数。

(2)若函数没有返回值语句,则函数的返回值类型说明符为  void  

        参数和返回值都不是函数必需的

(3)函数由  函数首部  和函数体两个部分组成。

(4)若函数类型缺省没定义,则隐含的函数返回值类型是  int  

(5)已知函数的定义为int fun(int a, double b){…},则声明函数的语句为  int fun(int a, double b); 

        也可忽略形参名:int fun(int, double);

(6)声明一个局部变量用静态方式存储的关键字是  static  

(7)以下程序的输出结果是  7,14  

#include<stdio.h>

int func(int a, int b)
{       
  static int m = 1, i = 2;
  i += m;
  m = i + a + b;
  return m;
}

int main(void)
{
  int k = 3, m = 1, p;
  p = func(k, m);
  printf("%d,", p);
  p = func(k, m);
  printf("%d\n", p);
  return 0;
}

        func()中i、m都为静态变量,首次调用时,p=m=3+3+1,输出为7,第二次时,p=m=10+3+1,输出为14。

(8)以下程序的输出结果是  1  2  

#include<stdio.h>
#include<string.h>
int count(char str[], char c);
int main(void)
{
    char s[] = "I love C programming!\n\0 I love China!";
    printf("%d %d\n", count(s, 'I'), count(s, 'o'));
    return 0;
}
int count(char str[], char c)
{
    int i, t = 0;
    for (i = 0; i < strlen(str); i++)
    {
        if (str[i] == c)
        {
            t++;
        }
    }
    return t;
}

        count()意在记录字符数组str中有几个c字符,而传入的字符数组s中带'\0',strlen()不会算上" I love China!"的长度,故'I'有 1 个,'o'有 2 个。

(9)以下程序的输出结果是  a=48  

#include<stdio.h>

int f(intd[], int m)
{
  int j, s = 1;
  for (j = 0; j < m; j++)
  {
     s = s*d[j];
  }
  return s;
}

int main(void)
{
  int a, z[] = { 2,4,6,8,10 };
  a = f(z, 3);
  printf("a=%d\n", a);
  return 0;
}

        f()意在计算数组intd的前m项的累乘。

(10)以下程序的输出结果是  654321 

#include<stdio.h>

void func(int n)
{
    printf("%d", n % 10);
    if (n >= 10)
    {
        func(n / 10);
    }
    else
    {
        printf("\n");
    }
}

int main(void)
{
    func(123456);
    return 0;
}

        func()意在从末位依次输出各位的数字。输出末位后,通过n/10进行递归。

3.编程题

(1)编写函数,将一个仅包含整数(可能为负)的字符串转化为对应的整数。

#include <stdio.h>
int f(char s[]);
int main(void)
{
    int res;
    char s[20];
    gets(s);//获取字符串
    res = f(s);
    printf("%d\n", res);
    return 0;
}

int f(char s[])
{
    int res = 0, flag = 1;
    for (int i = 0; i < strlen(s); i++)
    {//遍历数组,非'-'号转换为int
        if (s[i] != '-')
        {
            res = res * 10 + (s[i] - '0');
        }
        else
        {
            flag = 0;
        }
    }
    if (flag == 0) res *= -1;//若曾遇'-',改变res

    return res;
}

(2)编写一个能比较字符串大小的函数,将两个字符串中第一个不相同字符的ASCII码值之差作为返回值。

#include <stdio.h>
int f(char s1[], char s2[]);
int main(void)
{
    char s1[20], s2[20];
    int res;
    printf("字符串1:");
    gets(s1);
    printf("\n字符串2:");
    gets(s2);
    res = f(s1, s2);
    printf("差值为%d", res);//输出差值
    return 0;
}

int f(char s1[], char s2[])
{
    int i;
    for (i = 0; s1[i] == s2[i]; i++)
    {//比较直到不同之处
        if (s1[i] == '\0')
        {
            printf("字符串1等于字符串2\n");
            return 0;
        }
    }
    if (s1[i] > s2[i])
    {//利用下标i时,s1和s2不同,再进行比较具体的大小
        printf("字符串1大于字符串2\n");
        return (s1[i] - s2[i]);
    }
    else
    {
        printf("字符串1小于字符串2\n");
        return (s2[i] - s1[i]);
    }

    return 0;
}

(3)编写程序,从键盘输入10个整数,用函数实现将其中最大数与最小数的位置对换,输出调整后的数组。

#include <stdio.h>
void f(int s[]);
int main(void)
{
	int s[10];
	for (int i = 0; i < 10; i++)
	{
		scanf("%d", &s[i]);
	}
	f(s);
}

void f(int s[])
{
	int max = 0, min = 0;
	for (int i = 1; i < 10; i++)
	{//寻找最大值、最小值
		if (s[max] < s[i])
		{
			max = i;
		}
		if (s[min] > s[i])
		{
			min = i;
		}
	}
	s[max] += s[min];//交换最大值和最小值位置
	s[min] = s[max] - s[min];
	s[max] -= s[min];
	for (int i = 0; i < 10; i++)
	{
		printf("%d\n", s[i]);
	}
}

(4)编写函数,对给定的二维数组(3×3)进行转置(即行列互换)。

#include <stdio.h>
void f(int s[3][3]);
int main(void)
{
	int s[3][3];
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			scanf("%d", &s[i][j]);
		}
	}
	f(s);
}

void f(int s[3][3])
{
	int res[3][3];//用res记录转换后的数组
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			res[i][j] = s[j][i];
			printf("%d  ", res[i][j]);
		}
		printf("\n");
	}
}

(5)编写函数,用冒泡法对输入的字符(不超过10个)按从小到大顺序排序。

#include <stdio.h>
void f(char s[]);
int main(void)
{
	char s[20];
	printf("输入不超过10个的字符:");
	gets(s);
	while (strlen(s) > 10)
	{
		printf("字符过多,重新输入:");
		gets(s);
	}
	f(s);
}

void f(char s[])
{
	int k = 0;
	for (int i = 0; i < 9; i++)
	{
		for (int j = 9; j > i ; j--)
		{
			if (s[j] < s[j - 1])
			{//交换
				s[j - 1] += s[j];
				s[j] = s[j - 1] - s[j];
				s[j - 1] -= s[j];
			}
		}
	}
	printf("%s", s);
}

(6)编写程序,输出3~10000内的可逆质数。可逆质数是指:一个质数将其各位数字的顺序倒过来构成的反序数也是质数。如157和751均为质数,它们是可逆质数。要求调用两个函数实现。

#include <stdio.h>
#include <math.h>
int prime(int n);
int invert(int n);
int main(void)
{
	for (int i = 3; i < 10001; i++)
	{//遍历3~10000
		if (prime(i) && invert(i))
		{
			printf("%d\n", i);
		}
	}
	return 0;
}

int prime(int n)
{
	if ((n + 1) % 6 == 0 || (n - 1) % 6 == 0)
	{//利用大于等于5的质数一定和6的倍数相邻性质
		for (int i = 2; i < (int)sqrt(n) + 1; i++)
		{//判断是否可为2到其平方根+1整除
			if (n % i == 0)
			{
				return 0;
			}
		}
		return 1;
	}
	else
	{
		if (n == 3)
		{
			return 1;
		}
	}
	return 0;
}

int invert(int n)
{//翻转并判断是否为质数
	int res = 0;
	while (n != 0)
	{
		res = res * 10 + n % 10;
		n /= 10;
	}
	if (prime(res))
	{
		return 1;
	}
	return 0;
}

(7)编写函数,将一个十进制数转换成八进制数。

#include <stdio.h>
void f(int n);
int main(void)
{
	int n;
	scanf("%d", &n);
	f(n);
	return 0;
}

void f(int n)
{
	char res[20];
	int k = 0;
	while (n != 0)
	{
		res[k] = (n % 8) + '0';
		n /= 8;
		k++;
	}
	for (int i = k - 1; i >= 0; i--)
	{
		printf("%c", res[i]);
	}
}

(8)从键盘输入一个正整数,逆序输出。要求使用循环和递归两种方法分别实现。

#include <stdio.h>
void f1(int n);
void f2(int n);
int main(void)
{
	int n;
	scanf_s("%d", &n, sizeof(n));
	f1(n);
	printf("递归:");
	f2(n);
	return 0;
}

void f1(int n)//循环
{
	int res = 0;
	while (n != 0)
	{
		res = res * 10 + n % 10;
		n /= 10;
	}
	printf("循环:%d\n", res);
}

void f2(int n)//递归
{
	printf("%d", n % 10);
	n /= 10;
	if (n != 0)
	{
		f2(n);
	}
}

(9)定义带参数的宏,计算三角形的周长和面积。

#include <stdio.h>
#include <math.h>
#define cir(a, b, c) (a + b + c)
#define s(a, b, c) sqrt((a+b+c)/2*((a+b+c)/2-a)*((a+b+c)/2-b)*((a+b+c)/2-c))
int main(void)
{
	float a = 0, b = 0, c = 0;
	printf("输入三边长\n");
	printf("a:");
	scanf("%f", &a);
	printf("b:");
	scanf("%f", &b);
	printf("c:");
	scanf("%f", &c);
	printf("\n周长为:%.2f\n", cir(a, b, c));
	printf("面积为:%.2f\n", s(a, b, c));
    return 0;
}

(10)定义函数,参数分别表示行数、列数和字符,输出由该行该列该字符构成的以下这种空心图形。

* * * * *
*        *
*        *
* * * * *

#include <stdio.h>
void f(int row, int column, char c);
void col(int column, char c, int flag);
int main(void)
{
	int row, column;
	char c;
	printf("输出行数");
	scanf("%d", &row);
	printf("输出列数");
	scanf("%d", &column);
	printf("输出字符");
	getchar();// 清除输入缓冲区中的换行符
	scanf("%c", &c);
	f(row, column, c);
	return 0;
}

void f(int row, int column, char c)
{
	for (int i = 0; i < row; i++)
	{
		int flag = i == 0 || i == row - 1;
		if (flag)
		{
			for (int i = 0; i < column; i++)
			{
				printf("%c ", c);
			}
			printf("\n");
		}
		else
		{
			for (int i = 0; i < column; i++)
			{
				if (i == 0 || i == column - 1)
				{
					printf("%c ", c);
				}
				else printf("  ");
			}
			printf("\n");
		}
	}
}

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值