前言
本文讲解:矩阵主、反对角线元素之和,二分法求方程根,处理字符串中 * 号
一、程序填空📝 --- 矩阵主、反对角线元素之和
难度:⭐
题目📃
在此程序中,函数 fun 的功能是:计算 N×N 矩阵的主对角线元素和反对角线元素之和,并作为函数值返回。要求先累加主对角线元素中的值,再累加反对角线元素中的值。
例如,若 N = 3,有下列矩阵:
1 2 3
4 5 6
7 8 9
首先累加 1、5、9,然后累加 3、5、7,函数返回值为 30。
代码如下:
在1️⃣2️⃣3️⃣处填空
#include <stdio.h> #define N 4 int fun(int t[][N], int n) { int i, sum; /**********found**********/ 1️⃣; for(i=0; i<n; i++) /**********found**********/ sum+= 2️⃣; for(i=0; i<n; i++) /**********found**********/ sum+= t[i][n-i-3️⃣] ; return sum; } void main() { int t[][N]={21,2,13,24,25,16,47,38,29,11,32,54,42,21,3,10},i,j; printf("\nThe original data:\n"); for(i=0; i<N; i++) { for(j=0; j<N; j++) printf("%4d",t[i][j]); printf("\n"); } printf("The result is: %d",fun(t,N)); }
分析🧐
这道题相对简单
- 填写:sum = 0
由下方的sum的使用可以知道
这个sum没有赋初值
又因为是sum是用来做累加求和
所以初始值是0 - 填写:t[ i ][ i ]
由题意可以知道,这里有两个for循环
这里的第一个就是累加从左往右(主对角线)的长度
可以看出规律,都是行列相等的 - 填写:1
这个循环,是来实现反对角线的(从右往左)
可以写一下反对角线的各个元素,就可以得出规律了
解答代码如下:
#include <stdio.h> #define N 4 int fun(int t[][N], int n) { int i, sum; /**********found**********/ 1️⃣sum = 0; for(i=0; i<n; i++) /**********found**********/ 2️⃣sum+= t[i][i]; for(i=0; i<n; i++) /**********found**********/ 3️⃣sum+= t[i][n-i-1] ; return sum; } void main() { int t[][N]={21,2,13,24,25,16,47,38,29,11,32,54,42,21,3,10},i,j; printf("\nThe original data:\n"); for(i=0; i<N; i++) { for(j=0; j<N; j++) printf("%4d",t[i][j]); printf("\n"); } printf("The result is: %d",fun(t,N)); }
二、程序修改🛠️ --- 二分法求方程根
难度:⭐
题目📃
在此程序中,函数 fun 和 funx 的功能是:用二分法求方程 2x³ - 4x² + 3x - 6 = 0 的一个根,并要求绝对误差不超过 0.001。
例如,若给 m 输入 - 100,n 输入 90,则函数求得的一个根为 2.000。
请改正程序中的错误,使它能得出正确的结果。
注意:部分源程序在文件 modi1.c 中。
不要改动 main 函数,不得增行或删行,也不得更改程序的结构!
代码如下:
在代码中找出2个错误并修改
#include <stdio.h> #include <math.h> double funx(double x) { return(2*x*x*x-4*x*x+3*x-6); } double fun( double m, double n) { /************found************/ int r; r=(m+n)/2; /************found************/ while(fabs(n-m)<0.001) { if(funx(r)*funx(n)<0) m=r; else n=r; r=(m+n)/2; } return r; } void main( ) { double m,n, root; printf("Enter m n : \n"); scanf("%lf%lf",&m,&n); root=fun( m,n ); printf("root = %6.3f\n",root); }
分析🧐
这道题的意思难以理解,但是不要被这个文字描述吓到了,看他在程序里挖的错,都是一眼能够看出来的
- 第8行改为
double r;
函数的返回值是double类型
而最后是返回r的,所以很明显 i 是double - 第11行改为
while(fabs(r)<0.001)
由题目可知,绝对值不超过0.001
所以是小于0.001
解答代码如下:
#include <stdio.h> #include <math.h> double funx(double x) { return(2*x*x*x-4*x*x+3*x-6); } double fun( double m, double n) { /************found************/ 1️⃣ double r; r=(m+n)/2; /************found************/ 2️⃣ while(fabs(r)<0.001) { if(funx(r)*funx(n)<0) m=r; else n=r; r=(m+n)/2; } return r; } void main( ) { double m,n, root; printf("Enter m n : \n"); scanf("%lf%lf",&m,&n); root=fun( m,n ); printf("root = %6.3f\n",root); }
三、程序设计💻 --- 处理字符串中 * 号
难度:⭐⭐⭐
题目📃
在此程序中,规定输入的字符串中只包含字母和 * 号。
编写函数 fun,其功能是:除了字符串前导和尾部的号外,将串中其它的 * 号全部删除。形参 h 已指向字符串中第一个字母,形参 p 指向字符串的中最后一个字母。在编写函数时,不得使用 C 语言提供的字符串函数。
例如,若字符串中的内容为 ******ABC*DEFG******,删除后,字符串中的内容应当是:******ABCDEFG******。在编写函数时,不得使用 C 语言提供的字符串函数。
注意:部分源程序在文件 prog1.c 中。
请勿改动主函数 main 和其他函数中的任何内容,仅在函数 fun 的花括号中填入你编写的若干语句。
代码如下:
在fun函数中编写
#include <stdio.h> void fun( char *a, char *h,char *p ) { } void main() { char s[81],*t, *f; printf("Enter a string:\n");gets(s); t=f=s; while(*t)t++; t--; while(*t=='*')t--; while(*f=='*')f++; fun( s , f,t ); printf("The string after deleted:\n");puts(s); }
分析🧐
可以先看main函数的功能,就是将t指针跳过后面的*号,还有将f指针是跳过前面的*号
而后在fun函数中,h指针相当于指向在左边第一个非*号地址的位置
p指针是指向右边非*号地址的位置
这也就相当于是帮我们省去了考虑前后导零的情况了
之后就可以想到覆盖,当h指针是*号,就覆盖它
如果不是*号就向前走
解答代码如下:
#include <stdio.h> void fun( char *a, char *h,char *p ) { //p指向最右边非星号的位置 //h指向最左边非星号的位置 int j; while(h < p) { //让flag指向h,代替h指针移动 //如果直接让h指针移动的话,就只能执行一次了 char *flag = h; if(*flag == '*') { //如果是*号,就将其覆盖 for(j = 0; flag[j] != '\0'; j++) flag[j] = flag[j + 1]; //覆盖完后,长度也要减少一个,所以p-- p--; //如果不是*号的话h指针就向前移动 }else h++; } } void main() { char s[81],*t, *f; printf("Enter a string:\n");gets(s); t=f=s; while(*t)t++; t--; while(*t=='*')t--; while(*f=='*')f++; fun( s , f,t ); printf("The string after deleted:\n");puts(s); }
今日题的总结
如果遇到题目看不懂,一定不要慌,先看看代码中能不能找出解出这个空的条件
希望本文能够帮助到你😊