C语言提高之——指针表达式

在理解指针表达式之前先有一个概念就是“左值”和“右值”,对于左值就是可以出现在赋值符号左边的东西,右值就是那些可以出现在赋值符号右边的东西。进一步抽象可以这样理解:左值应该可以作为一个地址空间用来存放一个值,而右值可以作为一个值来处理,当然需要说明的是有些是既可以作为左值也可以作为右值的,例如:定义a为一个指针指向b,那么*a既可以作为一个右值即地址b中存放的数据,也可以作为一个左值即表示b的地址。其实说到这里就已经说明了一个简单的指针表达式了,那就是:*a。下边就再讨论一些其他的指针表达式。

首先做一个声明:

char ch = “a”;

char *cp = &ch;

其实这个声明很明了,这个声明声明了两个变量:ch和cp,cp作为一个指针指向ch。为了便于随后的说明,我现在做如下设想:cp变量地址为0x12,ch变量的地址为0x23,即现在空间cp中的内容为:0x23,ch中的内容为a字符。下边做一些表达式的分析:

1、&ch:右值:表示ch的地址信息,即0x23这个值。左值:它作为左值是非法的,因为它已经不可以作为一个空间来使用。

2、cp:右值;表示cp中的内容,即ch的地址信息(0x23)。左值:表示cp这个地址空间,作为一个空间使用。

3、&cp:右值:表示cp的地址信息,即0x12这个数据。左值:类比&ch也可知它作为左值是非法的。

4、*cp:这个和我们博文开始的例子是一样的。右值:表示ch内的内容(a字符)。左值:表示ch这个地址空间。

5、*cp + 1:要注意*(我个人理解为间接范围操作符)的优先级高于+。右值:运算过程为:首先做间接的访问操作得到a字符的一个拷贝,再加1,得到字符b。左值:位置未清晰定义,是非法的。

6、*(cp + 1):这个表达式可以把cp+1看做一个整体,它作为指针加法运算的结果是一个右值,表示ch的下一个地址,*(cp+1)做右值表示对ch下一个地址中的数据内容,做左值表示ch下一个地址这个空间(注意:cp+1本身不是左值)。

7、++cp与cp++:该表达式涉及++运算符,两个表达式除了都有cp+1的功能外,两个表达式整体的结果也都会得到变量的拷贝,但是前缀++会先执行加1的操作再获得变量拷贝,而后缀++则是先进行变量的拷贝再执行加1操作。因此++cp表达式作为右值执行后cp和++cp都会指向cp后面的内存位置,而cp++作为右值执行后cp会指向cp内存后面的内存位置,而cp++整体则是指向cp原来的内存位置(0x12)。他们都没有清晰的位置定义,所以都是不合法的左值。

8、*++cp与*cp++:对比上边两个表达式这两个理解起来也很容易了,只是进行了一次指针运算即间接访问操作,对于右值来看,这两个表达式结果只是对上边两个操作结果的间接访问,即对应空间内的数据;对于左值来看,这回就是合法的了,对应的就是响应地址的地址信息了。

综合:其实关于指针的表达式还有很多,不同运算符之间的相应组合都会形成相应操作符,只要根据相应的运算符的优先级一步步运算都可以得到其相应结果。叙述了这么多的表达式,但是在实际运用中大多数还是一般的表达式,之所以把他们都整理一下是因为:1、有助于我们去理解别人的代码,因为别人很可能会写出这些表达式。2、有个别时候是用得到的,学习也是有必要的。3、总结这么多最终目的并不是要简单的去理解现有的表达式,而是通过现有的表达式的整理和理解,充分理解指针以及指针表达式的真正含义,深入的理解指针这个东西,有助于后期的学习和提高。

时间: 2024-12-19 01:42:43

C语言提高之——指针表达式的相关文章

C 指针&&表达式&&常量

一.指针 在计算机语言中,由于通过地址能找到所需的变量,可以说地址指向该变量单元,因此把地址形象的称为'指针',意思是能通过它来找到以它为地址的内存单元. 1.1.指针&&变量 指针变量与普通变量一样,使用之前不仅要定义说明而且必须要赋具体的值,未经赋值的指针变量不能使用:可以对指针变量初始化为NULL,但是不能对值为NULL的指针变量解引用. 如下定义一个指针变量p指向a,这样就可以通过p访问a并对a进行操作. int a=0; int *p=NULL; p=&a; *p=10;

C语言中,为什么指针表达式的值+1.对应的地址值却+4?/为什么两个数组元素的地址相减之差不为地址之差?

