user-0 提问: 二位数组a[2][3]，为什么&(*(a+1)+0)无法编译成功？

回复:
user: user-1
content: 理解和讨论之前请先学会如何观察！  http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组  //char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

user: user-2
content: 引用 11 楼 lizh1009的回复:[quote=引用 9 楼 paschen 的回复:] a+b本身是右值，不管b是多少（包括是0），再取&相当于是对一个中间临时变量取地址 不好意思，10楼的回复说错了。 1.(*(a+1)+0)的值是一个内存中存在的地址，请问能详细解释下为何(*(a+1)+0)是右值而*(a+1)是左值吗？还是不太理解。还是说只需要死记硬背*运算符得到的结果就是左值？ 2.c语言是不是规定&运算符的对象必须是左值？这个知识点书上没说，我用man命令也找不到，请问linux系统能不能像查询函数那样用man手册查询到一些运算符的说明？ 谢谢。 [/quote] http://zh.cppreference.com/w/c/language/operator_member_access http://zh.cppreference.com/w/c/language/value_category

user: user-0
content: 引用 9 楼 paschen 的回复:a+b本身是右值，不管b是多少（包括是0），再取&相当于是对一个中间临时变量取地址 不好意思，10楼的回复说错了。 1.(*(a+1)+0)的值是一个内存中存在的地址，请问能详细解释下为何(*(a+1)+0)是右值而*(a+1)是左值吗？还是不太理解。还是说只需要死记硬背*运算符得到的结果就是左值？ 2.c语言是不是规定&运算符的对象必须是左值？这个知识点书上没说，我用man命令也找不到，请问linux系统能不能像查询函数那样用man手册查询到一些运算符的说明？ 谢谢。

user: user-0
content: 引用 9 楼 paschen 的回复:a+b本身是右值，不管b是多少（包括是0），再取&相当于是对一个中间临时变量取地址 1.(*(a+1)+0)的值是一个内存中存在的地址，请问能详细解释下为何(*(a+1)+0)是左值而*(a+1)是右值吗？还是不太理解。还是说只需要死记硬背*运算符得到的结果就是左值？ 2.c语言是不是规定&运算符的对象必须是左值？这个知识点书上没说，我用man命令也找不到，请问linux系统能不能像查询函数那样用man手册查询到一些运算符的说明？ 谢谢。

user: user-2
content: a+b本身是右值，不管b是多少（包括是0），再取&相当于是对一个中间临时变量取地址

user: user-2
content: 解引用表达式*p得到的是左值，&(*p)一定是正确的，因为*p得到的是p指向的实体

user: user-0
content: 引用 5 楼 paschen 的回复:[quote=引用 4 楼 lizh1009的回复:][quote=引用 2 楼 paschen 的回复:] 别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？[/quote] 别把&和*搞混了，前者才是取址，后者是解引[/quote] 还是不太明白，(*(a + 1) + 0)是右值，*(a+1)为什么不是右值？

user: user-2
content: 引用 4 楼 lizh1009的回复:[quote=引用 2 楼 paschen 的回复:] 别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？[/quote] 不好意思，理解错你意思了，*(a+1)是左值，不是右值

user: user-2
content: 引用 4 楼 lizh1009的回复:[quote=引用 2 楼 paschen 的回复:] 别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？[/quote] 别把&和*搞混了，前者才是取址，后者是解引

user: user-0
content: 引用 2 楼 paschen 的回复:别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的 但是*(a+1)也是右值啊，为什么能对*(a+1)取址？

user: user-2
content: 引用 1 楼 user-3的回复:#include<stdio.h> int main() {     int a[2][3];     printf("%p\n",(*(a+1)+0));     printf("%p\n",(*(a+1))); //  printf("a=%p\n",a); //  printf("&a+1=%p\n",&a+1); //  printf("a=%p\n",a+1); //  printf("&(a[1]=%p\n",&a[1]);      return 0; }  %p可以认为是默认带了& 所以 不用加& %p输出的是指针指向的地址，并不是指针变量自身的地址，加&得到的是自身的地址，不可混为一谈

user: user-2
content: 别想太多(*(a + 1) + 0)代表什么，可以肯定的是它是一个右值（或者理解成临时变量），不能对一个右值取地址，所以是错的

user: user-3
content: #include<stdio.h> int main() {     int a[2][3];     printf("%p\n",(*(a+1)+0));     printf("%p\n",(*(a+1))); //  printf("a=%p\n",a); //  printf("&a+1=%p\n",&a+1); //  printf("a=%p\n",a+1); //  printf("&(a[1]=%p\n",&a[1]);      return 0; }  %p可以认为是默认带了& 所以 不用加&