实验五
task 1_1
源代码:
1 #include<stdio.h> 2 #define N 5 3 4 void input(int x[],int n); 5 void output(int x[],int n); 6 void find_min_max(int x[],int n,int *pmin,int *pmax); 7 8 int main(){ 9 int a[N]; 10 int min,max; 11 12 printf("录入%d个数据:\n",N); 13 input(a,N); 14 15 printf("数据是:\n"); 16 output(a,N); 17 18 printf("数据处理...\n"); 19 find_min_max(a,N,&min,&max); 20 21 printf("输出结果:\n"); 22 printf("min = %d,max = %d\n",min,max); 23 24 return 0; 25 } 26 27 void input(int x[],int n){ 28 int i; 29 30 for(i=0;i < n;++i) 31 scanf("%d",&x[i]); 32 } 33 34 void output(int x[],int n){ 35 int i; 36 37 for(i=0;i < n;++i) 38 printf("%d",x[i]); 39 printf("\n"); 40 } 41 42 void find_min_max(int x[],int n,int *pmin,int *pmax){ 43 int i; 44 45 *pmin = *pmax = x[0]; 46 47 for(i=0;i < n;++i) 48 if(x[i] < *pmin) 49 *pmin = x[i]; 50 else if(x[i] > *pmax) 51 *pmax = x[i]; 52 }
运行结果:

