《C语言程序设计学习指导与实践教程》——2.7.5 函数程序设计(题目分析与代码演示)

目录

前言

实验目的

实验内容与要求

1.完成程序,求解n!。

2.计算s=1^k+2^k+3^k+…+N^k。

3.写出下面3个程序的输出结果,说明每个程序中的各个x有何不同。

4.阅读程序,理解程序的功能,写出预期结果并上机验证。

5.编程并上机调试运行。

(1)编写一个判断素数的函数,在主函数输入一个整数,输出是否为素数的信息。

(2)输入一个整数,将它逆序输出。要求定义并调用函数 reverse(number),它的功能是返回number的逆序数。如reverse(12345)的返回值是54321。

(3)用递归法求n阶勒让德多项式的值,递归公式为:

(4)编写一函数,由实参传递一个字符串,统计此字符串中字母、数字、空格和其他字符的个数,在主函数中输入字符串并输出上述结果。

(5)定义一个带参数的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参。输出交换后的两个值。

(6)编写函数,实现两个字符串的连接,在主函数中输入两个字符串并输出连接后的结果(不要使用库函数中的strcat函数)。

(7)请编写函数fun,它的功能是:求出1~1000之内能被7或11整除,但不能同时被7和11整除的所有整数,并将它们放在a所指的数组中,通过n返回这些数的个数。在主函数中输出这些整数,并给出统计的总数。

(8)设有未完成的函数:

字符串s中无序地存储了10个数字字符,没有重复。函数的功能是:如果字符c不是数字字符,函数原样返回该字符;否则,在s中查找字符c,并返回其在s中前一个字符。如果该字符位于s的最前面(字符‘9’),则返回最后一个字符‘6’。

如GetChar('4')得到字符'1',GetChar('T')得到字符'T'。

请完成该函数并在主函数中调用。

【思考题】


前言

本篇基于《C语言程序设计学习指导与实践教程》(刘涛 叶明全 主编 | 上海交通大学出版社)教材书中的2.7.5章节 实验 函数程序设计。分析了实验中的例题。(有部分暂未完成)

上一篇:2.6.5《数组的定义及使用》

《C语言程序设计学习指导与实践教程》——2.6.5 数组的定义及使用(题目分析与代码演示)icon-default.png?t=N7T8https://blog.csdn.net/qq_45580875/article/details/134142141


实验目的

(1)掌握定义函数的方法。

(2)掌握函数实参与形参的对应关系,体会“值传递”的方式。

(3)掌握函数的嵌套调用和递归调用的方法。

(4)掌握全局变量和局部变量、动态变量和静态变量的概念与使用方法。

(5)理解数组作为函数参数的传递方式。

(6)理解宏的概念,掌握宏的定义。

(7)了解文件包含的概念,掌握其用法。


实验内容与要求

1.完成程序,求解n!。

#include<stdio.h>
f(int n)
{
	if (n == 1)
		return 1;
	else
		return _______;
}
void main()
{
	int x, i;
	scanf("%d", &i);
	________;
	printf("%d!=%d\n", i, x);
}

具体要求:①输入并完善源程序;②对源程序进行编译、连接和运行;③写出程序运行结果。

【完整程序】

#include<stdio.h>
f(int n)
{
	if (n == 1)
		return 1;
	else
		return n * f(n-1);    //这里填n*f(n-1)
}
void main()
{
	int x, i;
	scanf_s("%d", &i);
	x = f(i);    //这里填f(i)
	printf("%d!=%d\n", i, x);
}

 【运行结果】

输入数据输出结果
55!=120
66!=720

2.计算s=1^k+2^k+3^k+…+N^k。

#include<stdio.h>
long f1(int i, int j)
{
	long power = i;
	int m;
	for (m = 1; m < j; m++)
		________;
	return power;
}
void main()
{
	int n, k, m;
	long sum = 0;
	printf("please input N,k:\n");
	scanf_s("%d,%d", &n, &k);
	for (m = 1;________; m++)
		________;
	printf("sum is %ld\n", sum);
}

 具体要求:①输入并完善源程序;②对源程序进行编译、连接和运行;③写出程序运行结果。

【完整程序】

#include<stdio.h>
long f1(int i, int j)
{
	long power = i;
	int m;
	for (m = 1; m < j; m++)
		power *= i;
	return power;
}
void main()
{
	int n, k, m;
	long sum = 0;
	printf("please input N,k:\n");
	scanf_s("%d,%d", &n, &k);
	for (m = 1; m <= n; m++)
		sum += f1(m, k);
	printf("sum is %ld\n", sum);
}

