理解C语言中指针的声明以及复杂声明的语法

 

理解C语言中指针的声明以及复杂声明的语法

标签: c语言指针复杂声明
  225人阅读  评论(0)  收藏  举报
  分类:

昨天刚把《C程序设计语言》中“指针与数组”章节读完,终于把心中的疑惑完全解开了。如今记录下我对指针声明的理解,顺便说下如何在C语言中建立复杂声明以及读懂复杂声明markdown

本文章中的内容参考自《C程序设计语言》函数

指针是什么就不详细说明了,用一句话来总结就是:“指针是一种保存变量地址的变量”。post

1.声明简单的指针变量


先看看代码:spa

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *p;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明一个指向int类型数据的指针变量 p</span>
p = &i;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//&为取地址符,把变量i的地址赋值给指针 p</span>
*p = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此时 i 的值变成2了</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

这段代码声明了一个指针变量p,并把它指向变量i,经过*p能够访问到变量i,并对i的值进行修改。如今对星号 * 的做用进行详细的讲解。* 是一元运算符,它用在不一样的地方将具备不一样的做用。.net

1.1 星号 * 用于声明语句时的做用


上面的代码片断中的第2行代码“int *p;”就是星号 * 用于声明语句时的状况。对于指针的声明,咱们首先要从 p 这里开始看起,这是C语言中“声明”的语法,下面会介绍到。 
第一步:先看p的右边有没有其它符号(分号不算),能够看到p的右边并无符号。设计

第二步:看p的左边,在p的左边有一个星号 * ,关键的时候到了!在这里能够看到星号 * 做用于p上面,其产生的效果是:“声明变量 p 是一个指针 ”。目前为止,咱们已经知道 p 是一个指针了,但还不知道该指针是指向什么类型数据的。指针

第三步:看星号 * 右边的类型说明符 int,在这里int的做用就是声明 p 指向的数据类型是int。至此,“int *p;”这句代码就彻底解释完了。code

注意!上面的 int 、* 这两个符号发挥做用是有前后的,并非组合在一块儿来发挥做用的。先是 * 发挥做用:声明p是一个指针变量。而后是int发挥做用:声明p指向的数据类型是整型数据

1.2 星号 * 用于声明语句以外时做用

以上代码片断中,最后一句“ *p = 2; ”就是星号 * 用于声明语句以外时的做用。这句语句等效于“ i = 2;”。 
用专业点的说法就是:若是指针p指向整形变量 i,那么在 i 出现的任何上下文中均可以使用 *p ,当 * 做用于指针变量p时,就是访问指针变量p所指向的变量 i。

至此,已经说了如何声明简单的指针变量,是否是以为很简单呢?接下来将会按照复杂程度递增的顺序来介绍和指针有关的复杂声明

2.复杂声明和声明语法

2.1声明指向指针的指针变量

先看代码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *p = &i;    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明指针变量p,p指向变量i</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> **pp;       <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明指针变量pp</span>
pp = &p;        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//pp指向变量p,p是指针变量</span>
**pp = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;       <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此时 i 的值变成 2 了</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//*(*pp) = 2;这个语句等效于上面的语句</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>

代码段中的一、2行在上面已经介绍过了,如今主要介绍第2行以后的代码。 
注意,这下面这两句是等效的,这是由于相似于 * 和++这样的一元运算符遵循从右至左的结合顺序。

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> **pp;   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明方式1</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *(*pp); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明方式2</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

如今开始解释声明方式2(和声明方式1是同样),同上面的简单声明同样。咱们再次从变量名pp开始。 
第一步:先看看pp右边有没有符号,能够看到pp的右边有一个右括号,而括号只是强调结合顺序,因此不用管它。

第二步:看pp的左边,能够看到,pp的左边有一个星号 * (从右数起第一个星号),该星号的做用是:“声明变量pp是一个指针。此时,咱们还不知道指针pp所指向的数据类型,而且把括号里面的 * 和 pp 两个符号都解释完了。如今看看括号外面的符号。

第三步:先看括号外面的右边,能够看到,括号外面的右边并无符号。

第四步:看括号左边,这时,咱们看到括号外面的左边有一个星号 * (从右数起,第二个星号 *),这个星号 * 的做用是:“声明指针变量pp所指向的数据类型是指针类型”。此时,咱们已经知道了pp指向的数据类型是指针类型(便是代码片断中 p 的类型),但还不知道所指向的指针是指向什么类型数据的。例如,pp指向指针p,但殊不知道p指向的是什么类型的数据。

