6

我想知道为什么这可以编译:

#include <stdio.h>
int main(int argc, char const* argv[])
{
    char *str[3];
    char x = 'a';
    char *px;
    px = &x;
    str[0] = px;
    return 0;
}

虽然这不能:

#include <stdio.h>
int main(int argc, char const* argv[])
{
    char *str[3];
    str[1] = &'a';
    return 0;
}

decla.c: In function ‘main’:
decla.c:9:14: error: lvalue required as unary ‘&amp;’ operand
4

5 回答 5

9

说得简单一点,只能取变量的地址;像文字一样'a'不是变量。

ISO/IEC 9899:2011 §6.5.3.2 地址和间接运算符

约束

¶1 一元运算符的操作数&应为函数指示符、 一元运算符[]或一元运算符的结果*,或指定不是位域且未使用register存储类说明符声明的对象的左值。

标准中的引用意味着您可以使用:

  • &array[i]
  • &*ptr
  • &function

或变量,或结构或联合类型的成员:

  • &var
  • &ptr->member
  • &obj.member

等等。

于 2013-08-09T21:25:02.473 回答
7

一些回复说您只能获取命名变量的地址,但这并不完全正确:如果您使用的是 C99 或更高版本,您还可以获取复合文字的地址或复合文字的字段。通常这对于调用一个函数很有用,该函数需要一个指向某个结构的 in 指针,您只需要在调用期间创建它。例子:draw(&(struct point){ 5, 10 });

可用于获取标量地址的一些途径[编辑并解释]:

// create a char array containing only 'a', dereference to get 'a', and take its address
char *c = &*(char[]){'a'};  

// same as above, but using an array subscript
char *c = & (char[]){'a'}[0];        

/* create a literal for one unnamed struct containing only the char member "c",
   access .c, and take its address all in the same statement */        
char *c = &(struct{char c;}){'a'}.c;

在包含块的持续时间内,*c 将等于'a'。

然而,使用复合文字获取文字地址的更简洁和更常见的方法是简单地声明一个只有一个元素的数组文字,这将像往常一样在赋值时衰减为指针:

char *c = (char[]){'a'};

这是该工作的相当典型的语法。但事实证明,该语言允许我们做一些更直接和稍微不直观的事情:我们可以声明一个标量类型的复合文字。这将上述所有内容简化为更明显的:

char *c = &(char){'a'};

在你的情况下,

#include <stdio.h>
int main(int argc, char const* argv[])
{
    char *str[3];
    str[1] = &(char){'a'};
    return 0;
}

它比 '&' 更冗长一些,实际上只比分配临时变量少了几个键,但它确实存在。

于 2013-08-10T00:28:46.167 回答
5

问题是 operator 的地址仅适用于names

char character = 'a';
str[1] = &character;

应该可以正常工作。

&'a'不起作用的原因是因为不能保证一个值甚至有一个地址。它可以直接从代码页加载到寄存器中,在这种情况下,它不在可引用内存中,或者至少不在您应该取消引用的内存中。

于 2013-08-09T21:25:55.820 回答
1

第一个片段工作正常,因为您正在获取变量的地址。

在第二个代码片段中:-

str[1] = &'a'; 

这不是正确的方法。'a' 不是变量。运算符的地址运算符对名称起作用。如果你想让它工作,然后改变它: -

 char c = 'a';
 str[1] = &c;
于 2013-08-09T21:26:43.473 回答
1

正如乔纳森所说,您只能获取变量的地址。在幕后,'a' 实际上只是一个短整数('a' 的 ASCII 值)。因此,这与您不能这样做的原因相同:

str[1] = &9;
于 2013-08-09T21:27:04.793 回答