透过下面的程序可以加深对于指针的理解。
指针和数组
字符串长度函数 i_strlen
由于 strlen 在C标准函数库中已经存在,为了便于区分,函数名使用了前缀 i_
#include
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;
}
#include
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;
}
用指针也可以做同样的事情!
int i_strlen(char *s)
{
int n;
for (n = 0; *s != '\0'; n++)
s++;
return n;
}
int i_strlen(char *s)
{
int n;
for (n = 0; *s != '\0'; n++)
s++;
return n;
}
或者
int i_strlen(char *s)
{
int n = 0;
while (*s!= '\0') {
n++;
s++;
}
return n;
}
int i_strlen(char *s)
{
int n = 0;
while (*s!= '\0') {
n++;
s++;
}
return n;
}
指针也可以进行简单的算术运算,比如减法操作
int i_strlen(char *s)
{
char *p = s;
while (*p != '\0')
p++;
return p - s; /* 利用了字符类型占用空间为1个字节的特点 */
}
int i_strlen(char *s)
{
char *p = s;
while (*p != '\0')
p++;
return p - s; /* 利用了字符类型占用空间为1个字节的特点 */
}
想不想看看 p 和 s 的真面目?
#include
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;
}
#include
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
最简单的数组版本
#include
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;
}
#include
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;
}
精简的数组版本
void i_strcpy(char *s, char *t)
{
int i = 0;
while ( (s[i] = t[i]) != '\0' )
i++;
}
void i_strcpy(char *s, char *t)
{
int i = 0;
while ( (s[i] = t[i]) != '\0' )
i++;
}
指针版本
#include
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;
}
#include
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 可以写出下面的形式
#include
void i_strcpy(char *s, char *t)
{
while(*t!='\0')
*s++=*t++;
*s='\0';
}
#include
void i_strcpy(char *s, char *t)
{
while(*t!='\0')
*s++=*t++;
*s='\0';
}
经验丰富的程序员写的版本 *
void strcpy(char *s, char *t)
{
while ( (*s++ = *t++) != '\0' )
; /* 空语句,不可省略 */
}
void strcpy(char *s, char *t)
{
while ( (*s++ = *t++) != '\0' )
; /* 空语句,不可省略 */
}
更为精炼的版本 *
void strcpy(char *s, char *t)
{
while (*s++ = *t++)
; /* 空语句,不可省略 */
}
void strcpy(char *s, char *t)
{
while (*s++ = *t++)
; /* 空语句,不可省略 */
}
进一步学习可参考 【分类目录】【设计导读】【K&R C语言】第5章 指针与数组