实验4
实验4
task1
1 #include <stdio.h> 2 #define N 4 3 #define M 2 4 5 void test1() { 6 int x[N] = {1, 9, 8, 4}; 7 int i; 8 9 // 输出数组x占用的内存字节数 10 printf("sizeof(x) = %d\n", sizeof(x)); 11 12 // 输出每个元素的地址、值 13 for (i = 0; i < N; ++i) 14 printf("%p: %d\n", &x[i], x[i]); 15 16 // 输出数组名x对应的值 17 printf("x = %p\n", x); 18 } 19 20 void test2() { 21 int x[M][N] = {{1, 9, 8, 4}, {2, 0, 4, 9}}; 22 int i, j; 23 24 // 输出二维数组x占用的内存字节数 25 printf("sizeof(x) = %d\n", sizeof(x)); 26 27 // 输出每个元素的地址、值 28 for (i = 0; i < M; ++i) 29 for (j = 0; j < N; ++j) 30 printf("%p: %d\n", &x[i][j], x[i][j]); 31 printf("\n"); 32 33 // 输出二维数组名x, 以及,x[0], x[1]的值 34 printf("x = %p\n", x); 35 printf("x[0] = %p\n", x[0]); 36 printf("x[1] = %p\n", x[1]); 37 printf("\n"); 38 } 39 40 int main() { 41 printf("测试1: int型一维数组\n"); 42 test1(); 43 44 printf("\n测试2: int型二维数组\n"); 45 test2(); 46 47 return 0; 48 }

问题1:一维数组x在内存中是否连续存放?x和&x[0]的值相同吗?
连续。相同。
问题2:二维数组x在内存中是否按行连续存放?x、x[0]和&x[0][0]的值相同吗?x[0]和x[1]相差多少?该差值的含义是什么?
连续。相同。相差16。该数组中第二行首个地址与第一行首个地址相差16,意味着该数组第一行中含有4个int类型整数,而一个int类型整数占4个字节。
task2
1 #include <stdio.h> 2 #define N 100 3 4 // 函数声明 5 void input(int x[], int n); 6 double compute(int x[], int n); 7 8 int main() { 9 int x[N]; 10 int n, i; 11 double ans; 12 13 while(printf("Enter n: "), scanf("%d", &n) != EOF) { 14 input(x, n); // 函数调用 15 ans = compute(x, n); // 函数调用 16 printf("ans = %.2f\n\n", ans); 17 } 18 19 return 0; 20 } 21 22 // 函数定义 23 void input(int x[], int n) { 24 int i; 25 26 for(i = 0; i < n; ++i) 27 scanf("%d", &x[i]); 28 } 29 30 // 函数定义 31 double compute(int x[], int n) { 32 int i, high, low; 33 double ans; 34 35 high = low = x[0]; 36 ans = 0; 37 38 for(i = 0; i < n; ++i) { 39 ans += x[i]; 40 41 if(x[i] > high) 42 high = x[i]; 43 else if(x[i] < low) 44 low = x[i]; 45 } 46 47 ans = (ans - high - low)/(n-2); 48 49 return ans; 50 }

问题1:一维数组作为参数时(以input函数为例),形参、实参书写形式分别是什么?
x,x[ ]。
问题2:函数input的功能是?函数compute的功能是?
input的功能是从键盘上获得输入,将输入的数据存放在数组x[ ]中。compute的功能是在得出数组x[ ]中最大值和最小值后,得出数组中所有数据减去最大值和最小值后的和的平均值。
task3
1 #include <stdio.h> 2 #define N 100 3 4 // 函数声明 5 void output(int x[][N], int n); 6 void init(int x[][N], int n, int value); 7 8 int main() { 9 int x[N][N]; 10 int n, value; 11 12 while(printf("Enter n and value: "), scanf("%d%d", &n, &value) != EOF) { 13 init(x, n, value); // 函数调用 14 output(x, n); // 函数调用 15 printf("\n"); 16 } 17 18 return 0; 19 } 20 21 // 函数定义 22 void output(int x[][N], int n) { 23 int i, j; 24 25 for(i = 0; i < n; ++i) { 26 for(j = 0; j < n; ++j) 27 printf("%d ", x[i][j]); 28 printf("\n"); 29 } 30 } 31 32 // 函数定义 33 void init(int x[][N], int n, int value) { 34 int i, j; 35 36 for(i = 0; i < n; ++i) 37 for(j = 0; j < n; ++j) 38 x[i][j] = value; 39 }