问题回答:
1.函数find_min_max是查找数组中的最大值与最小值;
2.pmin指向的是主函数中变量min的地址;pmax指向的是主函数中max的地址。
指针分析:①在line19,&获取变量min、max本身在内存中的地址,同时&min、&max也是实际参数;
②在line42,int *pmin、int *pmax是形式参数;
③在line45,完成指针变量pmin和pmax的初始化。
task 1_2
源代码:
1 #include<stdio.h> 2 #define N 5 3 4 void input(int x[],int n); 5 void output(int x[],int n); 6 void *find_max(int x[],int n); 7 8 int main(){ 9 int a[N]; 10 int *pmax; 11 12 printf("录入%d个数据:\n",N); 13 input(a,N); 14 15 printf("数据是:\n"); 16 output(a,N); 17 18 printf("数据处理...\n"); 19 pmax = find_max(a,N); 20 21 printf("输出结果:\n"); 22 printf("max = %d\n",*pmax); 23 24 return 0; 25 } 26 27 void input(int x[],int n){ 28 int i; 29 30 for(i=0;i < n;++i) 31 scanf("%d",&x[i]); 32 } 33 34 void output(int x[],int n){ 35 int i; 36 37 for(i=0;i < n;++i) 38 printf("%d",x[i]); 39 printf("\n"); 40 } 41 42 void *find_max(int x[],int n){ 43 int max_index = 0; 44 int i; 45 46 for(i=0;i < n;++i) 47 if(x[i] > x[max_index]) 48 max_index = i; 49 50 return &x[max_index]; 51 }
运行结果:
问题回答:
1.函数find_max是在数组中查找最大值;返回的是最大值的地址;
2.可以。
三种指针对比:①输出参数指针:数据流双向,传入地址,修改外部变量;结果储存在外部变量;返回的数量可以多个。
②返回指针(索引法):数据流单向,返回地址;指向原始数组元素;返回数量只能一个。
③返回指针(指针跟踪法):数据流单向,返回地址;指向原始数组元素;返回数量只能一个。
task 2_1
源代码:
1 #include<stdio.h> 2 #include<string.h> 3 #define N 80 4 5 int main(){ 6 char s1[N] = "Learning makes me happy"; 7 char s2[N] = "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("sizeof(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 }
运行结果:
问题回答:
1.s1的大小为80个字节;
sizeof(s1)计算的是数组s1在内存中占用的总字节数(sizeof是编译时运算符,计算的是整个数组的大小,与数组当前储存的内容无关);
strlen(s1)统计的是字符串的有效长度即字符数(从字符串开头到第一个空字符\0(不包括\0)为止的字符数)。
2.不能,因为不能直接将字符串常量的地址赋给数组名s1;
3.交换。
task 2_2
源代码:
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; 9 10 printf("sizeof(s1) vs. strlen(s1):\n"); 11 printf("sizeof(s1) = %d\n",sizeof(s1)); 12 printf("sizeof(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 tmp = s1; 20 s1 = s2; 21 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 }
运行结果:

问题回答:
1.s1中存放的是字符串常量“Learing makes me happy”在内存中的首地址;
sizeof(s1)计算的指针变量s1本身占用的内存字节数;
strlen(s1)统计的是指针s1所指向的字符串长度;
2.可以替换;
此代码中s1是一个指针变量,可以存储地址值,第一行声明指针变量,第二行给指针变量赋值一个地址;
上一个代码s1是字符数组名,在编译时被当作指针变量,s1被分配了N个连续内存,字符串的内容被复制到数组内存中;
3.交换的是指针变量的值;字符串常量在内存中没有交换,它们的位置没有改变。
task 3
源代码:
1 #include<stdio.h> 2 3 int main(){ 4 int x[2][4] = {{1,9,8,4},{2,0,4,9}}; 5 int i,j; 6 int *ptr1; 7 int(*ptr2)[4]; 8 9 printf("输入1:使用数组名、下标直接访问二维数组元素\n"); 10 for(i = 0;i < 2; ++i){ 11 for(j = 0;j < 4; ++j) 12 printf("%d",x[i][j]); 13 printf("\n"); 14 } 15 16 printf("\n输出2:使用指针变量ptr1(指向元素)间接访问\n"); 17 for(ptr1 = &x[0][0], i = 0;ptr1 < &x[0][0] + 8;++ptr1, ++i){ 18 printf("%d", *ptr1); 19 20 if((i + 1) % 4 == 0) 21 printf("\n"); 22 } 23 24 printf("\n输入3:使用指针变量ptr2(指向一维数组)间接访问\n"); 25 for(ptr2 = x;ptr2 < x+2;++ptr2){ 26 for(j = 0;j < 4;++j) 27 printf("%d",*(*ptr2+j)); 28 printf("\n"); 29 } 30 31 return 0; 32 }
运行结果:

task 4
源代码:
1 #include<stdio.h> 2 #define N 80 3 4 void replace(char *str,char old_car,char new_car); 5 6 int main(){ 7 char text[N] = "Programing is diffcult or not,it is a question."; 8 9 printf("原始文本:\n"); 10 printf("%s\n",text); 11 12 replace(text,'i','*'); 13 14 printf("处理后文本:\n"); 15 printf("%s\n",text); 16 17 return 0; 18 } 19 20 void replace(char *str,char old_car,char new_car){ 21 int i; 22 23 while(*str){ 24 if(*str == old_car) 25 *str = new_car; 26 str++; 27 } 28 }
运行结果:

问题回答:
1.函数replace的功能是遍历给定的字符串,将其中的所有指定字符old_char替换为另一个字符new_char,如在此程序中就是将' i '全部换成' * ';
2.可以。
task 5
源代码:
1 #include<stdio.h> 2 #define N 80 3 4 char *str_trunc(char *str, char x); 5 6 int main(){ 7 char str[N]; 8 char ch; 9 10 while(printf("输入字符串:"),gets(str) != NULL){ 11 printf("输入一个字符:"); 12 ch = getchar(); 13 14 printf("截断处理...\n"); 15 str_trunc(str,ch); 16 17 printf("截断处理后的字符串:%s\n\n",str); 18 getchar(); 19 } 20 21 return 0; 22 } 23 24 char *str_trunc(char *str,char x){ 25 while(*str){ 26 if(*str == x){ 27 *str = '\0'; 28 return str; 29 } 30 str++; 31 } 32 return str; 33 }
运行结果:
回答问题:

getchar()是为了读取换行符;
task 6
源代码:
1 #include<stdio.h> 2 #include<string.h> 3 #define N 5 4 5 int check_id(char *str); 6 7 int main(){ 8 char *pid[N] = {"31010120000721626x", 9 "3301061996x0203301", 10 "53010220051126571", 11 "510104199211197977", 12 "53010220051126133Y"}; 13 int i; 14 15 for(i = 0; i < N;++i) 16 if(check_id(pid[i])) 17 printf("%s\tTure\n",pid[i]); 18 else 19 printf("%s\tFalse\n",pid[i]); 20 21 return 0; 22 } 23 24 int check_id(char *str){ 25 //检查是否为18位 26 if(strlen(str)!= 18) 27 return 0; 28 29 //检查前17位是否均为数字 30 int i; 31 for(i = 0;i < 17;++i){ 32 if(str[i] < '0' || str[i] > '9') 33 return 0; 34 } 35 36 //检查最后一位是不是数字或0 37 if(str[17] < '0' || str[17] > '9' && str[17]!='x') 38 return 0; 39 40 return 1; 41 } 42
运行结果:

task 7
源代码:
1 #include<stdio.h> 2 #define N 80 3 void encoder(char *str,int n); 4 void decoder(char *str,int n); 5 6 int main(){ 7 char words[N]; 8 int n; 9 10 printf("输入英文文本:"); 11 gets(words); 12 13 printf("输入n:"); 14 scanf("%d",&n); 15 16 printf("编码后的英文文本:"); 17 encoder(words,n); 18 printf("%s\n",words); 19 20 printf("对编码后的英文文本解码:"); 21 decoder(words,n); 22 printf("%s\n",words); 23 24 return 0; 25 } 26 27 void encoder(char *str,int n){ 28 char *p = str; 29 while(*p != '\0'){ 30 if(*p >= 'a' && *p <= 'z') 31 *p = 'a' + (*p -'a' + n)% 26; 32 else if(*p >= 'A' && *p <= 'Z') 33 *p = 'A' + (*p - 'A' + n)% 26; 34 p++; 35 } 36 } 37 38 void decoder(char *str,int n){ 39 char *p = str; 40 while(*p != '\0'){ 41 if(*p >= 'a' && *p <= 'z') 42 *p = 'a' + (*p - 'a' - n + 26)% 26; 43 else if(*p >= 'A' && *p <= 'Z') 44 *p = 'A' + (*p - 'A' - n + 26)% 26; 45 p++; 46 } 47 }
运行结果:



task 8
1 #include<stdio.h> 2 #include<string.h> 3 4 void sort(int n,char *s[]); 5 6 int main(int argc,char *argv[]){ 7 int i; 8 9 sort(argc-1,argv+1); 10 11 for(i = 1;i < argc;++i) 12 printf("hello,%s\n",argv[i]); 13 14 return 0; 15 } 16 17 void sort(int n, char *s[]){ 18 int i,j; 19 char *tmp; 20 21 for(i = 0;i < n-1;++i) 22 for(j = 0;j < n-i-1;++j) 23 if(strcmp(s[j],s[j+1])>0){ 24 tmp = s[j]; 25 s[j] = s[j+1]; 26 s[j+1] = tmp; 27 } 28 }
运行结果:

总结:
1.本次实验,让我对指针有了更进一步的了解,但是对指针的用法还需进一步掌握,在读代码时,有时仍然需要借助AI来帮我解释。
2.task 5我根据task4编写,答案正确。但给AI时它说这是一段错误代码,使用str遍历,找到截断位置并替换为'\0'时,str指向的地址就不是字符串的起始地址了,它给我的修改建议是创建一个新指针遍历。因为测试数据正确,所以我并没有百分百理解。我现在对这两种用法的区别仍然有些疑惑,后续我会让AI帮助我编写两段代码,来让我更加直观的看到两种用法的区别。
浙公网安备 33010602011771号