实验6 指针
四、实验结论
1. 实验任务1
task1_1
1 #include <stdio.h> 2 #define N 4 3 4 int main() 5 { 6 int x[N] = {1, 9, 8, 4}; 7 int i; 8 int *p; 9 10 // 方式1:通过数组名和下标遍历输出数组元素 11 for(i=0; i<N; ++i) 12 printf("%d", x[i]); 13 printf("\n"); 14 15 // 方式2:通过指针变量遍历输出数组元素 (写法1) 16 for(p=x; p<x+N; ++p) 17 printf("%d", *p); 18 printf("\n"); 19 20 // 方式2:通过指针变量遍历输出数组元素(写法2) 21 p = x; 22 for(i=0; i<N; ++i) 23 printf("%d", *(p+i)); 24 printf("\n"); 25 26 // 方式2:通过指针变量遍历输出数组元素(写法3) 27 p = x; 28 for(i=0; i<N; ++i) 29 printf("%d", p[i]); 30 printf("\n"); 31 32 return 0; 33 }

task1_2
1 #include <stdio.h> 2 #define N 4 3 4 int main() 5 { 6 char x[N] = {'1', '9', '8', '4'}; 7 int i; 8 char *p; 9 10 // 方式1:通过数组名和下标遍历输出数组元素 11 for(i=0; i<N; ++i) 12 printf("%c", x[i]); 13 printf("\n"); 14 15 // 方式2:通过指针变量遍历输出数组元素 (写法1) 16 for(p=x; p<x+N; ++p) 17 printf("%c", *p); 18 printf("\n"); 19 20 // 方式2:通过指针变量遍历输出数组元素(写法2) 21 p = x; 22 for(i=0; i<N; ++i) 23 printf("%c", *(p+i)); 24 printf("\n"); 25 26 // 方式2:通过指针变量遍历输出数组元素(写法3) 27 p = x; 28 for(i=0; i<N; ++i) 29 printf("%c", p[i]); 30 printf("\n"); 31 32 return 0; 33 }

回答问题
1.程序task1_1.c中,假设指针变量p初始值是地址2000,则执行++p后,指针变量p中存放的地址值是2004。
2.程序task1_2.c中,假设指针变量p初始值是地址2000,则执行++p后,指针变量p中存放的地址值是2001
3.都是对指针变量做++p操作,因为task1_1中指针变量指向的是整型数组(int占四个字节),而task1_2中指针变量指向的是字符数组(char占一个字节),所以结果不同。
2. 实验任务2
task2_1
1 #include <stdio.h> 2 3 int main() 4 { 5 int x[2][4] = { {1,9,8,4}, {2,0,2,2}} ; 6 int i, j; 7 int *p; // 指针变量,存放int类型数据的地址 8 int (*q)[4]; // 指针变量,指向包含4个int型元素的一维数组 9 10 // 使用数组名、下标访问二维数组元素 11 for(i=0; i<2; ++i) 12 { 13 for(j=0; j<4; ++j) 14 printf("%d", x[i][j]); 15 printf("\n"); 16 } 17 18 // 使用指针变量p间接访问二维数组元素 19 for(p = &x[0][0], i = 0; p < &x[0][0] + 8; ++p, ++i) 20 { 21 printf("%d", *p); 22 if( (i+1)%4 == 0) 23 printf("\n"); 24 } 25 26 // 使用指针变量q间接访问二维数组元素 27 for(q=x; q<x+2; ++q) 28 { 29 for(j=0; j<4; ++j) 30 printf("%d", *(*q+j)); 31 printf("\n"); 32 } 33 34 return 0; 35 }

task2_2
1 #include <stdio.h> 2 3 int main() 4 { 5 char x[2][4] = { {'1', '9', '8', '4'}, {'2', '0', '2', '2'} }; 6 int i, j; 7 char *p; // 指针变量,存放char类型数据的地址 8 char (*q)[4]; // 指针变量,指向包含4个char型元素的一维数组 9 10 // 使用数组名、下标访问二维数组元素 11 for(i=0; i<2; ++i) 12 { 13 for(j=0; j<4; ++j) 14 printf("%c", x[i][j]); 15 printf("\n"); 16 } 17 18 // 使用指针变量p间接访问二维数组元素 19 for(p = &x[0][0], i = 0; p < &x[0][0] + 8; ++p, ++i) 20 { 21 printf("%c", *p); 22 if( (i+1)%4 == 0) 23 printf("\n"); 24 } 25 26 // 使用指针变量q间接访问二维数组元素 27 for(q=x; q<x+2; ++q) 28 { 29 for(j=0; j<4; ++j) 30 printf("%c", *(*q+j)); 31 printf("\n"); 32 } 33 34 return 0; 35 }

回答问题
1.程序task2_1.c中:
假设指针变量p初始值是地址2000,则执行++p后,指针变量p中存放的地址值2004。
假设指针变量q初始值是地址2000,则执行++q后,指针变量q中存放的地址值是2004。
2.程序task2_2.c中:
假设指针变量p初始值是地址2000,则执行++p后,指针变量p中存放的地址值是2001。
假设指针变量q初始值是地址2000,则执行++q后,指针变量q中存放的地址值是2001。
3.都是对指针变量做++操作,但是因为指针变量指向的数据类型不同,所以结果有差别。
3. 实验任务3
task3_1
1 #include <stdio.h> 2 #include <string.h> 3 #define N 80 4 5 int main() 6 { 7 char s1[] = "C, I love u."; 8 char s2[] = "C, I hate u."; 9 char tmp[N]; 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 strcpy(tmp, s1); 21 strcpy(s1, s2); 22 strcpy(s2, tmp); 23 24 printf("\nafter swap: \n"); 25 printf("s1: %s\n", s1); 26 printf("s2: %s\n", s2); 27 28 return 0; 29 }

