本文大部分知识点来自于互联网,对这些知识归纳汇总结合自己的理解进行阐述。关于指针、指针数组、数组指针、函数指针、运算符优先级等等基本小知识点剖析。
一、 优先级列表
C优先级列表
| Precedence | Operator | Description | Example | Associativity |
| 1 | () | Grouping operator | (a + b) / 4; |
left to right |
| 2 | ! | Logical negation | if( !done ) ... | right to left |
| 3 | ->* | Member pointer selector | ptr->*var = 24; | left to right |
| 4 | * | Multiplication | int i = 2 * 4; | left to right |
| 5 | + | Addition | int i = 2 + 3; | left to right |
| 6 | << | Bitwise shift left | int flags = 33 << 1; | left to right |
| 7 | < | Comparison less-than | if( i < 42 ) ... |
left to right |
| 8 | == | Comparison equal-to | if( i == 42 ) ... | left to right |
| 9 | & | Bitwise AND | flags = flags & 42; | left to right |
| 10 | ^ | Bitwise exclusive OR | flags = flags ^ 42; | left to right |
| 11 | | | Bitwise inclusive (normal) OR | flags = flags | 42; | left to right |
| 12 | && | Logical AND | if( conditionA && conditionB ) ... | left to right |
| 13 | || | Logical OR | if( conditionA || conditionB ) ... | left to right |
| 14 | ? : | Ternary conditional (if-then-else) | int i = (a > b) ? a : b; | right to left |
| 15 | = | Assignment operator | int a = b; |
right to left |
| 16 | , | Sequential evaluation operator | for( i = 0, j = 0; i < 10; i++, j++ ) ... | left to right |
C++优先级列表
| Precedence | Operator | Description | Example | Associativity |
| 1 | () | Grouping operator | (a + b) / 4; | left to right |
| 2 | ! | Logical negation | if( !done ) ... | right to left |
| 3 | ->* | Member pointer selector | ptr->*var = 24; | left to right |
| 4 | * | Multiplication | int i = 2 * 4; | left to right |
| 5 | + | Addition | int i = 2 + 3; | left to right |
| 6 | << | Bitwise shift left | int flags = 33 << 1; | left to right |
| 7 | < | Comparison less-than | if( i < 42 ) ... | left to right |
| 8 | == | Comparison equal-to | if( i == 42 ) ... | left to right |
| 9 | & | Bitwise AND | flags = flags & 42; | left to right |
| 10 | ^ | Bitwise exclusive OR | flags = flags ^ 42; | left to right |
| 11 | | | Bitwise inclusive (normal) OR | flags = flags | 42; | left to right |
| 12 | && | Logical AND | if( conditionA && conditionB ) ... | left to right |
| 13 | || | Logical OR | int i = (a > b) ? a : b | left to right |
| 14 | ? : | Ternary conditional (if-then-else) | if( conditionA || conditionB ) ... | right to left |
| 15 | = | Assignment operator | int a = b; | right to left |
| 16 | , | Sequential evaluation operator | for( i = 0, j = 0; i < 10; i++, j++ ) ... | left to right |
二、 指针数组和数组指针
指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。
数组指针:首先它是一个指针,它指向一个数组。在32 位系统下永远是占4 个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称。
下面到底哪个是数组指针,哪个是指针数组呢:A) int *p1[10]; B) int (*p2)[10];
这里需要明白一个符号之间的优先级问题。优先级参看第一点。“[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组。至于p2 就更好理解了,在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。我们可以借助下面的图加深理解:
三、 函数和指针
3.1 指针函数
这个比较简单此处不做过多阐述。指针函数就是返回指针的函数,一般定义形式如下:
类型名 *函数名(函数参数表列);
例: const char* strcpy(char* strDest, const char* strSrc);理解:“()”的优先级高于“*” ,故 strcpy 先于 "()" 结合表明这是一个函数,再与 "*"结合表明返回一个指针。前面 const char 表明函数 strcpy 返回的就是一个 const char 类型指针。
3.2 函数指针
函数指针是指向函数的指针变量,即本质是一个指针变量。一般定义形式如下:
类型名 (*函数名)(参数);
例 : int (*p_func)(char*);理解:p_func先与“*”结合表明这是一个指针变量,后面“()”表明该指针指向一个函数,char* strdata 是该函数的参数,前面的 int 是该函数的返回值。
关于调用问题:假定有函数 int func(char* strdata); 要调用该函数可直接 func(str) ; 也可用函数指针调用。调用形式如下:
p_func = func; // 赋值
(*p_func)(str); // 调用
3.3 返回函数指针的函数
先来看一个表达式,void (*signal(int signo, void (*func)(int)))(int);这是Linux的一个声明(先不说这是函数还是指针),当然你可以谷歌它。如果你能完全理解并能随心所欲写类似代码那么你不用看这篇文章了,这是在浪费你时间。
有一类函数,返回指针不过返回的是指向函数的指针。一般定义形式如下:
类型名 (*函数名(函数参数列表))(函数参数列表);
例:int (*func(char a, short b))(int); 理解:按优先级来一步一步解析该声明。func先和右边的“()”结合表明 func 是一个函数,然后和“*”结合意味着它是一个指针函数。作为一个指针函数(见3.1)就要有它的返回值。现在来看 func 的返回值,最右边的“()”表示它要指向一个函数。这个函数的形式是 int funcname(int) 。
用 typedef 关键字会使该声明更简单易懂。int (*p_type)(int); 此处 p_type 是一个函数指针变量。 typedef int (*p_type)(int); 此时 p_type 就成为了一个函数指针类型。int (*func(char a, short b))(int); 就可以写为 p_type func(char a, short b);
然后来看刚刚给出的 void (*signal(int signo, void (*func)(int)))(int); 理解:signal 是一个函数, 第二个参数是一个函数指针,指向 void funcname(int x) 类型的函数, signal 的返回值是一个函数指针,指向 void funcname(int x) 类型的函数。为什么要这么设计?这么设计有什么好处?signal 函数是处理信号的函数,作用相当于消息映射。他要指名信号 signo 对应的处理函数即 func 指向的函数。返回值为什么要和 func 一样?看 const char* strcpy(char* strDest, const char* strSrc) 的返回值就一清二楚了。

被折叠的 条评论
为什么被折叠?