问题1:两维数组作为函数参数时(以函数output为例),形参、实参书写形式分别是什么?
x,x[ ][N]。
问题2:两维数组作为函数形参时,第二维大小能省略吗?(以函数output为例,试着把形参x[][N]写成x[][],编译代码,观察编译器是否报错)
不能。
问题3:函数output的功能是?函数init的功能是?
output的功能是输出数组x[ ][N],形成一个n*n阶的矩阵。init的功能是将从键盘上输入的value值赋予x[ ][N],形成x[n][n],该数组每个值都为输入value值。
task4
1 #include <stdio.h> 2 #define N 100 3 4 double median(int x[N], int n); 5 void input(int x[N], int n); 6 7 int main() { 8 int x[N]; 9 int n; 10 double ans; 11 12 while (printf("Enter n: "), scanf_s("%d", &n) != EOF) { 13 input(x, n); 14 ans = median(x, n); 15 printf("ans = %g\n\n", ans); 16 } 17 18 return 0; 19 } 20 double median(int x[N],int n) { 21 int i, j,t; 22 for(i = 0;i < n-1;++i) 23 for (j = 0; j < n - 1 - i; ++j) 24 if (x[j] > x[j + 1]) { 25 t = x[j]; 26 x[j] = x[j + 1]; 27 x[j + 1] = t; 28 } 29 if (n % 2 == 0) 30 return (double)(x[n / 2] + x[n / 2 - 1]) / 2; 31 return x[(n - 1) / 2]; 32 } 33 34 void input(int x[N], int n) { 35 for (int i = 0; i < n; ++i) 36 scanf_s("%d", &x[i]); 37 }

task5
1 #include <stdio.h> 2 #define N 100 3 4 void input(int x[][N], int n); 5 void output(int x[][N], int n); 6 int rotate_to_right(int x[][N], int n); 7 8 int main() { 9 int x[N][N]; 10 int n; 11 12 printf("输入n: "); 13 scanf_s("%d", &n); 14 input(x, n); 15 16 printf("原始矩阵:\n"); 17 output(x, n); 18 19 x[N][N] = rotate_to_right(x, n); 20 printf("变换后矩阵:\n"); 21 output(x, n); 22 23 return 0; 24 } 25 26 int rotate_to_right(int x[][N], int n) { 27 int t[N][1]; 28 for (int m = 0;m < n;++m) 29 t[m][0] = x[m][n - 1]; 30 for (int i = n - 1; i >= 0; --i) 31 for(int j = n - 1;j > 0;--j) 32 x[i][j] = x[i][j - 1]; 33 for (int m = 0; m < n; ++m) 34 x[m][0] = t[m][0]; 35 return x[n][n]; 36 } 37 38 void input(int x[][N], int n) { 39 int i, j; 40 41 for (i = 0; i < n; ++i) { 42 for (j = 0; j < n; ++j) 43 scanf_s("%d", &x[i][j]); 44 } 45 } 46 47 void output(int x[][N], int n) { 48 int i, j; 49 50 for (i = 0; i < n; ++i) { 51 for (j = 0; j < n; ++j) 52 printf("%4d", x[i][j]); 53 54 printf("\n"); 55 } 56 }

task6
1 #include <stdio.h> 2 #define N 100 3 void dec_to_n(int x, int n); // 函数声明 4 5 int main() { 6 int x; 7 8 while (printf("输入十进制整数: "), scanf_s("%d", &x) != EOF) { 9 dec_to_n(x, 2); // 函数调用: 把x转换成二进制输出 10 dec_to_n(x, 8); // 函数调用: 把x转换成八进制输出 11 dec_to_n(x, 16); // 函数调用: 把x转换成十六进制输出 12 13 printf("\n"); 14 } 15 16 return 0; 17 } 18 19 void dec_to_n(int x, int n) { 20 int y[N]; 21 int i = 0, j; 22 do { 23 y[i] = x % n; 24 i += 1; 25 x /= n; 26 } while (x); 27 for (j = i-1; j >= 0; --j) { 28 if (y[j] < 10) 29 printf("%d", y[j]); 30 else 31 printf("%c", y[j] - 10 + 'A'); 32 } 33 printf("\n"); 34 }