回答问题:
问题1:数组s1的大小是13,sizeof(s1)计算的是字符串在内存中的长度,strlen(s1)统计的是字符串的长度。
问题2:line7代码,不能替换成文件内写法。文件内那种先定义后赋值的写法需要在定义数组时给出数组的长度。
问题3:line20-22执行后,字符数组s1和s2中的内容交换了。
task3_2
1 #include <stdio.h> 2 #include <string.h> 3 #define N 80 4 5 int main() 6 { 7 char *s1 = "C, I love u."; 8 char *s2 = "C, I hate u."; 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 return 0; 29 }

回答问题:
问题1:指针变量s1中存放的是"C, I love u."。sizeof(s1)计算的是字符串在内存中的长度。strlen(s1)统计的是字符串的长度。问题2:line7代码能替换成文件内的写法。
问题3:line20-line22,交换的是指针变量s1和s2的指向。字符串常量"C, I love u."和字符串常量"C, I hate u."在内存存储单元中没有交换。
4. 实验任务4
1 #include <stdio.h> 2 #include <string.h> 3 #define N 5 4 int check_id(char *str); // 函数声明 5 int main() 6 { 7 char *pid[N] = {"31010120000721656X", "330106199609203301", "53010220051126571", "510104199211197977", "53010220051126133Y"}; 8 int i; 9 for(i=0; i<N; ++i) 10 if( check_id(pid[i]) ) // 函数调用 11 printf("%s\tTrue\n", pid[i]); 12 else 13 printf("%s\tFalse\n", pid[i]); 14 15 return 0; 16 17 } 18 19 // 函数定义 20 // 功能: 检查指针str指向的身份证号码串形式上是否合法。 21 // 形式合法,返回1,否则,返回0 22 23 int check_id(char *str) 24 { 25 char *p,*temp; 26 for(p=str;p<str+5;p++) 27 { 28 if(strlen(p) != 18) 29 { 30 return 0; 31 break; 32 } 33 else 34 { 35 temp = p; 36 for(;temp<p+18;temp++) 37 { 38 if(*temp>='0'&&*temp<='9'||*temp == 'X'); 39 else 40 { 41 return 0; 42 break; 43 } 44 } 45 if(temp = p+18) 46 return 1; 47 } 48 } 49 }

5. 实验任务5
1 #include <stdio.h> 2 #include <string.h> 3 #define N 80 4 int is_palindrome(char *s); // 函数声明 5 int main() 6 { 7 char str[N]; 8 int flag; 9 printf("Enter a string:\n"); 10 gets(str); 11 12 flag = is_palindrome(str); // 函数调用 13 14 if (flag) 15 printf("YES\n"); 16 else 17 printf("NO\n"); 18 19 return 0; } 20 21 // 函数定义 22 // 功能:判断s指向的字符串是否是回文串 23 // 如果是,返回1;否则,返回0 24 25 int is_palindrome(char *s) 26 { 27 int i=0,len,j; 28 len = strlen(s); 29 j = len/2; 30 for(;i<j;) 31 { 32 if(*(s+i) == *(s+len-i-1)) 33 i++; 34 else 35 { 36 return 0; 37 break; 38 } 39 if(i=j) 40 return 1; 41 } 42 }


6. 实验任务6
1 #include <stdio.h> 2 #define N 80 3 void encoder(char *s); // 函数声明 4 void decoder(char *s); // 函数声明 5 6 int main() 7 { 8 char words[N]; 9 10 printf("输入英文文本: "); 11 gets(words); 12 13 printf("编码后的英文文本: "); 14 encoder(words); // 函数调用 15 printf("%s\n", words); 16 17 printf("对编码后的英文文本解码: "); 18 decoder(words); // 函数调用 19 printf("%s\n", words); 20 21 return 0; 22 } 23 24 25 /*函数定义 26 功能:对s指向的字符串进行编码处理 27 编码规则: 28 对于a~z或A~Z之间的字母字符,用其后的字符替换; 其中,z用a替换,Z用A替换 29 其它非字母字符,保持不变 30 */ 31 void encoder(char *s) 32 { 33 for(;*s!='\0';s++) 34 { 35 if(*s == 'z'||*s == 'Z') 36 *s = *s - 25; 37 else if(*s >= 'a'&&*s < 'z'||*s >= 'A'&&*s < 'Z') 38 *s = *s + 1; 39 } 40 } 41 42 43 /*函数定义 44 功能:对s指向的字符串进行解码处理 45 解码规则: 46 对于a~z或A~Z之间的字母字符,用其前面的字符替换; 其中,a用z替换,A用Z替换 47 其它非字母字符,保持不变 48 */ 49 void decoder(char *s) 50 { 51 for(;*s!='\0';s++) 52 { 53 if(*s == 'a'||*s == 'A') 54 *s = *s + 25; 55 else if(*s > 'a'&&*s <= 'z'||*s > 'A'&&*s <= 'Z') 56 *s = *s - 1; 57 } 58 }


浙公网安备 33010602011771号