将字符串s1中任何与字符串s2匹配的字符都删掉

     源自《The C Programming Language》P38 pr2-4:

     编写函数squeeze(s1, s2),将字符串s1中任何与字符串s2中字符匹配的字符都删除。

     代码:

     

main.c
1 #include <stdio.h>
2
3 #define MAXLINE 100
4
5 char s[MAXLINE] = {'\0'}; //用于存储经过squeeze处理后的字符串
6 char* squeeze(char s1[], char s2[]);
7 int any(char s1[], char s2[]);
8
9 int main()
10 {
11
12 char str[] = "good fuck you see you next time"; //待处理字符串
13 char charset[] = "koei"; //参考字符集:当中存储所有要被抹去的字符
14 //char s[MAXLINE] = {'\0'}; //---(1)
15
16 printf("%d\n", any(str, charset));
17 printf("%s\n", squeeze(str, charset));
18
19 return 0;
20 }
21
22 char* squeeze(char s1[], char s2[])
23 {
24 int i, j, k;
25 //char s[MAXLINE] = {'\0'}; //---(2)
26
27 k = 0;
28 for(i = 0; s1[i] != '\0'; ++i)
29 {
30 j = 0;
31 while(s2[j] != '\0' && s1[i] != s2[j])
32 ++j;
33 if(s2[j] == '\0')
34 s[k++] = s1[i];
35 }
36 s[k] = '\0';
37
38 return s;
39 }
40
41 int any(char s1[], char s2[])
42 {
43 int i, j, minloc;
44
45 minloc = 100;
46 for(i = 0; s2[i] != '\0'; ++i)
47 {
48 for(j = 0; s1[j] != '\0' && s1[j] != s2[i]; ++j)
49 ;
50 if(s1[j] != '\0')
51 if(minloc > j)
52 minloc = j;
53 }
54 if(minloc == 100)
55 return -1;
56
57 return minloc;
58 }
59
60 /***********************************
61 any函数参考代码
62 ***********************************/
63 /*int any(char s1[], char s2[])
64 {
65 int i, j;
66
67 for(i = 0; s1[i] != '\0'; ++i)
68 for(j = 0; s2[j] != '\0'; ++j)
69 if(s1[i] == s2[j])
70 return i;
71 return -1;
72 }*/

     分析:

     1,  关于函数返回值,如果本例中将字符串s定义在函数squeeze中,当执行完return s;后,将会给主函数返回一个char*

          指针,但因为s是squeeze的局部变量,当调用完squeeze后会释放字符串s所占有的空间,故在主函数中打印字符串

          printf("%s/n", squeeze(str, charset));时,只是打印了存放在主函数临时变量中的从squeeze中返回的指针所指向

          的字符串,而这个字符串是个未知字符串,所有会在终端打印出莫名其妙的字符串。

     2,  关于函数返回值的解析:例如函数fun1调用了函数fun2,当fun2返回时,会将返回值暂存在寄存器中(一般是eax),

          当程序返回到fun1中执行时,fun1会将返回值从eax中拷贝到自己的栈空间中(一般以临时变量的形式),故而在fun1

          中可以使用fun2的返回值。

          Q: 返回值是怎么会被保存到寄存器里呢?

          A:你用return x语句,编译器会给你自动插入
               mov eax, x
               ret
               的代码,汇编指令ret在这里只有返回调用地址的作用,返回值x存储在eax中。

     3,  如果将s定义在main函数中,则在squeeze函数中使用s是非法的,未定义的,使用本例中将s定义为全局变量,这样

          不管是对main还是squeeze函数都是可见,已定义的。

posted on 2011-04-29 23:47  将军之盾  阅读(1176)  评论(0编辑  收藏  举报