透过下面的程序可以加深对于指针的理解。
指针和数组
字符串长度函数 i_strlen
由于 strlen 在C标准函数库中已经存在,为了便于区分,函数名使用了前缀 i_
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> int i_strlen(char s[]) { int n = 0; while (s[n] != '\0') ++n; return n; } int main() { char s[100]={ "China" }; printf("%d\n", i_strlen(s)); return 0; } |
用指针也可以做同样的事情!
1 2 3 4 5 6 7 | int i_strlen(char *s) { int n; for (n = 0; *s != '\0'; n++) s++; return n; } |
或者
1 2 3 4 5 6 7 8 9 | int i_strlen(char *s) { int n = 0; while (*s!= '\0') { n++; s++; } return n; } |
指针也可以进行简单的算术运算,比如减法操作
1 2 3 4 5 6 7 | int i_strlen(char *s) { char *p = s; while (*p != '\0') p++; return p - s; /* 利用了字符类型占用空间为1个字节的特点 */ } |
想不想看看 p 和 s 的真面目?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h> int i_strlen(char *s) { char *p = s; printf("begin address=%d\n", s); while (*p != '\0') p++; printf(" end address=%d\n", p); return p - s; } int main() { char s[100]={ "China" }; printf("%d\n", i_strlen(s)); return 0; } |
在这个函数中,还不太能看出指针的简洁之美。 下面来个更有代表性的字符串复制函数 strcpy
最简单的数组版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h> void i_strcpy(char *s, char *t) { int i = 0; for (i=0; t[i]!='\0'; i++) s[i]=t[i]; s[i]='\0'; /* 非常重要,设定字符串的终结符 */ } int main() { char s[100]= {"China" }; char t[100]= {"Beijing" }; i_strcpy(s, t); printf("%s\n", s); return 0; } |
精简的数组版本
1 2 3 4 5 6 | void i_strcpy(char *s, char *t) { int i = 0; while ( (s[i] = t[i]) != '\0' ) i++; } |
指针版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h> void i_strcpy(char *s, char *t) { while(*t!='\0') { *s=*t; s++; t++; } *s='\0'; } int main() { char s[100]= {"China" }; char t[100]= {"Beijing" }; i_strcpy(s, t); printf("%s\n", s); return 0; } |
根据“前缀往前移、后缀往后移”的原则,i_strcpy 可以写出下面的形式
1 2 3 4 5 6 7 | #include <stdio.h> void i_strcpy(char *s, char *t) { while(*t!='\0') *s++=*t++; *s='\0'; } |
经验丰富的程序员写的版本 *
1 2 3 4 5 | void strcpy(char *s, char *t) { while ( (*s++ = *t++) != '\0' ) ; /* 空语句,不可省略 */ } |
更为精炼的版本 *
1 2 3 4 5 | void strcpy(char *s, char *t) { while (*s++ = *t++) ; /* 空语句,不可省略 */ } |
进一步学习可参考 【分类目录】【设计导读】【K&R C语言】第5章 指针与数组