指针增量和解除引用(左值必需错误)
我试图理解指针递增和解除引用是如何组合在一起的,我这样做是为了试一试:
#include int main(int argc, char *argv[]) { char *words[] = {"word1","word2"}; printf("%p\n",words); printf("%s\n",*words++); printf("%p\n",words); return 0; }
我希望这段代码可以执行以下操作之一:
- 首先取消引用然后增加指针(打印word1)
- 首先取消引用然后增加值(打印ord1)
- 取消引用指针+ 1(打印word2)
但编译器甚至不会编译它,并给出了这个错误: lvalue required as increment operand
我在这里做错了吗?
您不能递增数组,但可以递增指针。 如果将声明的数组转换为指针,则可以使其工作:
#include 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; }
你需要在第二个printf中的指针取消引用周围放置大括号,例如: printf("%s\n",(*words)++);
此外,如果您尝试在列表中获取数字2,则需要使用前缀增量而不是后缀。
words
是数组的名称,因此++
对它没有任何意义。 但是,您可以使用指向数组元素的指针:
for (char ** p = words; p != words + 2; ++p) { printf("Address: %p, value: '%s'\n", (void*)(p), *p); }
你可以使用更通用的sizeof(words)/sizeof(*words)
代替2
。
问题出在这一行:
printf("%s\n",*words++);
它被读作*(words++)
,即增加一块内存。 这没有意义,这有点像尝试:
int a = 1; (&a)++; // move a so that it points to the next address
这在C中是非法的
问题是由C中的数组和指针之间的区别引起的:(基本上)数组是一个内存块(在编译时分配),而指针是指向内存块的指针(不一定在编译时分配) 。 使用C时这是一个常见的绊倒,关于它还有其他问题(例如C:char指针和数组之间的差异 )。
(修复在其他答案中描述,但基本上你想使用指向字符串而不是字符串数组的指针。)