指针增量和解除引用(左值必需错误)

时间:2012-04-14 02:12:14

标签: c pointers lvalue post-increment pre-increment

我试图理解指针递增和解除引用是如何组合在一起的,我这样做是为了试一试:

#include <stdio.h>
int main(int argc, char *argv[])
{
    char *words[] = {"word1","word2"};
    printf("%p\n",words);
    printf("%s\n",*words++);
    printf("%p\n",words);
    return 0;
}

我希望这段代码可以执行以下操作之一:

  1. 首先取消引用然后增加指针(打印word1)
  2. 首先取消引用然后增加值(打印ord1)
  3. 取消引用指针+ 1(打印word2)
  4. 但编译器甚至不会编译它,并给出了这个错误:lvalue required as increment operand我在这里做错了吗?

4 个答案:

答案 0 :(得分:2)

您需要在第二个printf中的指针取消引用周围放置大括号,例如:printf("%s\n",(*words)++);此外,如果您试图在列表中获取第2个,则需要使用前缀增量而不是后缀

答案 1 :(得分:2)

您不能递增数组,但可以递增指针。如果将声明的数组转换为指针,则可以使其工作:

#include <stdio.h>
int main(int argc, char *argv[])
{
    const char *ww[] = {"word1","word2"};
    const char **words = ww;
    printf("%p\n",words);
    printf("%s\n",*words++);
    printf("%p\n",words);
    return 0;
}

答案 2 :(得分:1)

words是数组的名称,因此++对此没有任何意义。但是,您可以使用指向数组元素的指针:

for (char ** p = words; p != words + 2; ++p)
{
    printf("Address: %p, value: '%s'\n", (void*)(p), *p);
}

您可以使用更通用的2

,而不是sizeof(words)/sizeof(*words)

答案 3 :(得分:0)

问题在于这一行:

printf("%s\n",*words++);

它被读作*(words++),即增加一块内存。这没有意义,这有点像尝试:

int a = 1;
(&a)++; // move a so that it points to the next address

在C中是非法的。

问题是由C中的数组和指针之间的区别引起的:(基本上)数组是一块内存(在编译时分配),而指针是指向内存块的指针(不一定分配在编译时间)。使用C时这是一个常见的绊倒,关于它还有其他问题(例如C: differences between char pointer and array)。

(修补程序在其他答案中有描述,但基本上你想使用指向字符串而不是字符串数组的指针。)