【发布时间】:2018-12-18 09:42:09
【问题描述】:
编辑: 我意识到我的 OP 中的代码很长且难以阅读。我用 4 行代码突出显示了问题。
char **t = {"Hello", "World"};
char **a = t;
++(a[0]);
printf("%c\n",**t);
我想在不丢失指向第一个字符的指针的情况下递增字符串数组。因此,我初始化了一个新指针“a”以指向第一个字符。但是,在我增加'a'指针之后,它似乎改变了't'指向的内容!在 printf 语句中,我希望 t 的指针值保持不变,但它似乎以 'a' 递增,现在指向第二个字符。为什么会这样?
已解决: 在上面的示例中,a 和 t 似乎是同一个指针,因此如果我更改一个(例如通过递增),更改也会反映在 pther 中。但是,如果我将 t 取消引用到另一个变量,那么我可以更改所述变量,而不会将该更改反映在 t 中。在上面的例子中,这看起来像
char *a = t[0];
++a;
printf("a value: %c\n", *a);
printf("t value: %c\n", **t);
我认为我最初对取消引用感到困惑,因为 t 指向一个指针。我得到的每个响应都是使用数组索引而不是指针,我明白为什么。
原帖: 说我有:
array1 {"arp", "live", "strong"}, and
array2 {"lively", "alive", "harp", "sharp", "armstrong"}
我正在尝试查找array1 中的字符串,它们是array2 中任何字符串的子字符串。
为此,我编写了一个辅助函数 (compString),它接收来自 array1 的字符串、整个 array2 以及 array2 的长度。
本质上,函数所做的是为字符串指针和数组指针创建本地指针值。然后它从array2 中提取第一个字符串并开始遍历它以找到输入字符串的第一个字母的匹配项。如果没有找到匹配,该函数将移动到下一个字符串,直到找到一个完整的匹配或直到它遍历整个array2。然后它返回到它的调用环境。
我遇到了一些意想不到的行为。当我调用该函数时(使用相同的参数),在已经调用它之后,数组指针似乎准确地指向它在上一次调用中停止的位置。
例如,如果我调用 compString("arp", array2, 5),那么该函数将标记从 harp 中的 a 开始的匹配。
然后,如果我调用compString("live", array2, 5),该函数将从harp 中的a 开始,并在不标记匹配的情况下到达数组的末尾。
最后,当我调用compString("strong", array2, 5) 时,array2 现在指向垃圾,因为它已经被迭代,并且没有标记匹配。
由于辅助函数所做的第一件事就是“本地化”传递的指针(即创建一个局部指针变量并将传递给函数的指针的值分配给它,然后迭代该局部变量),我会假设对该函数的后续调用不会“保存”指针的先前值。有什么指点吗?
附上来源:
#include <stdio.h>
#include <string.h>
int compString(char *, char **, int);
int main(void)
{
int sz1 = 3;
int sz2 = 5;
char *p, *p2;
char *array1[] = {"arp\0", "live\0", "strong\0"};
char *array2[] = {"lively\0", "alive\0", "harp\0", "sharp\0", "armstrong\0"};
compString("arp\0",array2,5);
compString("live\0",array2,5);
compString("strong\0",array2,5);
}
int compString(char *arr1, char **arr2, int sz2)
{
printf("\n\n\n");
printf("WORD: %s\n",arr1);
int i = 0;
char *a1 = arr1;
char **a2 = arr2;
char *p;
char *p2;
printf("BEGIN ITERATION %d\n",i);
printf("Checking against word: %s\n",a2[i]);
while (i < sz2)
{
printf("%c\n",*a2[i]);
if (*a1 == *a2[i])
{
char *p = a1;
char *p2 = a2[i];
while ((*p == *p2) && (*p != '\0'))
{
++p;
++p2;
}
if (*p == '\0')
{
return 1;
}
else
{
*++(a2[i]);
if (*(a2[i]) == '\0')
{
++i;
printf("BEGIN ITERATION %d\n",i);
printf("Checking against word: %s\n",a2[i]);
}
}
}
else
{
*++(a2[i]);
if (*(a2[i]) == '\0')
{
++i;
printf("BEGIN ITERATION %d\n",i);
printf("Checking against word: %s\n",a2[i]);
}
}
}
return 0;
}
【问题讨论】:
-
如果到目前为止您还没有尝试过,这可能是熟悉调试器的好时机。旁注:
"something"的末尾已经有一个\0(否则printf-s 也需要它,但它们不需要) -
不确定你想用
*++(a2[i]);做什么,但它看起来不正确,取消引用它什么也没做。 -
我对 *++(a2[i]) 的想法是 a2[i] 返回一个指向字符串的指针,++a2[i] 递增指针以指向所述的下一个字符字符串,并且 *++(a2[i]) 产生该字符的值。
-
这完全正确,但是您不会将该 char 的值存储在任何地方,因此取消引用是没有意义的,并且增加指针意味着您正在更改
arr2的内容,因此您的单词列表're check against 将随着时间的推移变得无用 -
@byrnesj1 在此处查看答案:Pointer expressions: *ptr++, *++ptr and ++*ptr。它应该很快澄清为什么它会降低你的文字数组。需要明确的是,因为您传递了
char **类型,所以您对数组具有读取权限,但仍然可以修改其元素。除非练习是使用指针运算,否则最好采用二维数组表示法。
标签: c arrays pointers scope iteration