从本质理解C指针的应用(1)

来源:互联网 发布:医药大数据 编辑:程序博客网 时间:2024/06/07 06:25

C指针说到底就是一种操作符,所以想要正确的理解C指针,那么最重要的就是莫过于理解操作符了

为了理解有些操作符存在的限制,你必须理解左值和右值(左值和右值)之间的区别。这两个术语是多年前由编译器设计者所创造并沿用至今。
左值就是那些能够出现在赋值符号左边的东西。右值就是那些可以出现在赋值符号右边的东西。这里有一例子:

a=b+25;

a是一个左值,因为它标识了一个可以存储结果的地点,b+25是一个右值,因为它指定了一个值。

那它们能够互换吗?

b+25=a;

原先作为左值的a此时也可以作为右值出现,因为每个位置都包含一个值。然而,b+25不能作为一个左值,因为它并没有标识一个特定的位置。因此上述语句非法

注意当计算机计算b+25时,它的结果必然保存在机器的某个地方。但是,程序员并没有办法预测该结果会存储在什么地方,也无法保证下一次还会保存在那个地方。故其结果是:这个表达式不是一个左值。同样的道理:字面值常量字面值常量也都不是左值。

听上去似乎变量可以作为左值而表达式不能作为左值,但这个推断并不准确。下面请看一例子:

int a[10];...a[b+10]=0;

下标引用实际上是一个操作符,所以表达式的左边实际上是一个表达式,但它却是一个合法的左值,因为它标识一个特定的位置,我们可以使用它,再看一指针例子:

int a,*p;...pi=&a;*p=20;

请看*p=20;它的左边很明显是一个表达式,但它却是一个合法的左值,为什么呢?指针p的值是内存中某个特定位置的地址,*操作符使机器指向那个位置。
当它作为左值使用的时候,这个表达式指定需要修改的位置。当它作为右值使用时,它就提取当前存储在这个位置的值。

这下大家伙明白了吧,所谓的指针无非就是这么用的,这也很好的理解了为何指针可以去修改一些变量的值,说到底就是*操作符是左值还是右值的原因,当它为左值的时候那就是指向要修改的位置,为右值则提取当前位置的值。

总结
左值和右值很好的解释了一些本质上的东西,特别是知晓了为何C语言语句的左边和右边会有如此大的区别,左值需要的是一个可以合理标识一个可以存储结果值的地点,前面提到变量其实在汇编语句中就是地址的代名词,而C语言编译之后就是汇编语句了,所以变量可以标识一个位置,放在左边可以当左值。

函数调用顺序

前面说到操作符,一般操作符都有所谓的优先级等等,故而就有什么运算的先后顺序,然而这里有个例外,函数的调用就是这个例外,举个例子

代码

#include<stdio.h>int func(){    int c;    c+=1;    return c; }  int main() {    int a;     a=func()+func()*func();    printf("the value=%d",a);    return 0; }

这里写图片描述

这里我们可以看到程序执行起来似乎是有些问题的,这就是函数调用不按常理出牌的原因,因为所谓的C语言标准并没有对此做出过规定,上述代码结果为2,换做其他的可能是这样执行的:2+3*4,或者是3+2*4,或者是4+2*3也说不定的事情,所以函数调用的顺序颇为杂乱,因编译器而异,故而一般在做可移植性的代码时,此类语句还是不要出现的为好。