多日没法博客,最近没什么进展,刚毕业事情多,重新温习了下C的基础,看到一个指针操作破坏数组的例子,百思不解,通过跟踪调试,终于有了自己的理解,原来是被指针的外衣所迷惑了,基础还是不行啊,还得多看,闲话不说,上例子。
版本一:
int findchar(char **strings, char value)
{
char *string;
while ((string = *strings++) != NULL) 标记1
{
while (*string != '/0')
{
if (*string++ == value)
return TRUE;
}
}
return FALSE;
}
版本二:
int findchar(char **strings, char value)
{
assert(strings != NULL);
while (*strings != NULL)
{
while (**strings != '/0')
{
if (*(*strings)++ == value) //红色部分的操作破坏了原本的数组 标记2
{
return TRUE;
}
}
strings++;
}
return FALSE;
}
以上两个函数的版本都是在数组中寻找对应的字符现在做下简单的分析:
拆分一下标记1和标记2的分别做的工作:
标记1:strings是一个指向指针的指针该指针存放的是一个指针
操作先拷贝一份strings的指针将它赋值给我们定义的指针变量string,然后将指针+1,使得strings指向下个指针,假设这个指针存放的内容是指向”hello”字符串首地址的指针。然后对这个地址的操作就留给我们定义的局部指针变量string来操作,原数组仍然保存指向这个字符串首地址的指针。
标记二:先对求得当前指针所保存的字符串的指针,然后将地址进行了+1操作使它指向下个一个字符地址比如”hello”,则操作完成后地址变成指向”ello”,然后依次循环到末尾,然后通过strings++,指向下一个指针,此时,前一个指针的值已经被修改。因此第二个版本做完依次操作后就无法再次进行查找,因为指针数组中保存的指针已经被修改了。而第一个版本中,在做比较操作时,将指针数组中保存的指针值,放到另外一个指针变量中去做操作,因此没有被破坏。
其实整个操作过程类似于简单的变量操作的区别,为了直观的表示它们的区别我做个简化解释:
版本一:
int p = 1;
int b = p;
++b;
此时b的值被改变了,而P仍然保存原先的值没被修改,版本一正是这么做的,只是我们这边是整型变量,而他操作的是指针变量而已。
版本二:
int p = 1;
++p;
直接将P保存的值进行自增操作,改变了P本身的值,版本二中,就是直接对所保存的字符串指针值,进行了自增,导致运行后本身数组的值被修改,范例用的是整型变量,而函数中操作得值其实是指针,换汤不换药而已,无法理解其实是被指针的外衣所迷惑了。