第五步:看最左边的符号“int”,这个int的做用就是:声明pp所指向的指针所指向的数据类型是整型int。例如,pp指向指针p,如今咱们知道了p指向的数据类型是int整型。

哈哈,是否是有点晕了,如今简单总结下:pp右边第一个星号 * 声明了pp是一个指针变量,第二个星号 * 声明了指针变量pp所指向的数据类型是指针类型,而类型说明符int则声明了pp所指向的指针指向的数据类型是int

看到这里,你可能会疑惑:必定要按照上面的步骤来解释声明吗?这是套路吗?

答:是的。由于这是C语言中”声明“的语法,下一小节将会对该语法进行介绍。之因此这么迟才介绍这个语法,是由于在用事后,会更容易理解它。

2.2 C语言中”声明“的语法

在这里,将会对声明的语法进行讲解,为后面理解更加复杂的声明打基础。

在C语言中解释一个声明,要先从被声明的变量名开始解释。并非从左到右,也不是从右到左解释,而是从中间开始,更准确来说,是从被声明的变量名开始解释。而声明老是由不少符号和惟一的变量名相结合,这些符号和惟一的变量名结合就是声明符。声明的形式为 
”T D“的形式,其中 T表明类型,D表明声明符。举个例子吧:

<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

int就是T,而*p就是D。

下面将以变量名p来对声明中用到的符号进行解释。

变量名p能够和不少符号来结合成声明符,如[ ],(),*。

1.当p与符号 [ ] 结合时(结合在p的右边),符号 [ ]的做用就是声明变量p是一个数组类型[ ]里面的数字则决定了数组中元素的个数。以下面的声明代码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> p[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>];<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明变量p是一个整型数组,数组中有5个元素</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

须要注意的是,符号[ ]的优先级是比星号 * 的优先级高的。