【运行结果】

注:这里输入N和k的值时,中间用英文状态下的“,”逗号隔开,否则会出现结果不正确的问题。


 3.写出下面3个程序的输出结果,说明每个程序中的各个x有何不同。

(1)

#include<stdio.h>
int x = 8;
void main()
{
	printf("\nx1=%d", x);
	{
		int x = 5;
		printf("\nx2=%d", x);
	}
}

(2)

#include<stdio.h>
int x = 8;
void main()
{
	printf("\nx1=%d", x);
	{
		int x = 5;
		printf("\nx2=%d", x);
	}
	printf("\nx3=%d", x);
}

(3)

#include<stdio.h>
void main() {
	void sub(void);
	int i;
	static int x;
	int y;
	i = 1; x = 8; y = 5;
	printf("i=%d x=%d y=%d\n", i, x, y);
	sub();
	printf("i=%d x=%d y=%d\n", i, x, y);
}
void sub(void) {
	int i;
	static int x;
	i = 18; x = 20;
	printf("i=%d x=%d\n", i, x);
}

【输出结果】

(1)程序1:

 (2)程序2:

(3)程序3:


 4.阅读程序,理解程序的功能,写出预期结果并上机验证。

(1)程序1:

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

 ①程序功能:将数组a的数按由大到小的顺序重新排列,并输出重新排列的结果。

②预期结果:

(2)程序2:

#include<stdio.h>
#define SQR(X) X*X
void main(){
	int a=15,k=1,m=1;
	a/=SQR(k+m)/SQR(k+m);
	printf("%d\n",a);
}

        这里有一个宏定义函数SQR(x),要注意宏定义函数的展开方式。如此处的SQR(k+m)/SQR(k+m),运算的过程为:k+m*k+m/k+m*k+m,即1+1*1+1/1+1*1+1=5。可以看出,宏函数传递表达式是不带括号的。所以最后a的结果为15/5=3。


 5.编程并上机调试运行。

(1)编写一个判断素数的函数,在主函数输入一个整数,输出是否为素数的信息。

①问题分析:

        此题的关键在于如何判断一个整数为素数。首先明确一下素数的定义。素数又称质数,其定义为,在大于1的自然数中,除了1和其本身之外不再有其他因数。如2,3,5,7等。

        判断一个整数为素数的方法有多种,这里列举了一个比较容易理解的。

②代码示例:

#include <stdio.h>

int isPrime(int num) {
    int i;
    if (num <= 1)
        return 0;  // 不是素数

    for (i = 2; i * i <= num; i++)
        if (num % i == 0)
            return 0;  // 不是素数

    return 1;  // 是素数
}

int main() {
    int num;
    printf("请输入一个整数:\n");
    scanf("%d", &num);

    if (isPrime(num))
        printf("%d是素数\n", num);
    else
        printf("%d不是素数\n", num);
    return 0;
}

(2)输入一个整数,将它逆序输出。要求定义并调用函数 reverse(number),它的功能是返回number的逆序数。如reverse(12345)的返回值是54321。

代码示例:

#include <stdio.h>
int reverse(int number) {
    int Reverse_Number = 0;

    while (number != 0) {
        int digit = number % 10;
        Reverse_Number = Reverse_Number * 10 + digit;
        number /= 10;
    }
    return Reverse_Number;
}

int main() {
    int number;
    printf("请输入一个整数:\n");
    scanf("%d", &number);

    int Reverse_Number = reverse(number);
    printf("逆序输出:%d\n", Reverse_Number);

    return 0;
}

(3)用递归法求n阶勒让德多项式的值,递归公式为:

 ①代码示例:

#include<stdio.h>
float p_n(int n, int x) {
	if (n == 0)
		return 1;
	else if (n == 1)
		return x;
	else if (n > 1)
		return ((2 * n - 1) * x - p_n(n - 1, x) - (n - 1) * p_n(n - 2, x)) / n;
}
void main() {
	int n, x;
	scanf("%d%d", &n, &x);
	float pn = p_n(n, x);
	printf("%.2f", pn);
}

②代码演示:


 (4)编写一函数,由实参传递一个字符串,统计此字符串中字母、数字、空格和其他字符的个数,在主函数中输入字符串并输出上述结果。

代码示例:

