实验4 C语言数组应用编程
1.实验任务1
task1_1源代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define N 4 4 5 void test1() { 6 int a[N] = {1, 9, 8, 4}; 7 int i; 8 9 // 输出数组a占用的内存字节数 10 printf("sizeof(a) = %d\n", sizeof(a)); 11 12 // 输出int类型数组a中每个元素的地址、值 13 for (i = 0; i < N; ++i) 14 printf("%p: %d\n", &a[i], a[i]); 15 16 // 输出数组名a对应的值 17 printf("a = %p\n", a); 18 } 19 20 void test2() { 21 char b[N] = {'1', '9', '8', '4'}; 22 int i; 23 24 // 输出数组b占用的内存字节数 25 printf("sizeof(b) = %d\n", sizeof(b)); 26 27 // 输出char类型数组b中每个元素的地址、值 28 for (i = 0; i < N; ++i) 29 printf("%p: %c\n", &b[i], b[i]); 30 31 // 输出数组名b对应的值 32 printf("b = %p\n", b); 33 } 34 35 int main() { 36 printf("测试1: int类型一维数组\n"); 37 test1(); 38 39 printf("\n测试2: char类型一维数组\n"); 40 test2(); 41 42 system("pause"); 43 return 0; 44 }
task1_1运行截图:
回答问题:
① int型数组a,在内存中是否是连续存放的?每个元素占用几个内存字节单元? 数组名a对应的值,和&a[0]是一样的吗?
答:是连续存放的;每个元素占用4个内存字节单元;数组名a对应的值和&a[0]是一样的。
② char型数组b,在内存中是否是连续存放的?每个元素占用几个内存字节单元? 数组名b对应的值,和&b[0]是一样的吗?
答:是连续存放的;每个元素占用1个内存字节单元;数组名b对应的值和&b[0]是一样的。
task1_2源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 2 4 #define M 4 5 6 void test1() { 7 int a[N][M] = {{1, 9, 8, 4}, {2, 0, 4, 9}}; 8 int i, j; 9 10 // 输出int类型二维数组a占用的内存字节数 11 printf("sizeof(a) = %d\n", sizeof(a)); 12 13 // 输出int类型二维数组a中每个元素的地址、值 14 for (i = 0; i < N; ++i) 15 for (j = 0; j < M; ++j) 16 printf("%p: %d\n", &a[i][j], a[i][j]); 17 printf("\n"); 18 19 // 输出int类型二维数组名a, 以及,a[0], a[1]的值 20 printf("a = %p\n", a); 21 printf("a[0] = %p\n", a[0]); 22 printf("a[1] = %p\n", a[1]); 23 printf("\n"); 24 } 25 26 void test2() { 27 char b[N][M] = {{'1', '9', '8', '4'}, {'2', '0', '4', '9'}}; 28 int i, j; 29 30 // 输出char类型二维数组b占用的内存字节数 31 printf("sizeof(b) = %d\n", sizeof(b)); 32 33 // 输出char类型二维数组b中每个元素的地址、值 34 for (i = 0; i < N; ++i) 35 for (j = 0; j < M; ++j) 36 printf("%p: %c\n", &b[i][j], b[i][j]); 37 printf("\n"); 38 39 // 输出char类型二维数组名b, 以及,b[0], b[1]的值 40 printf("b = %p\n", b); 41 printf("b[0] = %p\n", b[0]); 42 printf("b[1] = %p\n", b[1]); 43 } 44 45 int main() { 46 printf("测试1: int型两维数组"); 47 test1(); 48 49 printf("\n测试2: char型两维数组"); 50 test2(); 51 52 system("pause"); 53 return 0; 54 }
task1_2运行截图:
回答问题:
① int型二维数组a,在内存中是否是"按行连续存放"的?每个元素占用几个内存字节单元? 数组名a的值、a[0]的值、&a[0][0]的值,在数字字面值上,是一样的吗?
答:是连续存放的;每个元素占用4个内存字节单元;数组名a的值、a[0]的值、&a[0][0]的值在数字字面值上是一样的。
② char型二维数组b,在内存中是否是"按行连续存放"的?每个元素占用几个内存字节单元?数组名b的值、b[0]的值、&b[0][0]的值,在数字字面值上,是一样的吗?
答:是连续存放的;每个元素占用1个内存字节单元;数组名b的值、b[0]的值、&b[0][0]的值在数字字面值上是一样的。
③ 对于二维数组, 观察a[0], a[1]的值,它们之间相差多少?观察b[0]和b[1]的值,它们之间相差多少?有什么规律吗?
答:a[0], a[1]的值相差16个字节;b[0],b[1]的值相差4个字节;恰为数组占用字节的一半(每个数组恰只有2行)。
2.实验任务2
task2源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include <string.h> 4 5 #define N 80 6 7 void swap_str(char s1[N], char s2[N]); 8 void test1(); 9 void test2(); 10 11 int main() { 12 printf("测试1: 用两个一维char数组,实现两个字符串交换\n"); 13 test1(); 14 15 printf("\n测试2: 用二维char数组,实现两个字符串交换\n"); 16 test2(); 17 18 system("pause"); 19 return 0; 20 } 21 22 void test1() { 23 char views1[N] = "hey, C, I hate u."; 24 char views2[N] = "hey, C, I love u."; 25 26 printf("交换前: \n"); 27 puts(views1); 28 puts(views2); 29 30 swap_str(views1, views2); 31 32 printf("交换后: \n"); 33 puts(views1); 34 puts(views2); 35 } 36 37 void test2() { 38 char views[2][N] = {"hey, C, I hate u.", 39 "hey, C, I love u."}; 40 41 printf("交换前: \n"); 42 puts(views[0]); 43 puts(views[1]); 44 45 swap_str(views[0], views[1]); 46 47 printf("交换后: \n"); 48 puts(views[0]); 49 puts(views[1]); 50 } 51 52 void swap_str(char s1[N], char s2[N]) { 53 char tmp[N]; 54 55 strcpy(tmp, s1); 56 strcpy(s1, s2); 57 strcpy(s2, tmp); 58 }
task2运行截图:
问:函数模块swap_str()的形参是一维数组。为什么test1()和test2()模块中调用时,实参的书写形式一个不加[]、一个加[]?
答:test1中应用的是一维数组;test2中应用的是二维数组,调用时要表示是哪一行。
3.实验任务3
task3_1源代码:
1 /* 2 从键盘输入一行英文文本,统计英文单词总数 3 为了简化问题处理,只考虑单词以空格间隔的情形 4 对教材例5.22代码做了些微改动: 5 1. 统计单词个数,编写成函数模块;增加了多组输入 6 2. 去掉了不必要的中间变量 7 */ 8 9 #include <stdio.h> 10 #include<stdlib.h> 11 12 #define N 80 13 14 int count(char x[]); 15 16 int main() { 17 char words[N+1]; 18 int n; 19 20 while(gets(words) != NULL) { 21 n = count(words); 22 printf("单词数: %d\n\n", n); 23 } 24 25 system("pause"); 26 return 0; 27 } 28 29 int count(char x[]) { 30 int i; 31 int word_flag = 0; // 用作单词标志,一个新单词开始,值为1;单词结束,值为0 32 int number = 0; // 统计单词个数 33 34 for(i = 0; x[i] != '\0'; i++) { 35 if(x[i] == ' ') 36 word_flag = 0; 37 else if(word_flag == 0) { 38 word_flag = 1; 39 number++; 40 } 41 } 42 43 return number; 44 }
task3_1运行截图:
task3_2源代码:
1 /* 2 输入一行英文文本,统计最长单词,并打印输出。 3 为简化问题,只考虑单词之间用空格间隔的情形。 4 相较于教材例5.24,做了以下改动: 5 1. 增加了多组输入,因此,一些变量初始化放到了第一层循环里面 6 2. 微调了代码书写逻辑和顺序 7 */ 8 9 #include <stdio.h> 10 #include<stdlib.h> 11 #define N 1000 12 13 int main() { 14 char line[N]; 15 int word_len; // 记录当前单词长度 16 int max_len; // 记录最长单词长度 17 int end; // 记录最长单词结束位置 18 int i; 19 20 while(gets(line) != NULL) { 21 word_len = 0; 22 max_len = 0; 23 end = 0; 24 25 i = 0; 26 while(1) { 27 // 跳过连续空格 28 while(line[i] == ' ') { 29 word_len = 0; // 单词长度置0,为新单词统计做准备 30 i++; 31 } 32 33 // 在一个单词中,统计当前单词长度 34 while(line[i] != '\0' && line[i] != ' ') { 35 word_len++; 36 i++; 37 } 38 39 // 更新更长单词长度,并,记录最长单词结束位置 40 if(max_len < word_len) { 41 max_len = word_len; 42 end = i; // end保存的是单词结束的下一个坐标位置 43 } 44 45 // 遍历到文本结束时,终止循环 46 if(line[i] == '\0') 47 break; 48 } 49 50 // 输出最长单词 51 printf("最长单词: "); 52 for(i = end - max_len; i < end; ++i) 53 printf("%c", line[i]); 54 printf("\n\n"); 55 } 56 57 system("pause"); 58 return 0; 59 }
task3_2运行截图:
思考:符号算字
源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 4 #define N 80 5 6 int count(char x[]); 7 8 int main() { 9 char words[N+1]; 10 int n; 11 12 while(gets(words) != NULL) { 13 n = count(words); 14 printf("单词数: %d\n\n", n); 15 } 16 17 system("pause"); 18 return 0; 19 } 20 21 int count(char x[]) { 22 int i; 23 int word_flag = 0; // 用作单词标志,一个新单词开始,值为1;单词结束,值为0 24 int number = 0; // 统计单词个数 25 26 for(i = 0; x[i] != '\0'; i++) { 27 if(x[i] == ' ') 28 word_flag = 0; 29 else if(x[i]==','||x[i]=='.'||x[i]==':'||x[i]==';'||x[i]=='"'||x[i]=='?'||x[i]=='<'||x[i]=='!'){ 30 number++; 31 word_flag=0;} 32 else if(word_flag == 0) { 33 word_flag = 1; 34 number++; 35 } 36 } 37 38 return number; 39 }
运行截图:
4.实验任务4
task4源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 100 4 void dec_to_n(int x, int n); // 函数声明 5 6 int main() { 7 int x; 8 9 printf("输入一个十进制整数: "); 10 while(scanf("%d", &x) != EOF) { 11 dec_to_n(x, 2); // 函数调用: 把x转换成二进制输出 12 dec_to_n(x, 8); // 函数调用: 把x转换成八进制输出 13 dec_to_n(x, 16); // 函数调用: 把x转换成十六进制输出 14 15 printf("\n输入一个十进制整数: "); 16 } 17 18 system("pause"); 19 return 0; 20 } 21 22 23 void dec_to_n(int x, int n){ 24 char zu[]={"0123456789ABCDEF"}; 25 int a[N]; 26 int i=0,p; 27 do{ 28 p=x%n; 29 a[i++]=zu[p]; 30 x=x/n; 31 }while(x!=0); 32 for(i=i-1;i>=0;i--) 33 printf("%c",a[i]); 34 printf("\n"); 35 }
task4运行截图:
5.实验任务5
task5源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 5 4 5 // 函数声明 6 void input(int x[], int n); 7 void output(int x[], int n); 8 double average(int x[], int n); 9 void bubble_sort(int x[], int n); 10 11 int main() { 12 int scores[N]; 13 double ave; 14 15 printf("录入%d个分数:\n", N); 16 input(scores, N); 17 18 printf("\n输出课程分数: \n"); 19 output(scores, N); 20 21 printf("\n课程分数处理: 计算均分、排序...\n"); 22 ave = average(scores, N); 23 bubble_sort(scores, N); 24 25 printf("\n输出课程均分: %.2f\n", ave); 26 printf("\n输出课程分数(高->低):\n"); 27 output(scores, N); 28 29 system("pause"); 30 return 0; 31 } 32 33 // 函数定义 34 // 输入n个整数保存到整型数组x中 35 void input(int x[], int n) { 36 int i; 37 38 for(i = 0; i < n; ++i) 39 scanf("%d", &x[i]); 40 } 41 42 // 输出整型数组x中n个元素 43 void output(int x[], int n) { 44 int i; 45 46 for(i = 0; i < n; ++i) 47 printf("%d ", x[i]); 48 printf("\n"); 49 } 50 51 // 计算整型数组x中n个元素均值,并返回 52 double average(int x[], int n){ 53 double ave; 54 int i; 55 ave=0; 56 for(i=0;i<n;i++) 57 ave+=x[i]; 58 return ave*1.0/n; 59 } 60 61 62 63 // 对整型数组x中的n个元素降序排序 64 void bubble_sort(int x[], int n){ 65 int i,j,p; 66 for(i=0;i<n-1;i++){ 67 for(j=0;j<n-i-1;j++){ 68 if(x[j]<x[j+1]){ 69 p=x[j]; 70 x[j]=x[j+1]; 71 x[j+1]=p;} 72 } 73 } 74 }
task5运行截图:
6.实验任务6
task6源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include <string.h> 4 5 #define N 5 6 #define M 20 7 8 // 函数声明 9 void output(char str[][M], int n); 10 void bubble_sort(char str[][M], int n); 11 12 int main() { 13 char name[][M] = {"Bob", "Bill", "Joseph", "Taylor", "George"}; 14 int i; 15 16 printf("输出初始名单:\n"); 17 output(name, N); 18 19 printf("\n排序中...\n"); 20 bubble_sort(name, N); // 函数调用 21 22 printf("\n按字典序输出名单:\n"); 23 output(name, N); 24 25 system("pause"); 26 return 0; 27 } 28 29 // 函数定义 30 // 功能:按行输出二维数组中的字符串 31 void output(char str[][M], int n) { 32 int i; 33 34 for(i = 0; i < n; ++i) 35 printf("%s\n", str[i]); 36 } 37 38 // 函数定义 39 // 功能:使用冒泡排序算法对二维数组str中的n个字符串按字典序排序 40 void bubble_sort(char str[][M], int n){ 41 int i,j; 42 char a[20]; 43 for(i=0;i<n-1;i++){ 44 for(j=0;j<n-i-1;j++){ 45 if(strcmp(str[j],str[j+1])>0){ 46 strcpy(a,str[j]); 47 strcpy(str[j],str[j+1]); 48 strcpy(str[j+1],a); 49 }}} 50 }
task6运行截图:
7.实验任务7
task7源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include <string.h> 4 5 int main(){ 6 char a[110]; 7 int n; 8 int s; 9 while (scanf("%s", a) != EOF) { 10 int flag = 0; 11 for (n = 0; n < strlen(a); n++) { 12 for (s = n + 1; s < strlen(a); s++) { 13 if (a[n] == a[s]) { 14 flag = 1; 15 break; 16 } 17 } 18 if (flag == 1) { 19 break; 20 } 21 } 22 if (flag == 1) { 23 printf("YES\n\n"); 24 } 25 else if (flag == 0) { 26 printf("NO\n\n"); 27 } 28 } 29 system("pause"); 30 return 0; 31 }
task7运行截图:
8.实验任务8
task8源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 100 4 #define M 4 5 6 // 函数声明 7 void output(int x[][N], int n); 8 void rotate_to_right(int x[][N], int n); 9 10 11 int main() { 12 int t[][N] = {{21, 12, 13, 24}, 13 {25, 16, 47, 38}, 14 {29, 11, 32, 54}, 15 {42, 21, 33, 10}}; 16 17 printf("原始矩阵:\n"); 18 output(t, M); // 函数调用 19 20 rotate_to_right(t, M); // 函数调用 21 22 printf("变换后矩阵:\n"); 23 output(t, M); // 函数调用 24 25 system("pause"); 26 return 0; 27 } 28 29 // 函数定义 30 // 功能: 输出一个n*n的矩阵x 31 void output(int x[][N], int n) { 32 int i, j; 33 34 for (i = 0; i < n; ++i) { 35 for (j = 0; j < n; ++j) 36 printf("%4d", x[i][j]); 37 38 printf("\n"); 39 } 40 } 41 42 // 待补足3:函数rotate_to_right()定义 43 // 功能: 把一个n*n的矩阵x,每一列向右移, 最右边被移出去的一列绕回左边 44 void rotate_to_right(int x[][N], int n) { 45 int mid[M]; 46 int j,i; 47 for (j = 0; j < n; j++) { 48 mid[j] = x[j][M - 1]; 49 } 50 for (j = 0; j < n; j++) { 51 for (i = n-1; i >= 1; i--) { 52 x[j][i] = x[j][i - 1]; 53 } 54 } 55 for (i = 0; i < n; i++) { 56 x[i][0] = mid[i]; 57 } 58 }
task8运行截图: