- 指针移动(加减)的实质?
- 指针移动的应用?
指针的应用
1.在函数中应用指针对传入实参变量进行修改(跟引用的效果一样)
例子:
实现一个方法“多个返回值”的效果:返回一个三位数数字的个位、十位、百位。这里,我们借助指针来”返回“分解后的结果。这种应用也是最常见的指针应用。
// fun1:分解一个三位数,传递个位、十位和百位数字
bool parseNumber(int num,int* g,int* s,int* b)
{
if(num < 100 || num > 999)
{
// 只允许100~999的数字
return false;
}
*g = num % 10; // 直接修改指针指向的变量值
*s = (num / 10)%10;
*b = (num/100)%10;
return true;
}
//等同于
bool parseNumber(int num,int& g,int& s,int& b)
{
if(num < 100 || num > 999)
{
// 只允许100~999的数字
return false;
}
*g = num % 10; // 直接修改指针指向的变量值
*s = (num / 10)%10;
*b = (num/100)%10;
return true;
}
int main(int argc, char *argv[])
{
int num = 365;
int g,s,b;
if(parseNumber(num,&g,&s,&b)) //调用利用指针编写的函数
{
printf("%d %d %d\n",b,s,g);
}
if(parseNumber(num,g,s,b)) //调用利用引用编写的函数
{
printf("%d %d %d\n",b,s,g);
}
return 0;
}
2.利用指针的移动来辅助计算长度,实现strlen()函数
strlen是计算字符串的长度,其内部是通过判断是否以'\0'作为结束符
// fun2:自己模拟实现strlen函数
int myStrlen(char* str)
{
int len = 0;
while(*str != '\0')
{
str++;//此时指针指向char类型,每次移动一个字节长度
len++;
}
return len;
}
int main(int argc, char *argv[])
{
char test[] = "hello";
int len = myStrlen(test);
printf("The length of 'hello' is %d\n",len);
return 0;
}
str++;//此时指针指向char类型,每次移动一个字节长度
3.利用指针的各种技巧判断字符串A是否以字符串B结尾(经典)
判断一个字符串是否以另一个子子字符串结尾,这个方法在Java中属于String类,叫做endsWith。在C#中,也位于String类,叫做EndsWith,并提供了三个重载。这里,我们借助指针来辅助实现这个经典的endsWith方法。
思路:
- 要从两个字符串的结尾开始比较(要确保B字符串比A字符串短才能顺利比较)
- 利用指针怎么实现比较
// fun3:判断字符串A是否以字符串B结尾
bool endsWith(char* str,char* substr)
{
int strlen = 0;
while(*str != '\0')
{
str++;
strlen++;
}
int sublen = 0;
while(*substr != '\0')
{
substr++;
sublen++;
}
if(strlen < sublen)
{
// 如果子串长度比主串还长
return false;
}
int i;
for(i=0;i<=sublen;i++)
{
//有了前面的指针移动到末尾了,从末尾开始对比每一个字符,又一次用到了从后往前操作
char strCh = *str;
char subCh = *substr;
if(strCh != subCh)
{
return false;
}
else
{
str--;
substr--;
}
}
return true;
}
int main(int argc, char *argv[])
{
char str[] = "edisonchou";
char sub[] = "chou";
printf("%d\n", endsWith(str,sub));
char sub2[] = "zhou";
printf("%d\n", endsWith(str,sub2));
return 0;
}
指针移动的误解
指针的移动 跟指针指向的类型有关!
typedef int Rank
void Vector<T>::unsort(Rank lo,Rank hi)
{
//_elem首地址右移(int)lo个位置,到_elem[lo,hi),目的是让V[0,hi-lo)==_elem[lo,hi)较难理解
T* V = _elem + lo
for (int i = _size; i > 0; i--)
{
swap(V[i - 1], V[rand() % i]);
}
}
_elem首地址右移(int)lo个位置,到_elem[lo,hi),目的是让V[0,hi-lo)==_elem[lo,hi)较难理解
note:指针的数值(即被指对象的物理地址)的大小无多大意义,要找到所指向对象的大小。