浅谈c语言--复杂指针
C语言中的指针语法较为复杂,新手刚接触指针,容易混淆代码中指针的含义,错误的使用。
本文将一些常用的指针表达式说明,分析其内含,也是本人最近学c语言的一点心得。
1.指针的基本定义
一元运算符&可用于取一个对象的地址。
下列语句:p=&c
意思是把c的地址赋值给变量p,我们称p为“指向”c的指针。
一元运算符*是间接寻址或间接引用运算符。
当它作用于指针时,将访问指针所指向的对象。
2.右左法则
右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
从标识符开始(或者最内层的结构,如果不存在标识符的话,通常出现于函数指针),首先向右看,直到遇到 ) 括号或者结束,看到什么就说出来;然后向左看,直到遇到 ( 括号或者回到行首,看到什么就说出来。跳出一层括号,重复上述过程:右看看,说出来;左看看,说出来。直到你说出变量的类型或者返回值(针对函数指针),也就表示你把声明都读完了。
3.实例详解
3.1指针与结构体
例:对于结构声明
Struct{
int len;
char *str;
}*p;
表达式
++p->len :增加len的值
(++p)->len :先执行p的自增操作,然后对len操作
注:->的运算优先级比自增、自减要高。
*p->str :取str指向的值
*p->str++ : 先读取指针str指向的对象的值,然后再将str加1,类似*s++
(*p->str)++ :与上一个效果相同
*p++->str :先读取指针str指向的对象的值,然后再将p加1.
*s++:先在地址取值,然后将取得值加一。
*(s++):先在地址取值,然后把s原来指向的地址往后面指一位。
注:类似于*和++这样的一元运算符遵循从右到左的结合顺序。
3.2复杂声明 (指针、函数、数组)
例1 Char **a
a:字符型指向指针的指针
例2 int(*p)[13]
p:数值型指向数组长度为13的指针
例3 int *p[13]
p:数值型数组长度为13的数组指针
注:数组指针与指向数组的指针的区别如下:
数组指针:数组里面全是指针
指向数组的指针:指针就一个,数组里的内容未知
例4 int (*comp)(void*)
表明comp是一个指向函数的指针,该函数具有一个void*类型的参数,其返回值类型为int。
例5 int *comp(void*)
表明comp是一个函数,该函数返回一个指向int类型的指针。
例6 Char(* ( * p ( ) ) [ ] )( )
含义:函数p返回指向数组[ ]的指针,这个指针指向返回char的函数的指针。
分析(从里到外):
函数p返回指针 *p( )
指针指向指针数组 *( )[ ]
指针数组分别指向多个函数,这些函数的返回值为char类型 char(* )( )
例7 (* (* p [3] )( ) ) [5]
用例6从里到外分析方法,或者用右左法则分析。
数组指针是p,数组指针指向函数,该函数返回一个字符类型的数组长度为5的指针。
4.复杂声明代码
我认为看懂复杂指针,不需要用代码实现,因为这样似乎有点画蛇添足,如果看不懂这个复杂声明,那么怎么会用的好呢。但是为了文章里知识的完整性,还是需要代码帮助理解。
C程序设计语言这本书里也是给出了分析复杂声明的代码,网上找了一圈,发现这篇文章已经把代码摘录了。网址如下: https://www.cnblogs.com/battzion/p/4217443.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)