#include <stdio.h>
void CountCharacters(char str[]) {
    int characters = 0, numbers = 0, spaces = 0, others = 0;
    int i = 0;

    while (str[i] != '\0') {
        if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'))
            characters++;
        else if (str[i] >= '0' && str[i] <= '9')
            numbers++;
        else if (str[i] == ' ')
            spaces++;
        else
            others++;
        i++;
    }
    printf("字母个数:%d\n", characters);
    printf("数字个数:%d\n", numbers);
    printf("空格个数:%d\n", spaces);
    printf("其他字符个数:%d\n", others);
}

int main() {
    char str[100];

    printf("请输入一个字符串:\n");
    gets(str);

    CountCharacters(str);

    return 0;
}

(5)定义一个带参数的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参。输出交换后的两个值。

①代码示例:

#include <stdio.h>
#define SWAP(a, b) do {int temp;temp=a;a=b;b=temp;} while(0)

int main() {
    int num1, num2;
    printf("请输入两个整数:\n");
    scanf("%d%d", &num1, &num2);
    SWAP(num1, num2);
    printf("交换后的值:\n");
    printf("num1=%d,num2=%d\n", num1, num2);
    return 0;
}

②代码演示:


(6)编写函数,实现两个字符串的连接,在主函数中输入两个字符串并输出连接后的结果(不要使用库函数中的strcat函数)。

#include <stdio.h>

void StringConcatenate(char str1[], char str2[], char result[]) {
    int i = 0, j = 0;
    //这里使用两个字符串,再依次将两个字符串赋值到第三个字符串中,实现字符串连接
    // 复制第一个字符串到目标字符串中
    while (str1[i] != '\0') {
        result[j] = str1[i];
        i++;
        j++;
    }
    // 复制第二个字符串目标果字符串中
    i = 0;
    while (str2[i] != '\0') {
        result[j] = str2[i];
        i++;
        j++;
    }
    // 在目标字符串末尾添加字符串结束符
    result[j] = '\0';
}

int main() {
    char str1[100], str2[100], result[200];
    printf("请输入第一个字符串:");
    gets(str1);

    printf("请输入第二个字符串:");
    gets(str2);

    StringConcatenate(str1, str2, result);

    printf("连接后的字符串:%s\n", result);

    return 0;
}

(7)请编写函数fun,它的功能是:求出1~1000之内能被7或11整除,但不能同时被7和11整除的所有整数,并将它们放在a所指的数组中,通过n返回这些数的个数。在主函数中输出这些整数,并给出统计的总数。

【问题分析】

        题目中输出的数有三条要求:①1~1000以内的整数;②能被7或11整除;③但不同时被7和11整除。故可在函数fun中用for循环嵌套if判断语句,进行循环判断输出所满足条件的所有数。将这些数依次存放到指定数组a中,再设置一个计数器n,统计这些数的个数。

【代码示例】

#include<stdio.h>
int fun(int *a){
	int i=0;
	int n;
	for(n=1;n<1000;n++){
		if((n%7==0 || n%11==0) && !(n%7==0 && n%11==0)){
			a[i]=n;
			i++;
		}//通过if判断此数是否能被7或11整除,且不同时被7和11整除
	}
	return i;
}
	
void main(){
	int a[1000];
	int n = fun(a);
	int i;
	printf("%d\n",n);
	for(i=0;i<n;i++)
		printf("%d ",a[i]);
	printf("\n");
}

(8)设有未完成的函数:

char GetChar(char c){
    char s[]="9038571426";
    ……
}

字符串s中无序地存储了10个数字字符,没有重复。函数的功能是:如果字符c不是数字字符,函数原样返回该字符;否则,在s中查找字符c,并返回其在s中前一个字符。如果该字符位于s的最前面(字符‘9’),则返回最后一个字符‘6’。如GetChar('4')得到字符'1',GetChar('T')得到字符'T'。请完成该函数并在主函数中调用。


【思考题】(未完成)

1.请分析不返回值的函数定义与有返回值的函数定义有什么不同,思考着两类函数在实际编程中的作用。

2.请观察本次实验中使用的函数都有几个返回值,当一个函数需要有多个返回值时,应该如何处理?

3.数组作为函数参数有哪几种方式?这些方式中有没有能解决之前“函数多值返回问题”的方法?

        

总结

  • 16
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

扶光°

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

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

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

打赏作者

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

抵扣说明:

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

余额充值