2.当p与符号 ( )结合时(结合在p的右边),符号( )的做用就是:声明p是一个函数,经过p()能够调用该函数,()中能够有参数列表或者无参数列表,以下面代码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> p();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明一个函数p,返回值由前面的int决定</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> p(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> a,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明一个带参数的函数p</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

一样,符号( )的优先级比星号 * 高。

3.当p与星号 * 相结合时(结合在左边),符号 * 的做用就是声明p是一个指针类型 。以下代码 :

<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*p</span>; <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span>声明p是一个指针,该指针指向<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>类型数据</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

介绍完这三个符号后,能够继续介绍语法(套路)了。

在解释声明时,首先要决定声明的名字p是什么东西,而和p最近的符号则决定了p是什么东西。以下面声明:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> p();    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//p是函数</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *p;     <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//p是指针</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> p[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>];   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//p是数组</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *p[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>];  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//p是数组,里面的5个元素为指向int类型的指针</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

这里的第4行代码要解释一下,因为[ ]的优先级比星号 * 高,因此[ ]先做用于p,故p是一个数组,如今咱们知道p是一个数组了,但还不知道数组中的元素是什么类型,这时,就要看左边的星号 * ,星号 * 声明了数组中的元素是指针类型。如今,咱们知道了数组中的元素是指针类型,但还不知道那些指针是指向什么类型的,这时int发挥做用了,它声明了里面的指针是指向int类型数据的,因此这个声明的结果就是:声明了一个数组 ,数组有5个元素,每一个元素都是指向整型数据的指针

到这里,咱们对这个语法(套路)有点头绪了!

原来解释声明就是要先从名字p开始,而后从p的右边开始看符号(由于优先级高的符号 [ ]和 ( ) 是放在右边的),若是有符号,刚和p先结合。看完右边的符号(若是有的话)后,就决定了p是什么。这时,就到p左边的符号发挥做用了(左边要么是 * ,要么就什么都没有)。最后发挥做用是则是类型说明符(由于它在最外面)。

总的来讲,解释声明的套路就是不断问什么,而后从里往外看符号来解答什么的过程,说过无谓,再来看一段代码:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> *p();   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明1,声明一个函数p,返回类型为指针类型</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> (*p)(); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//声明2,声明一个函数指针p,p指向一个函数</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

咱们来按照套路来解释这两个声明 
声明1:首先,要肯定p是什么?从p右边的符号 ( ) 能够解得,p是一个函数。新的问题又来了,那函数p的返回值是什么类型?从p左边的星号 * 能够解得,函数p的返回值类型是指针类型。新的问题又来了,返回的指针指向的数据类型是什么啊?这时,按照套路,应该继续看外一层的右边(由于看符号的顺序为p的右左右左…,并且内层优先于外层),然而符号 ( ) 的右边没有符号了,转而看向外一层的左边。这时发现外一层的左边是类型说明符int,所以解得,返回的指针指向的数据类型是int。整个声明就是:声明p为一个函数,函数的参数为空,函数的返回值为指针,指针指向的数据类型为int。

声明2:因为这个声明中,有个括号把星号 * 和 p包住了,因此 * 和 p属于内层,而括号中p的右边没有符号,故 * 和p先结合,则声明了p是一个指针,这回答了p是什么。新的问题来了,p指向的是什么?这时,内一层的符号看完了,继续看外一层的右边,外一层的右边是符号( ) ,则解得p指向的是一个函数。而后再看外一层的左边得,该函数的返回值是int类型。整个声明就是:声明p是一个指针,这个指针指向一个函数,这个函数的返回值为int

总结一下,解释声明的套路就是:先从最内层开始看符号,先从名字p的右边开始看,再到左边。而后跳到外一层的右边开始,再到外一层的左边开始看。不断循环,直到没符号为止

下面把这个套路应用到更加复杂的声明中去。

以下面这个声明:

<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-value" style="box-sizing: border-box;">char</span> (*(*<span class="hljs-function" style="box-sizing: border-box;">x()</span>)<span class="hljs-attr_selector" style="color: rgb(0, 136, 0); box-sizing: border-box;">[]</span>)();</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

有没有头晕的感受?不用怕,按照套路来很简单的。 
首先从最里面开始,x的右边是符号 ( ) ,因此x是一个函数。再看x的左边,x的左边是一个星号 * ,因此 函数x的返回值类型为指针类型。继续跳到外一层的右边,发现外一层的右边是符号 [ ] ,因此指针指向的是一个数组。继续看左边,发现左边是一个星号 * ,因此数组中的元素的类型为指针类型。再看外一层的右边,发现符号 ( ),因此数组中的指针指向的是函数。最后看左边的类型说明符char,因此函数的返回值类型为char类型。整个声明就是:x是一个函数,函数的返回值类型是指针类型,这个指针指向的是一个数组,这个数组是指针数组(里面的元素是指针),数组中的指针是函数指针(指针指向函数),指针指向的函数的返回值类型是char类型。

再看这个声明:

<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-value" style="box-sizing: border-box;">char</span> (*(*x<span class="hljs-attr_selector" style="color: rgb(0, 136, 0); box-sizing: border-box;">[3]</span>)())<span class="hljs-attr_selector" style="color: rgb(0, 136, 0); box-sizing: border-box;">[5]</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

该声明的结果为:x是一个数组,数组有3个元素,元素的类型为指针类型,这些指针都是函数指针,所指向的函数的返回值为指针 ,返回的指针指向数组,指向的数组有5个元素,元素的类型为char类型。

到此为止,咱们已经学会了复杂声明的语法(套路)。这时咱们也能够利用这个语法来声明咱们想要的变量。

2.3 使用复杂声明

如今咱们来声明一些复杂的声明。

好比,咱们来声明一个函数x,函数x的返回值为指针类型,该指针指向一个数组,数组的元素类型为char。 
只要按套路反过来就好了: 
1. 函数x:

<code class="hljs erlang has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-title" style="box-sizing: border-box;">x</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">()</span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
  1. 函数x的返回值为指针类型: 。
<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*x</span>()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

3.该指针指向一个数组:

<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">(*<span class="hljs-function" style="box-sizing: border-box;">x()</span>)<span class="hljs-attr_selector" style="color: rgb(0, 136, 0); box-sizing: border-box;">[]</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

4.数组的元素类型为char:

<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-value" style="box-sizing: border-box;">char</span> (*<span class="hljs-function" style="box-sizing: border-box;">x()</span>)<span class="hljs-attr_selector" style="color: rgb(0, 136, 0); box-sizing: border-box;">[]</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

搞定!是否是很简单?

这篇文章到这里就结束了。这是个人第一篇博客,若是有什么错误,请在评论中回复。但愿这篇文章能帮助到你们更好地理解C语言中的声明的语法。