实验四
task1.c
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 int main() { 8 int x[N][N]; 9 int n; 10 while(printf("输入n: "), scanf("%d", &n) != EOF) { 11 printf("输入方阵:\n"); 12 input(x, n); 13 printf("输出方阵:\n"); 14 output(x, n); 15 if(is_magic(x, n)) 16 printf("是魔方矩阵\n\n"); 17 else 18 printf("不是魔方矩阵\n\n"); 19 } 20 return 0; 21 } 22 23 void input(int x[][N], int n) { 24 int i, j; 25 for (i = 0; i < n; ++i) { 26 for (j = 0; j < n; ++j) 27 scanf("%d", &x[i][j]); 28 } 29 } 30 31 void output(int x[][N], int n) { 32 int i, j; 33 for (i = 0; i < n; ++i) { 34 for (j = 0; j < n; ++j) 35 printf("%4d", x[i][j]); 36 printf("\n"); 37 } 38 } 39 40 int is_magic(int x[][N], int n) { 41 int i, j; 42 int sum_row, sum_col; 43 int sum_diag1 = 0, sum_diag2 = 0; 44 int target = n * (n * n + 1) / 2; 45 46 for (i = 0; i < n; i++) { 47 sum_diag1 += x[i][i]; 48 sum_diag2 += x[i][n - 1 - i]; 49 } 50 if (sum_diag1 != target || sum_diag2 != target) { 51 return 0; 52 } 53 54 for (i = 0; i < n; i++) { 55 sum_row = 0; 56 for (j = 0; j < n; j++) { 57 sum_row += x[i][j]; 58 } 59 if (sum_row != target) { 60 return 0; 61 } 62 } 63 64 for (j = 0; j < n; j++) { 65 sum_col = 0; 66 for (i = 0; i < n; i++) { 67 sum_col += x[i][j]; 68 } 69 if (sum_col != target) { 70 return 0; 71 } 72 } 73 74 return 1; 75 }

问题一:
一维数组 x 在内存中是连续存放的,就像一串首尾相接的车厢,每个元素一个挨着一个排,中间不会有空隙; x 和 &x[0] 的值是完全相同的, x 是数组名,它本身就代表数组首元素的地址,和直接取第一个元素 x[0] 的地址结果是一样的。
问题二:维数组 x 在内存中是按行优先连续存放的,就像把表格一行一行拉直成一条直线,先存完第一行所有元素,再接着存第二行,全程没有断开; x 、 x[0] 和 &x[0][0] 的值也是完全相同的,都指向二维数组第一个元素的地址; x[0] 和 x[1] 相差的字节数等于一行元素占用的总内存大小,比如一行有4个 int 元素、每个 int 占4字节,差值就是16字节,这个差值代表了从第0行首地址到第1行首地址需要跨过的内存空间,也就是一整行数据的总大小。
task2.c
1 #include <stdio.h> 2 #define N 100 3 4 void input(int x[], int n); 5 double compute(int x[], int n); 6 7 int main() { 8 int x[N]; 9 int n, i; 10 double ans; 11 12 while(printf("Enter n: "), scanf("%d", &n) != EOF) { 13 input(x, n); 14 ans = compute(x, n); 15 printf("ans = %.2f\n\n", ans); 16 } 17 18 return 0; 19 } 20 21 void input(int x[], int n) { 22 int i; 23 24 for(i = 0; i < n; ++i) 25 scanf("%d", &x[i]); 26 } 27 28 double compute(int x[], int n) { 29 int i, high, low; 30 double ans; 31 32 high = low = x[0]; 33 ans = 0; 34 35 for(i = 0; i < n; ++i) { 36 ans += x[i]; 37 38 if(x[i] > high) 39 high = x[i]; 40 else if(x[i] < low) 41 low = x[i]; 42 } 43 44 ans = (ans - high - low)/(n-2); 45 46 return ans; 47 }