在C语言中,我们常常用到的一个运算是让某个变量的值+1. 例如 M = M + 1. 而在实际运用中,我们发现 对于指针进行+1运算,算出来的结果是+4. 如下图 图中我们定义的 变量M 和指针Matrix如下: int M = 3; int* Matrix = {1,2,3}; 可以看到,对于M和 Matrix ,+1运算的效果是不同的. 这个差异是因为C语言的标准中规定了 加法与减法运算对于地址的操作和对于值的操作是不同的,如下文中粗体所示: C89 3.3.6 Additive opera

【C语言学习】指针再学习(二)之数组的指针

★一维数组 一个整型数据为4个字节.4个字节就是32位,即可以表示2^32个数字 在程序中定义一个数组a[5] = {1,2,3,4,5}; 那么a[0]的地址就是0x00000000,数组名a是数组首元素的地址,a的地址也是0x00000000.a+1则表示的地址是0x00000004,而不是0x00000001.因为1这个值,根据前面的指针a所指向的类型的长度来调整自己的长度.也就是说如果a是指向整型的指针,那么后面加的1也表示4个字节,如果a是指向字符型的指针,那么后面加的1表示1个字节.

《你必须知道的495个C语言问题》笔记--表达式

1.怎样才能避免这些未定义的求值顺序问题呢? 有几条简单的规则: 1.确保一个表达式最多只修改一个对象:一个简单变量.一个数组或者一个指针指向的位置. 2.如果一个对象在一个表达式中出现一次以上而且在表达式中被修改,则要确保对该对象的所有读访问都被用于计算它的 最终值.这条规则允许表达式i=i+1,尽管i出现了两次而且被修改了,但对i的旧值读取是用于计算i的新值. 3.如果想破坏第一条规则,就要确保修改的对象互不相同.同时,尽量限制到最多2至3个修改并参照下面例子的风格.在 这条规则下,c=*p

c语言数组与指针详解(上)

彻底搞懂c语言数组与指针 部分引用 c语言指针怎么理解 知乎 程序设计入门----c语言 (浙江大学翁恺) <c primer plus>第六版 基础知识 1. 指针基础 &:代表对变量取地址 int*或char*或者把这个星号紧贴着变量比如int *a = &b: 代表新建一个用来储存地址的变量,这也代表&b这个值的类型是int*. int *a, b 或 int* a, b 中只有a是int指针类型,b是int整型. 关于电脑大小端的讨论:大端是指是指数据的高字节,

C语言 结构体指针赋值 incompatible types when assigning to type &#39;char[20]&#39; from type &#39;char *&#39;

strcpy(pstudent->name, "guo zhao wei "); 为什么错误,该怎么写,(红色行) 追问 为什么不能直接赋值啊, 追答 用char nnnn[20]定义的,用strcpy 用char *ppp定义的,用=来赋值 C语言 结构体指针赋值 incompatible types when assigning to type 'char[20]' from type 'char *'

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用 传值 把实参的值赋值给行参 那么对行参的修改,不会影响实参的值 传地址 传值的一种特殊方式,只是他传递的是地址,不是普通的如int 那么传地址以后,实参和行参都指向同一个对象 传引用 真正的以地址的方式传递参数 传递以后,行参和实参都是同一个对象,只是他们名字不同而已 对行参的修改将影响实参的值 所谓变量是内存地址的一个抽象名字,在静态编译的程序中,所有变量名都会在编译时转换成内存地址,机器不知道变量名,只知道地址. C 语

黑马程序员——c语言学习心得—— 指针

黑马程序员——c语言学习心得—— 指针 -------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 1,打开文件fopen(文件名,打开方式);例如:FILE *fp = fopen("a1","r");  返回的是文件的指针(文件在内存缓冲区的首地址)fopen函数反回值 是指向 a1文件的指针,通常赋值给一个指针变量关于文件名a1 也可以是一个“路径+文件名”   c:\abc.txt----------------

如何理解c语言中得指针

最近有学习了c语言中得指针知识,脑袋都大了,迷迷糊糊理解了一半,由自己查了下资料,跟大家分享下c语言中指针的基本知识吧: 1.指针是一个地址,指向的是个类型. 2:指针指向的是地址,地址指向的是内容. 我们需要一个变量,来存储地址,这个变量的值是地址,但是我们可以通过修改变量的值,来不断的改变地址,但是,我们如果需要改变该个地址的值的话,就需要,对地址的值进行修改,而不改变地址. int a = 10: int *p : p = &a: *p =11: a=? 这里我们看到,p 是一个变量,我们