task7
1 #include <stdio.h> 2 #define N 100 3 4 void input(int x[][N], int n); 5 void output(int x[][N], int n); 6 int is_magic(int x[][N], int n); 7 8 int main() { 9 int x[N][N]; 10 int n; 11 12 while (printf("输入n: "), scanf_s("%d", &n) != EOF) { 13 printf("输入方阵:\n"); 14 input(x, n); 15 16 printf("输出方阵:\n"); 17 output(x, n); 18 19 if (is_magic(x, n)) 20 printf("是魔方矩阵\n\n"); 21 else 22 printf("不是魔方矩阵\n\n"); 23 } 24 25 return 0; 26 } 27 28 int is_magic(int x[][N], int n) { 29 int t = n*(n * n + 1) / 2; 30 int m = 0; 31 for (int i = 0; i < n; ++i) { 32 for (int j = 0; j < n; ++j) 33 m += x[i][j]; 34 if (m != t) 35 return 0; 36 m = 0; 37 } 38 for (int i = 0; i < n; ++i) { 39 for (int j = 0; j < n; ++j) 40 m += x[j][i]; 41 if (m != t) 42 return 0; 43 m = 0; 44 } 45 for (int i = 0; i < n; ++i) 46 for (int j = 0; j < n; ++j) 47 if (i == j) 48 m += x[i][j]; 49 if (m != t) 50 return 0; 51 m = 0; 52 for (int i = 0; i < n; ++i) 53 for (int j = 0; j < n; ++j) 54 if (i + j == n - 1) 55 m += x[i][j]; 56 if (m != t) 57 return 0; 58 return 1; 59 } 60 61 void input(int x[][N], int n) { 62 int i, j; 63 64 for (i = 0; i < n; ++i) { 65 for (j = 0; j < n; ++j) 66 scanf_s("%d", &x[i][j]); 67 } 68 } 69 void output(int x[][N], int n) { 70 int i, j; 71 72 for (i = 0; i < n; ++i) { 73 for (j = 0; j < n; ++j) 74 printf("%4d", x[i][j]); 75 76 printf("\n"); 77 } 78 }




思路:魔方矩阵要求元素的排列需满足:每行、每列、两条对角线上的和均等于幻和 n(n²+1)/2。因此将其拆分为三部分:每行,每列,两对角线都要满足要求。利用for循环得出每行,每列,俩对角线值再与n(n²+1)/2做判断,只要有一个值不符合就终止,得出该矩阵不是魔方矩阵,只有当所有条件都满足时才为魔方矩阵。
task8
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define N 100 4 5 int here_u_r(int x[N],int num); 6 7 int main() { 8 int x[N],ans; 9 int num = 0; 10 while (1) { 11 ans = here_u_r(x,num); 12 num += 1; 13 if (ans == 0) 14 continue; 15 printf("Let's see...WOW!居然是%d诶!", ans); 16 break; 17 } 18 return 0; 19 } 20 21 int here_u_r(int x[N],int num) { 22 int n = num * num, m = num * num * num; 23 int i = 0; 24 while (n != 0) { 25 x[i++] = n % 10; 26 n /= 10; 27 } 28 while (m != 0) { 29 x[i++] = m % 10; 30 m /= 10; 31 } 32 if (i != 10) 33 return 0; 34 for (int j = 0; j < 10; ++j) 35 for (int l = j + 1; l < 10; ++l) 36 if (x[j] == x[l]) 37 return 0; 38 return num; 39 }

思路:(瞪眼法得出bushi)首先要有一个被判断的数,一开始我想利用随机数,然后运行了5分钟都没得出答案,只好改为从0开始递增(话说,总共只有一个答案69,那找到一个就终止是什么意思啊喂!)。条件是:它的平方值与立方值一共使用了0到9十个数字,且一个数字只是用一次。那么,首先要判断平方和立方的数字个数之和要为10,不为10肯定不对;接着根据题意,数字为0~9,没有重复,因此判断10个数是否有相同的,如果有则不对,当满足这两个条件时则成立。至于方法则是数字个数和大小则放在数组中判断。
实验总结
1.实验4中printf中用了%g,其作用是自动去掉末尾无效的0,按需选择小数/科学计数法,让输出更简洁。对比%f和%e,%f固定小数形式,默认6位小数,%e强制科学计数法。
2.实验8,这条题目我无法像以前一样先写框架再填充细节,需要先将大体思路想好才能流畅地写代码。一开始我想的是用char类型x[],将数字从大到小排序后再与{0,1,2,3,4,5,6,7,8,9}对比.......等下,这个好像也行,咋不用呢?(好吧,这是走在路上想的,走到地了就忘了doge)。于是我就又想了一个,就用int类型x[],先通过限制数字个数的方式缩小范围,再根据数字不重复得出答案。第二个方法写起来简单一点,第一个方法还要用冒泡排序。
2026-05-05

浙公网安备 33010602011771号