问题1:
以 input 函数为例,一维数组作为形参时,写法是 int x[] (也可以写成 int *x );实参直接写数组名 x 就行,不用加括号或者地址符,直接传数组名就代表把数组的首地址传给函数了。
问题2:
input 函数的功能是从键盘读取 n 个整数,存到数组 x 里; compute 函数的功能是先算出数组里所有数的总和,再减去最大值和最小值,最后用剩下的总和除以 n-2 ,得到去掉一个最高分和一个最低分后的平均分。
task3.c
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 void output(int x[][N], int n) { 22 int i, j; 23 24 for(i = 0; i < n; ++i) { 25 for(j = 0; j < n; ++j) 26 printf("%d ", x[i][j]); 27 printf("\n"); 28 } 29 } 30 31 void init(int x[][N], int n, int value) { 32 int i, j; 33 34 for(i = 0; i < n; ++i) 35 for(j = 0; j < n; ++j) 36 x[i][j] = value; 37 }

问题1:
以 output 函数为例,二维数组作为形参时,写法是 int x[][N] ,第二维的大小必须写死(这里是宏定义的 N );实参直接写二维数组名 x 就行,和一维数组一样,直接传数组名就代表把二维数组的首地址传给函数了。
问题2:
不能省略第二维的大小,如果你把形参写成 x[][] ,编译器会直接报错,因为C语言规定二维数组作为函数参数时,必须明确第二维的长度,不然编译器没法计算每个元素的内存地址偏移。
问题3:
output 函数的功能是按行输出n×n的二维数组,把每个元素都打印出来; init 函数的功能是给n×n的二维数组所有元素统一赋值为传入的 value 值。
task4.c
1 #include <stdio.h> 2 #define N 100 3 // 函数声明 4 void input(int x[], int n); 5 double median(int x[], int n); 6 int main() { 7 int x[N]; 8 int n; 9 double ans; 10 while(printf("Enter n: "), scanf("%d", &n) != EOF) { 11 input(x, n); // 函数调用:录入数据 12 ans = median(x, n); // 函数调用:计算中值 13 printf("ans = %g\n\n", ans); 14 } 15 return 0; 16 } 17 18 void input(int x[], int n) { 19 int i; 20 for(i = 0; i < n; i++) { 21 scanf("%d", &x[i]); 22 } 23 } 24 25 double median(int x[], int n) { 26 int i, j, temp; 27 28 for(i = 0; i < n-1; i++) { 29 for(j = 0; j < n-1-i; j++) { 30 if(x[j] > x[j+1]) { 31 temp = x[j]; 32 x[j] = x[j+1]; 33 x[j+1] = temp; 34 } 35 } 36 } 37 38 if(n % 2 == 1) { 39 40 return x[n/2]; 41 } else { 42 43 return (x[n/2 - 1] + x[n/2]) / 2.0; 44 } 45 }

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

task6.c
1 #include <stdio.h> 2 #include<stdio.h> 3 #define N 100 4 void dec_to_n(int x, int n); 5 int main(){ 6 int x; 7 while(printf("输入十进制整数"),scanf("%d",&x)!=EOF){ 8 printf("二进制:"); 9 dec_to_n(x,2); 10 printf("八进制:"); 11 dec_to_n(x,8); 12 printf("十六进制:"); 13 dec_to_n(x,16); 14 printf("\n"); 15 } 16 return 0; 17 } 18 void dec_to_n(int x,int n){ 19 int stack[N],top = 0; 20 int num = x; 21 if(num == 0){ 22 printf("0\n"); 23 return; 24 } 25 if(num < 0){ 26 printf("-"); 27 num=-num; 28 } 29 while(num > 0){ 30 int rem = num % n; 31 stack[top++]=rem; 32 num=num/n; 33 } 34 while(top>0){ 35 int val=stack[--top]; 36 if(val<10){ 37 printf("%d",val); 38 } 39 else{ 40 printf("%c",'A'+(val-10)); 41 42 } 43 } 44 printf("\n"); 45 }

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



浙公网安备 33010602011771号