例如,
int main() { int i = 1; int* p, q; p = &i; //q = &i;//q不是指针 int* buf[20];//数组的每个元素都是int* return 0; }
第二行声明里面,*好象是右结合的,也就是p是一个*,指向int,而q是普通的int
第五行声明里面,*好象是左结合的,也就是buf是一个数组,有20个元素,每个元素都是int*
那本人就不清楚了,*号有没有确定的左右结合律呢?
还请指点
解决方案
8
比较好的写法是:int *p, *q;
写成int* p, q;可能让人造成误解
运算符结合性:http://www.cnblogs.com/softwaretesting/archive/2011/08/16/2139068.html
写成int* p, q;可能让人造成误解
运算符结合性:http://www.cnblogs.com/softwaretesting/archive/2011/08/16/2139068.html
4
什么叫左结合,什么叫右结合?不就是个指针吗?
4
一看楼上高手,立马明白啥意思了。
4
这跟结合性没关系,是优先级的问题,由于[]的优先级高于*,所以buf先跟[]结合,生成一个数组,然后再跟*结合,即指针数组,而不是*和左边的int结合在一起了,*一定是右结合的,所以推荐下面的书写格式
int *fun(int *p);//推荐 int* fun(int* p); int *p;//推荐 int* p;
8
int* buf[20] 一个包含20个元素的数组,数组每个元素为int*类型
int (*buf)[20] 一个指向,指向int[20]类型数组
int (*buf)[20] 一个指向,指向int[20]类型数组
4
//C++ Operators // Operators specify an evaluation to be performed on one of the following: // One operand (unary operator) // Two operands (binary operator) // Three operands (ternary operator) // The C++ language includes all C operators and adds several new operators. // Table 1.1 lists the operators available in Microsoft C++. // Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators. Operators associate with either the //expression on their left or the expression on their right; this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). // Table 1.1 shows the precedence and associativity of C++ operators // (from highest to lowest precedence). // //Table 1.1 C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+--+--+--+ //| Operator | Name or Meaning | Associativity | //+--+--+--+ //| :: | Scope resolution | None | //| :: | Global | None | //| [ ] | Array subscript | Left to right | //| ( ) | Function call | Left to right | //| ( ) | Conversion | None | //| . | Member selection (object) | Left to right | //| -> | Member selection (pointer) | Left to right | //| ++ | Postfix increment | None | //| -- | Postfix decrement | None | //| new | Allocate object | None | //| delete | Deallocate object | None | //| delete[ ] | Deallocate object | None | //| ++ | Prefix increment | None | //| -- | Prefix decrement | None | //| * | Dereference | None | //| & | Address-of | None | //| + | Unary plus | None | //| - | Arithmetic negation (unary) | None | //| ! | Logical NOT | None | //| ~ | Bitwise complement | None | //| sizeof | Size of object | None | //| sizeof ( ) | Size of type | None | //| typeid( ) | type name | None | //| (type) | Type cast (conversion) | Right to left | //| const_cast | Type cast (conversion) | None | //| dynamic_cast | Type cast (conversion) | None | //| reinterpret_cast | Type cast (conversion) | None | //| static_cast | Type cast (conversion) | None | //| .* | Apply pointer to class member (objects) | Left to right | //| ->* | Dereference pointer to class member | Left to right | //| * | Multiplication | Left to right | //| / | Division | Left to right | //| % | Remainder (modulus) | Left to right | //| + | Addition | Left to right | //| - | Subtraction | Left to right | //| << | Left shift | Left to right | //| >> | Right shift | Left to right | //| < | Less than | Left to right | //| > | Greater than | Left to right | //| <= | Less than or equal to | Left to right | //| >= | Greater than or equal to | Left to right | //| == | Equality | Left to right | //| != | Inequality | Left to right | //| & | Bitwise AND | Left to right | //| ^ | Bitwise exclusive OR | Left to right | //| | | Bitwise OR | Left to right | //| && | Logical AND | Left to right | //| || | Logical OR | Left to right | //| e1?e2:e3 | Conditional | Right to left | //| = | Assignment | Right to left | //| *= | Multiplication assignment | Right to left | //| /= | Division assignment | Right to left | //| %= | Modulus assignment | Right to left | //| += | Addition assignment | Right to left | //| -= | Subtraction assignment | Right to left | //| <<= | Left-shift assignment | Right to left | //| >>= | Right-shift assignment | Right to left | //| &= | Bitwise AND assignment | Right to left | //| |= | Bitwise inclusive OR assignment | Right to left | //| ^= | Bitwise exclusive OR assignment | Right to left | //| , | Comma | Left to right | //+--+--+--+
6
//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]
10
任何 T D1, D2; 形式的声明,可以认为等同于 T D1; T D2;
注意,*, [] 等符号不属于 T 的部分。
所以, int* p1, p2; 等同与 int* p1; int p2; (T 为 int , D1 为 * p1, D2 为 p2)。
=========================================
这与结合性无关。
=========================================
T 可以包括: int, char, float, unsigned short, void 等简单类型
class C, enum E, union U, C, E, U 等类或枚举类型
vector<int>
vector<int>::interator
typedef_name typedef 类型
decltype(a)
auto
… 等
但是,不会包括 *, [] 等部分。
注意,*, [] 等符号不属于 T 的部分。
所以, int* p1, p2; 等同与 int* p1; int p2; (T 为 int , D1 为 * p1, D2 为 p2)。
=========================================
这与结合性无关。
=========================================
T 可以包括: int, char, float, unsigned short, void 等简单类型
class C, enum E, union U, C, E, U 等类或枚举类型
vector<int>
vector<int>::interator
typedef_name typedef 类型
decltype(a)
auto
… 等
但是,不会包括 *, [] 等部分。