实验5 C语言指针应用编程
1. 实验任务1
task1_1源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 5 4 5 void input(int x[], int n); 6 void output(int x[], int n); 7 void find_min_max(int x[], int n, int *pmin, int *pmax); 8 9 int main() { 10 int a[N]; 11 int min, max; 12 13 printf("录入%d个数据:\n", N); 14 input(a, N); 15 16 printf("数据是: \n"); 17 output(a, N); 18 19 printf("数据处理...\n"); 20 find_min_max(a, N, &min, &max); 21 22 printf("输出结果:\n"); 23 printf("min = %d, max = %d\n", min, max); 24 25 system("pause"); 26 return 0; 27 } 28 29 void input(int x[], int n) { 30 int i; 31 32 for(i = 0; i < n; ++i) 33 scanf("%d", &x[i]); 34 } 35 36 void output(int x[], int n) { 37 int i; 38 39 for(i = 0; i < n; ++i) 40 printf("%d ", x[i]); 41 printf("\n"); 42 } 43 44 void find_min_max(int x[], int n, int *pmin, int *pmax) { 45 int i; 46 47 *pmin = *pmax = x[0]; 48 49 for(i = 1; i < n; ++i) 50 if(x[i] < *pmin) 51 *pmin = x[i]; 52 else if(x[i] > *pmax) 53 *pmax = x[i]; 54 }
task1_1运行截图:
回答问题:
1. 函数find_min_max实现的功能是?
答:利用指针寻找数据中的最大最小值。
2. "指针变量在使用之前必须指向确定的地址"。执行到line47时,指针变量pmin、pmax分别指向什么?
答:x[0]的地址。
task1_2源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 5 4 5 void input(int x[], int n); 6 void output(int x[], int n); 7 int *find_max(int x[], int n); 8 9 int main() { 10 int a[N]; 11 int *pmax; 12 13 printf("录入%d个数据:\n", N); 14 input(a, N); 15 16 printf("数据是: \n"); 17 output(a, N); 18 19 printf("数据处理...\n"); 20 pmax = find_max(a, N); 21 22 printf("输出结果:\n"); 23 printf("max = %d\n", *pmax); 24 25 system("pause"); 26 return 0; 27 } 28 29 void input(int x[], int n) { 30 int i; 31 32 for(i = 0; i < n; ++i) 33 scanf("%d", &x[i]); 34 } 35 36 void output(int x[], int n) { 37 int i; 38 39 for(i = 0; i < n; ++i) 40 printf("%d ", x[i]); 41 printf("\n"); 42 } 43 44 int *find_max(int x[], int n) { 45 int max_index = 0; 46 int i; 47 48 for(i = 1; i < n; ++i) 49 if(x[i] > x[max_index]) 50 max_index = i; 51 52 return &x[max_index]; 53 }
task1_2运行截图:
回答问题:
1. 函数find_max的功能是(返回的是什么)?
答:返回的是数据中最大值的地址。
2. 把函数find_max的实现写成以下代码,可以吗?如果不可以,请给出你的理由。
答:可以。
2. 实验任务2
task2_1源代码:
1 #include <stdio.h> 2 #include <string.h> 3 #define N 80 4 5 int main() { 6 char s1[] = "Learning makes me happy"; 7 char s2[] = "Learning makes me sleepy"; 8 char tmp[N]; 9 10 printf("sizeof(s1) vs. strlen(s1): \n"); 11 printf("sizeof(s1) = %d\n", sizeof(s1)); 12 printf("strlen(s1) = %d\n", strlen(s1)); 13 14 printf("\nbefore swap: \n"); 15 printf("s1: %s\n", s1); 16 printf("s2: %s\n", s2); 17 18 printf("\nswapping...\n"); 19 strcpy(tmp, s1); 20 strcpy(s1, s2); 21 strcpy(s2, tmp); 22 23 printf("\nafter swap: \n"); 24 printf("s1: %s\n", s1); 25 printf("s2: %s\n", s2); 26 27 return 0; 28 }
task2_1运行截图:
回答问题:
1.数组s1的大小是多少?sizeof(s1)计算的是什么?strlen(s1)统计的是什么?
答:大小是23;sizeof计算的是从数组首地址到'\0'的大小,包括'\0';strlen统计的是有效字符的长度。
2.line7代码,能否替换成以下写法?如果不能,写出原因。
答:不行,没有明确s1长度。
3.line20-22执行后,字符数组s1和s2中的内容是否交换?
答:交换了。
task2_2源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include <string.h> 4 #define N 80 5 6 int main() { 7 char *s1 = "Learning makes me happy"; 8 char *s2 = "Learning makes me sleepy"; 9 char *tmp; 10 11 printf("sizeof(s1) vs. strlen(s1): \n"); 12 printf("sizeof(s1) = %d\n", sizeof(s1)); 13 printf("strlen(s1) = %d\n", strlen(s1)); 14 15 printf("\nbefore swap: \n"); 16 printf("s1: %s\n", s1); 17 printf("s2: %s\n", s2); 18 19 printf("\nswapping...\n"); 20 tmp = s1; 21 s1 = s2; 22 s2 = tmp; 23 24 printf("\nafter swap: \n"); 25 printf("s1: %s\n", s1); 26 printf("s2: %s\n", s2); 27 28 system("pause"); 29 return 0; 30 }
task2_2运行截图:
回答问题:
1.指针变量s1中存放的是什么?sizeof(s1)计算的是什么?strlen(s1)统计的是什么?
答:存放的是句子的地址;计算指针的长度(可能为4或8,32位则为4字节,64则为8字节);统计有效字符的长度。
2.line7代码能否替换成下面的写法?对比task2_1.c中的line7, 描述二者的语义区别。
答:可以。上图是利用指针间接访问。
3.line20-line22,交换的是什么?字符串常量"Learning makes me happy"和字符串常量"Learning makes me sleepy"在内存存储单元中有没有交换?
答:交换的是s1和s2所指向的地址;没有交换。
3. 实验任务3
task3源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 4 int main() { 5 int x[2][4] = {{1, 9, 8, 4}, {2, 0, 4, 9}}; 6 int i, j; 7 int *ptr1; // 指针变量,存放int类型数据的地址 8 int(*ptr2)[4]; // 指针变量,指向包含4个int元素的一维数组 9 10 printf("输出1: 使用数组名、下标直接访问二维数组元素\n"); 11 for (i = 0; i < 2; ++i) { 12 for (j = 0; j < 4; ++j) 13 printf("%d ", x[i][j]); 14 printf("\n"); 15 } 16 17 printf("\n输出2: 使用指向元素的指针变量p间接访问二维数组元素\n"); 18 for (ptr1 = &x[0][0], i = 0; ptr1 < &x[0][0] + 8; ++ptr1, ++i) { 19 printf("%d ", *ptr1); 20 21 if ((i + 1) % 4 == 0) 22 printf("\n"); 23 } 24 25 printf("\n输出3: 使用指向一维数组的指针变量q间接访问二维数组元素\n"); 26 for (ptr2 = x; ptr2 < x + 2; ++ptr2) { 27 for (j = 0; j < 4; ++j) 28 printf("%d ", *(*ptr2 + j)); 29 printf("\n"); 30 } 31 32 system("pause"); 33 return 0; 34 }
task3运行截图:
回答问题:
1.int (*ptr)[4]; 中,标识符ptr表示的语义是什么?
答:由于()优先级最高,因而ptr是一个int类型的指针,该指针指向包含4个int变量的数组。(可以把*ptr等价为x)
2、int *ptr[4];中,标识符ptr表示的语义是什么?
答:是一个指向int型的指针数组,即:ptr是包含4个元素的指针数组,指针指向的是int型。
4. 实验任务4
task4_1源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 80 4 5 void replace(char *str, char old_char, char new_char); // 函数声明 6 7 int main() { 8 char text[N] = "c programming is difficult or not, it is a question."; 9 10 printf("原始文本: \n"); 11 printf("%s\n", text); 12 13 replace(text, 'i', '*'); // 函数调用 注意字符形参写法,单引号不能少 14 15 printf("处理后文本: \n"); 16 printf("%s\n", text); 17 18 system("pause"); 19 return 0; 20 } 21 22 // 函数定义 23 void replace(char *str, char old_char, char new_char) { 24 int i; 25 26 while(*str) { 27 if(*str == old_char) 28 *str = new_char; 29 str++; 30 } 31 }
task4_1运行截图:
回答问题:
1. 函数replace的功能是?
答:将字符i全部替换成*。
2. line26, 圆括号里循环条件可以改写成*str != '\0'吗?
答:可以。
task4_2源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 80 4 5 void str_trunc(char *str, char x); 6 7 int main() { 8 char str[N]; 9 char ch; 10 11 printf("输入字符串: "); 12 gets(str); 13 14 printf("输入一个字符: "); 15 ch = getchar(); 16 17 printf("截断处理...\n"); 18 str_trunc(str, ch); 19 20 printf("截断处理后的字符串: %s\n", str); 21 22 system("pause"); 23 } 24 25 void str_trunc(char *str, char x) { 26 while(*str) { 27 if(*str == x) 28 *str = '\0'; // blank1 29 30 str++; // blank2 31 } 32 33 return; // blank3 34 }
task4_2运行截图:
5. 实验任务5
task5_1源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include <string.h> 4 void sort(char *name[], int n); 5 6 int main() { 7 char *course[4] = {"C Program", 8 "C++ Object Oriented Program", 9 "Operating System", 10 "Data Structure and Algorithms"}; 11 int i; 12 13 sort(course, 4); 14 15 for (i = 0; i < 4; i++) 16 printf("%s\n", course[i]); 17 18 system("pause"); 19 return 0; 20 } 21 22 void sort(char *name[], int n) { 23 int i, j; 24 char *tmp; 25 26 for (i = 0; i < n - 1; ++i) 27 for (j = 0; j < n - 1 - i; ++j) 28 if (strcmp(name[j], name[j + 1]) > 0) { 29 tmp = name[j]; 30 name[j] = name[j + 1]; 31 name[j + 1] = tmp; 32 } 33 }
task5_1运行截图:
task5_2源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include <string.h> 4 void sort(char *name[], int n); 5 6 int main() { 7 char *course[4] = {"C Program", 8 "C++ Object Oriented Program", 9 "Operating System", 10 "Data Structure and Algorithms"}; 11 int i; 12 13 sort(course, 4); 14 for (i = 0; i < 4; i++) 15 printf("%s\n", course[i]); 16 17 system("pause"); 18 return 0; 19 } 20 21 void sort(char *name[], int n) { 22 int i, j, k; 23 char *tmp; 24 25 for (i = 0; i < n - 1; i++) { 26 k = i; 27 for (j = i + 1; j < n; j++) 28 if (strcmp(name[j], name[k]) < 0) 29 k = j; 30 31 if (k != i) { 32 tmp = name[i]; 33 name[i] = name[k]; 34 name[k] = tmp; 35 } 36 } 37 }
task5_2运行截图:
回答问题:
1.这两种算法实现中,交换的是指针变量的值,还是内存中字符串的存储位置发生了交换?
答:仅改变了指针变量的值。
6. 实验任务6
task6源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #include <string.h> 4 #define N 5 5 6 int check_id(char *str); // 函数声明 7 8 int main() { 9 char *pid[N] = {"31010120000721656X", 10 "330106199609203301", 11 "53010220051126571", 12 "510104199211197977", 13 "53010220051126133Y"}; 14 int i; 15 16 for (i = 0; i < N; ++i) 17 if (check_id(pid[i])) // 函数调用 18 printf("%s\tTrue\n", pid[i]); 19 else 20 printf("%s\tFalse\n", pid[i]); 21 22 system("pause"); 23 return 0; 24 } 25 26 // 函数定义 27 // 功能: 检查指针str指向的身份证号码串形式上是否合法。 28 // 形式合法,返回1,否则,返回0 29 int check_id(char *str) { 30 // 补足函数实现 31 // ... 32 int t=0; 33 34 if(strlen(str)!=18) 35 return 0; 36 37 while(*str){ 38 switch(*str++){ 39 case '0' : 40 case '1' : 41 case '2' : 42 case '3' : 43 case '4' : 44 case '5' : 45 case '6' : 46 case '7' : 47 case '8' : 48 case '9' : 49 case 'X' :t++;break; 50 default:return 0;} 51 } 52 53 return 1; 54 }
task6运行截图:
7. 实验任务7
task7源代码:
1 #include <stdio.h> 2 #include<stdlib.h> 3 #define N 80 4 void encoder(char *str); // 函数声明 5 void decoder(char *str); // 函数声明 6 7 int main() { 8 char words[N]; 9 10 while(printf("输入英文文本: "),gets(words)!=NULL){ 11 12 printf("编码后的英文文本: "); 13 encoder(words); // 函数调用 14 printf("%s\n", words); 15 16 printf("对编码后的英文文本解码: "); 17 decoder(words); // 函数调用 18 printf("%s\n", words); 19 printf("\n"); 20 } 21 22 system("pause"); 23 return 0; 24 } 25 26 /*函数定义 27 功能:对s指向的字符串进行编码处理 28 编码规则: 29 对于a~z或A~Z之间的字母字符,用其后的字符替换; 其中,z用a替换,Z用A替换 30 其它非字母字符,保持不变 31 */ 32 void encoder(char *str) { 33 while(*str){ 34 if((*str >= 'a' && *str < 'z') || (*str >= 'A' && *str < 'Z')) 35 *str += 1; 36 else if(*str == 'z') 37 *str = 'a'; 38 else if(*str == 'Z') 39 *str = 'A'; 40 str++; 41 }} 42 43 /*函数定义 44 功能:对s指向的字符串进行解码处理 45 解码规则: 46 对于a~z或A~Z之间的字母字符,用其前面的字符替换; 其中,a用z替换,A用Z替换 47 其它非字母字符,保持不变 48 */ 49 void decoder(char *str) { 50 while(*str){ 51 if((*str >= 'a' && *str < 'z') || (*str >= 'A' && *str < 'Z')) 52 *str -= 1; 53 else if(*str == 'a') 54 *str = 'z'; 55 else if(*str == 'A') 56 *str = 'Z'; 57 str++; 58 }}
task7运行截图: